Class SharedAxonServerContainer
AxonServerContainer configuration meant to be shared by every IT test suite in
the build, instead of each test class declaring its own.
Testcontainers' reuse feature (a container-level GenericContainer.withReuse(boolean) combined with
testcontainers.reuse.enable=true in ~/.testcontainers.properties) attaches to an already-running
container instead of starting a new one, but only when the requested configuration hashes identically to one
already running. Every test class that used to hand-roll its own AxonServerContainer therefore started a
fresh container, even within the same build. Depending on INSTANCE here instead, rather than
constructing a separate AxonServerContainer, is what lets those requests collapse onto the same running
container.
This class lives in this module specifically because it is low enough in the dependency graph for every consumer
-- connector/axon-server-connector, dependency-injection/spring/spring-boot-autoconfigure, and all
integrationtests/* modules -- to reach it directly.
- Since:
- 5.4.0
- Author:
- John Hendrikx
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final AxonServerContainerThe shared container instance.static final StringClasspath resource name of the Axon Server Enterprise test license. -
Method Summary
Modifier and TypeMethodDescriptionstatic voidStartsINSTANCEif it isn't already running.static booleanChecks whetherLICENSE_RESOURCEis present on this JVM's classpath.
-
Field Details
-
LICENSE_RESOURCE
Classpath resource name of the Axon Server Enterprise test license. Only present (and thus only mounted, seeINSTANCE) in modules whose test classpath includes it; absent elsewhere. Tests that don't need multi-context features work identically either way.- See Also:
-
INSTANCE
The shared container instance. Byte-identical construction is the entire point: it is what lets Testcontainers' reuse hash match across every module and JVM fork that references it.
-
-
Method Details
-
ensureStarted
public static void ensureStarted()StartsINSTANCEif it isn't already running.GenericContainer.start()is idempotent on its own -- Testcontainers makes it a no-op when the container is already running in this JVM -- so this is a thin, explicitly-named entry point for callers rather than a correctness requirement.synchronizedalone only guards within one JVM, not across forked processes, and Testcontainers' ownfindContainerForReuse()has no locking of its own (confirmed via its source: a// TODO lockingcomment). Two Surefire/Failsafe forks can therefore both decideINSTANCEisn't running yet and both end up creating their own container instead of one attaching to the other's -- confirmed directly: from a clean Docker state, two forks calling this method concurrently produced two separate containers on two different ports, even though both compute the identical reuse hash. AFileLockserializes the whole check-and-start sequence across processes, so the second caller sees the first one's container already running (and matching on hash) by the time it gets to check. Keptsynchronizedtoo: a secondFileLockacquisition attempt from another thread in the same JVM throwsOverlappingFileLockExceptionrather than waiting, so cross-thread safety within this JVM still needs the intrinsic lock. -
licenseExists
public static boolean licenseExists()Checks whetherLICENSE_RESOURCEis present on this JVM's classpath.- Returns:
trueif the license resource is present and non-empty,falseotherwise
-