-
Notifications
You must be signed in to change notification settings - Fork 149
Migration guide: Citrus 4.x to 5.x
Citrus 5.0 brings several changes:
-
Split package removal — every
org.citrusframework.*package now belongs to exactly one Maven module, enabling Java Module System (JPMS) support. - Maven artifact renames — some module artifact IDs have changed.
- Dependency upgrades — Citrus 5.0 upgrades to Spring Framework 7, Spring Boot 4, and Jackson 3.
This guide covers every change you need to address when upgrading from Citrus 4.x.
The following Citrus Maven artifacts have been renamed:
| Old artifactId | New artifactId |
|---|---|
citrus-junit5 |
citrus-junit-jupiter |
Update your pom.xml:
<!-- Before -->
<dependency>
<groupId>org.citrusframework</groupId>
<artifactId>citrus-junit5</artifactId>
</dependency>
<!-- After -->
<dependency>
<groupId>org.citrusframework</groupId>
<artifactId>citrus-junit-jupiter</artifactId>
</dependency>Citrus 5.0 upgrades its transitive dependencies to major new versions. If your project manages these versions explicitly, you will need to upgrade them as well:
| Dependency | Citrus 4.x | Citrus 5.0 |
|---|---|---|
| Spring Framework | 6.x | 7.x |
| Spring Boot | 3.x | 4.x |
| Spring WS | 4.x | 5.x |
| Spring Integration | 6.x | 7.x |
| Jackson | 2.x (com.fasterxml.jackson) |
3.x (tools.jackson) |
Jackson 3 changed its Maven coordinates and Java package names. If your test code uses Jackson directly (e.g. for custom ObjectMapper configuration):
// Before (Jackson 2.x)
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
// After (Jackson 3.x)
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.cfg.EnumFeature;
import tools.jackson.core.StreamReadFeature;Maven coordinates also changed:
<!-- Before -->
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<!-- After -->
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>Note: Jackson annotations remain in
com.fasterxml.jackson.annotation(package unchanged), but may require explicit dependency oncom.fasterxml.jackson.core:jackson-annotations.
In some configurations (especially non-Spring-Boot setups), spring-expression may need to be added as an explicit dependency:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
</dependency>Most changes are mechanical package renames — class names stay the same. You can fix the majority with IDE refactoring or search-and-replace.
Based on real-world migrations, these are the changes you will encounter most frequently (ranked by how many files they typically affect):
-
TestActionSupport— nearly every test class imports this:org.citrusframework.TestActionSupport→org.citrusframework.dsl.TestActionSupport -
NamespaceContextBuilder— common in XML-heavy projects:org.citrusframework.xml.namespace.NamespaceContextBuilder→org.citrusframework.api.xml.namespace.NamespaceContextBuilder -
XsdSchemaRepository— used in endpoint configurations:org.citrusframework.xml.XsdSchemaRepository→org.citrusframework.xml.schema.XsdSchemaRepository -
DefaultTestActions— used for custom action builders:org.citrusframework.DefaultTestActions→org.citrusframework.dsl.DefaultTestActions -
Functions— used for function utilities:org.citrusframework.functions.Functions→org.citrusframework.base.functions.Functions -
Endpoint adapters — used in endpoint configurations:
org.citrusframework.endpoint.adapter.*→org.citrusframework.base.endpoint.adapter.* -
Container classes (
BeforeSuite,AfterSuite,BeforeTest,AfterTest):org.citrusframework.container.*→org.citrusframework.api.container.* -
Spring config:
org.citrusframework.config.CitrusSpringConfig→org.citrusframework.spring.config.CitrusSpringConfig
Use Optimize Imports across your project after updating Citrus dependencies. The IDE will resolve most moves automatically since class names are unchanged.
Apply these ordered replacements to your import statements and fully-qualified references:
# citrus-api: actions, containers, conditions, etc.
org.citrusframework.actions. → org.citrusframework.api.actions.
org.citrusframework.container. → org.citrusframework.api.container.
org.citrusframework.condition. → org.citrusframework.api.condition.
org.citrusframework.common. → org.citrusframework.api.common.
org.citrusframework.agent. → org.citrusframework.api.agent.
org.citrusframework.openapi. → org.citrusframework.api.openapi.
org.citrusframework.kubernetes. → org.citrusframework.api.kubernetes.
org.citrusframework.main. → org.citrusframework.api.main.
org.citrusframework.xml.namespace. → org.citrusframework.api.xml.namespace.
org.citrusframework.xml.Marshaller → org.citrusframework.api.xml.Marshaller
org.citrusframework.xml.Unmarshaller → org.citrusframework.api.xml.Unmarshaller
org.citrusframework.xml.StringResult → org.citrusframework.api.xml.StringResult
org.citrusframework.xml.StringSource → org.citrusframework.api.xml.StringSource
org.citrusframework.yaml. → org.citrusframework.api.yaml.
# citrus-api: validation contexts
org.citrusframework.validation.json. → org.citrusframework.validation.context.json.
org.citrusframework.validation.xml. → org.citrusframework.validation.context.xml.
org.citrusframework.validation.yaml. → org.citrusframework.validation.context.yaml.
org.citrusframework.validation.script.→ org.citrusframework.validation.context.script.
org.citrusframework.validation.ws. → org.citrusframework.validation.context.ws.
org.citrusframework.validation.openapi.→org.citrusframework.validation.context.openapi.
# citrus-api: utilities
org.citrusframework.json. → org.citrusframework.util.json.
org.citrusframework.yaml.YamlNodeStringBuilder → org.citrusframework.util.yaml.YamlNodeStringBuilder
org.citrusframework.yaml.YamlStringBuilder → org.citrusframework.util.yaml.YamlStringBuilder
# citrus-base
org.citrusframework.functions. → org.citrusframework.base.functions.
org.citrusframework.validation.matcher.→org.citrusframework.base.validation.matcher.
org.citrusframework.report. → org.citrusframework.base.report.
org.citrusframework.endpoint.adapter. → org.citrusframework.base.endpoint.adapter.
org.citrusframework.endpoint.AbstractEndpointAdapter → org.citrusframework.base.endpoint.AbstractEndpointAdapter
org.citrusframework.endpoint.AbstractEndpointBuilder → org.citrusframework.base.endpoint.AbstractEndpointBuilder
org.citrusframework.endpoint.DefaultEndpointFactory → org.citrusframework.base.endpoint.DefaultEndpointFactory
org.citrusframework.server. → org.citrusframework.base.server.
org.citrusframework.context.StaticTestContextFactory → org.citrusframework.base.context.StaticTestContextFactory
org.citrusframework.annotations.CitrusAnnotations → org.citrusframework.base.annotations.CitrusAnnotations
org.citrusframework.message.builder. → org.citrusframework.base.message.builder.
org.citrusframework.main.AbstractTestEngine → org.citrusframework.base.main.AbstractTestEngine
org.citrusframework.main.scan. → org.citrusframework.base.main.scan.
# citrus-base: DSL classes
org.citrusframework.DefaultTestActionBuilder → org.citrusframework.dsl.DefaultTestActionBuilder
org.citrusframework.DefaultTestActions → org.citrusframework.dsl.DefaultTestActions
org.citrusframework.TestActionSupport → org.citrusframework.dsl.TestActionSupport
# citrus-docker (connector)
org.citrusframework.actions.docker. → org.citrusframework.docker.
# citrus-spring
org.citrusframework.config.xml. → org.citrusframework.spring.config.xml.
org.citrusframework.config.handler. → org.citrusframework.spring.config.handler.
org.citrusframework.config.util. → org.citrusframework.spring.config.util.
org.citrusframework.config. → org.citrusframework.spring.config.
org.citrusframework.context.SpringBeanReferenceResolver → org.citrusframework.spring.context.SpringBeanReferenceResolver
org.citrusframework.context.TestContextFactoryBean → org.citrusframework.spring.context.TestContextFactoryBean
org.citrusframework.CitrusSpringContext → org.citrusframework.spring.CitrusSpringContext
org.citrusframework.CitrusSpringContextProvider → org.citrusframework.spring.CitrusSpringContextProvider
org.citrusframework.CitrusSpringSettings → org.citrusframework.spring.CitrusSpringSettings
# citrus-spring-integration
org.citrusframework.channel. → org.citrusframework.springintegration.channel.
org.citrusframework.actions.PurgeMessageChannelAction → org.citrusframework.springintegration.actions.PurgeMessageChannelAction
# citrus-groovy (runtime)
org.citrusframework.script. → org.citrusframework.groovy.actions.
org.citrusframework.message.builder.script. → org.citrusframework.groovy.message.builder.
org.citrusframework.util.GroovyTypeConverter → org.citrusframework.groovy.util.GroovyTypeConverter
# citrus-sql (connector)
org.citrusframework.actions.AbstractDatabaseConnectingTestAction → org.citrusframework.sql.actions.AbstractDatabaseConnectingTestAction
org.citrusframework.actions.ExecutePLSQLAction → org.citrusframework.sql.actions.ExecutePLSQLAction
org.citrusframework.actions.ExecuteSQLAction → org.citrusframework.sql.actions.ExecuteSQLAction
org.citrusframework.actions.ExecuteSQLQueryAction → org.citrusframework.sql.actions.ExecuteSQLQueryAction
org.citrusframework.util.SqlUtils → org.citrusframework.sql.util.SqlUtils
# citrus-validation-xml
org.citrusframework.variable.dictionary.xml. → org.citrusframework.xml.variable.dictionary.
org.citrusframework.xml.XsdSchemaRepository → org.citrusframework.xml.schema.XsdSchemaRepository
org.citrusframework.xml.XmlFormattingMessageProcessor → org.citrusframework.xml.message.processor.XmlFormattingMessageProcessor
org.citrusframework.xml.LSResolverImpl → org.citrusframework.xml.support.LSResolverImpl
org.citrusframework.xml.XmlConfigurer → org.citrusframework.xml.support.XmlConfigurer
org.citrusframework.util.XMLUtils → org.citrusframework.xml.support.XMLUtils
org.citrusframework.XmlValidationHelper → org.citrusframework.xml.support.XmlValidationHelper
org.citrusframework.dsl.XmlSupport → org.citrusframework.xml.dsl.XmlSupport
org.citrusframework.dsl.XpathSupport → org.citrusframework.xml.dsl.XpathSupport
org.citrusframework.message.builder.MarshallingPayloadBuilder → org.citrusframework.xml.message.builder.MarshallingPayloadBuilder
# citrus-validation-json
org.citrusframework.variable.dictionary.json. → org.citrusframework.json.variable.dictionary.
org.citrusframework.dsl.JsonSupport → org.citrusframework.json.dsl.JsonSupport
org.citrusframework.dsl.JsonPathSupport → org.citrusframework.json.dsl.JsonPathSupport
org.citrusframework.message.builder.ObjectMappingPayloadBuilder → org.citrusframework.json.message.builder.ObjectMappingPayloadBuilder
# citrus-validation-groovy
org.citrusframework.validation.script.Groovy → org.citrusframework.validation.groovy.Groovy
# citrus-validation-hamcrest
org.citrusframework.validation.matcher.hamcrest. → org.citrusframework.validation.hamcrest.matcher.
org.citrusframework.validation.HamcrestHeaderValidator → org.citrusframework.validation.hamcrest.HamcrestHeaderValidator
org.citrusframework.validation.HamcrestValueMatcher → org.citrusframework.validation.hamcrest.HamcrestValueMatcher
org.citrusframework.container.HamcrestConditionExpression → org.citrusframework.validation.hamcrest.HamcrestConditionExpression
# citrus-jbang (tools)
org.citrusframework.jbang. → org.citrusframework.jbang.cli.
Note: Apply the most specific replacements first (e.g.
config.xml.beforeconfig.), and skip replacements for packages that remain unchanged in your code.
The concrete CitrusContext class has been extracted into an interface in citrus-api. The implementation is now DefaultCitrusContext in citrus-base, discovered via ServiceLoader.
// Before (4.x)
import org.citrusframework.CitrusContext;
CitrusContext ctx = new CitrusContext();
// After (5.0) — use ServiceLoader (recommended)
import org.citrusframework.CitrusContext;
CitrusContext ctx = CitrusContext.newInstance();
// After (5.0) — or reference the implementation directly
import org.citrusframework.base.DefaultCitrusContext;
DefaultCitrusContext ctx = new DefaultCitrusContext();The concrete TestContextFactory class has been extracted into an interface in citrus-api. The implementation is now DefaultTestContextFactory in citrus-base, discovered via ServiceLoader.
// Before (4.x)
import org.citrusframework.context.TestContextFactory;
TestContextFactory factory = new TestContextFactory();
// After (5.0) — use ServiceLoader (recommended)
import org.citrusframework.context.TestContextFactory;
TestContextFactory factory = TestContextFactory.newInstance();
// After (5.0) — or reference the implementation directly
import org.citrusframework.base.context.DefaultTestContextFactory;
DefaultTestContextFactory factory = new DefaultTestContextFactory();Three new interfaces have been introduced in citrus-api under org.citrusframework.api.container:
-
IteratingActionContainer— marker interface extendingTestActionContainer -
TestBoundaryActionContainer— interface for before/after test containers with group and name-pattern filtering -
TestSuiteActionContainer— interface for before/after suite containers with suite-name filtering
These are transparent additions — existing container implementations now implement these interfaces.
The following classes moved from the org.citrusframework root package to org.citrusframework.dsl:
| Class | Old package | New package |
|---|---|---|
DefaultTestActionBuilder |
org.citrusframework |
org.citrusframework.dsl |
DefaultTestActions |
org.citrusframework |
org.citrusframework.dsl |
TestActionSupport |
org.citrusframework |
org.citrusframework.dsl |
If your tests implement TestActionSupport, update the import:
// Before
import org.citrusframework.TestActionSupport;
// After
import org.citrusframework.dsl.TestActionSupport;The following Spring XML factory beans have been removed without replacement:
org.citrusframework.config.xml.AbstractEndpointFactoryBeanorg.citrusframework.config.xml.AbstractServerFactoryBean
If you extended these classes, use AbstractEndpointParser / AbstractServerParser (now in org.citrusframework.spring.config.xml) instead.
| Old package | New package | Description |
|---|---|---|
o.c.actions.* |
o.c.api.actions.* |
All action builder interfaces (~257 classes) |
o.c.container.* |
o.c.api.container.* |
Test action containers (~24 classes) |
o.c.common.* |
o.c.api.common.* |
Common interfaces (Named, Described, etc.) |
o.c.condition.* |
o.c.api.condition.* |
Condition interface |
o.c.agent.* |
o.c.api.agent.* |
Agent configuration |
o.c.kubernetes.* |
o.c.api.kubernetes.* |
Kubernetes types |
o.c.openapi.* |
o.c.api.openapi.* |
OpenAPI specification types |
o.c.main.* |
o.c.api.main.* |
Test engine interfaces |
o.c.xml.{Marshaller,Unmarshaller,...} |
o.c.api.xml.* |
XML marshalling interfaces |
o.c.xml.namespace.* |
o.c.api.xml.namespace.* |
Namespace context builders |
o.c.yaml.{SchemaType,...} |
o.c.api.yaml.* |
YAML schema types |
o.c.json.* |
o.c.util.json.* |
JSON string builder utilities |
o.c.yaml.{YamlStringBuilder,...} |
o.c.util.yaml.* |
YAML string builder utilities |
o.c.validation.json.* |
o.c.validation.context.json.* |
JSON validation contexts |
o.c.validation.xml.* |
o.c.validation.context.xml.* |
XML validation contexts |
o.c.validation.yaml.* |
o.c.validation.context.yaml.* |
YAML validation contexts |
o.c.validation.script.* |
o.c.validation.context.script.* |
Script validation contexts |
o.c.validation.ws.* |
o.c.validation.context.ws.* |
SOAP validation contexts |
o.c.validation.openapi.* |
o.c.validation.context.openapi.* |
OpenAPI validation contexts |
| Old package | New package | Description |
|---|---|---|
o.c.functions.* |
o.c.base.functions.* |
Function library and registry (~40 classes) |
o.c.validation.matcher.* |
o.c.base.validation.matcher.* |
Validation matchers (~25 classes) |
o.c.report.* |
o.c.base.report.* |
Reporters (HTML, JUnit, etc.) |
o.c.endpoint.* |
o.c.base.endpoint.* |
Abstract endpoint classes |
o.c.endpoint.adapter.* |
o.c.base.endpoint.adapter.* |
Endpoint adapters |
o.c.server.* |
o.c.base.server.* |
Abstract server classes |
o.c.context.* |
o.c.base.context.* |
Context implementations |
o.c.annotations.CitrusAnnotations |
o.c.base.annotations.CitrusAnnotations |
Annotation processor (note: @CitrusTest, @CitrusResource, etc. remain in o.c.annotations) |
o.c.message.builder.* |
o.c.base.message.builder.* |
Message builder support |
o.c.main.* |
o.c.base.main.* |
Abstract test engine |
o.c.main.scan.* |
o.c.base.main.scan.* |
Test scanners |
o.c.xml.Jaxb2Marshaller |
o.c.base.xml.Jaxb2Marshaller |
JAXB marshaller |
o.c.{DSL classes} |
o.c.dsl.* |
DSL support (see above) |
| Old package | New package | Description |
|---|---|---|
o.c.config.xml.* |
o.c.spring.config.xml.* |
Spring XML bean parsers (~75 classes) |
o.c.config.* |
o.c.spring.config.* |
Spring configuration classes |
o.c.config.handler.* |
o.c.spring.config.handler.* |
Namespace handlers |
o.c.config.util.* |
o.c.spring.config.util.* |
Parser utilities |
o.c.context.* |
o.c.spring.context.* |
Spring context (reference resolver, factory bean) |
o.c.report.* |
o.c.spring.report.* |
Listener factories |
o.c.functions.* |
o.c.spring.functions.* |
Function config and factories |
o.c.spi.* |
o.c.spring.spi.* |
Spring resource wrappers |
o.c.validation.* |
o.c.spring.validation.* |
Validator config and factories |
o.c.validation.matcher.* |
o.c.spring.validation.matcher.* |
Validation matcher factories |
o.c.common.* |
o.c.spring.* |
Spring test loader classes |
o.c.CitrusSpring* |
o.c.spring.CitrusSpring* |
Spring context/settings |
o.c.xml.* |
o.c.spring.xml.* |
Marshaller adapters |
| Old package | New package | Description |
|---|---|---|
o.c.actions.docker.* |
o.c.docker.* |
Docker actions and commands |
| Old package | New package | Description |
|---|---|---|
o.c.channel.* |
o.c.springintegration.channel.* |
Channel endpoints (~14 classes) |
o.c.channel.selector.* |
o.c.springintegration.channel.selector.* |
Message selectors (~8 classes) |
o.c.channel.endpoint.builder.* |
o.c.springintegration.channel.endpoint.builder.* |
Endpoint builders |
o.c.config.xml.* |
o.c.springintegration.config.xml.* |
XML parsers |
o.c.config.annotation.* |
o.c.springintegration.config.annotation.* |
Annotation configs |
o.c.config.handler.* |
o.c.springintegration.config.handler.* |
Namespace handlers |
o.c.actions.PurgeMessageChannel* |
o.c.springintegration.actions.* |
Purge channel action |
| Old package | New package | Description |
|---|---|---|
o.c.script.* |
o.c.groovy.actions.* |
Groovy actions |
o.c.message.builder.script.* |
o.c.groovy.message.builder.* |
Groovy payload builders |
o.c.config.xml.GroovyActionParser |
o.c.groovy.config.xml.GroovyActionParser |
XML parser |
o.c.util.GroovyTypeConverter |
o.c.groovy.util.GroovyTypeConverter |
Type converter |
| Old package | New package | Description |
|---|---|---|
o.c.actions.* (SQL classes) |
o.c.sql.actions.* |
SQL actions (4 classes) |
o.c.config.xml.* (SQL parsers) |
o.c.sql.config.xml.* |
XML parsers |
o.c.util.SqlUtils |
o.c.sql.util.SqlUtils |
SQL utilities |
| Old package | New package | Description |
|---|---|---|
o.c.variable.dictionary.xml.* |
o.c.xml.variable.dictionary.* |
XML data dictionaries |
o.c.xml.XsdSchemaRepository |
o.c.xml.schema.XsdSchemaRepository |
Schema repository |
o.c.xml.{LSResolverImpl,XmlConfigurer} |
o.c.xml.support.* |
XML support utilities |
o.c.util.XMLUtils |
o.c.xml.support.XMLUtils |
XML utilities |
o.c.XmlValidationHelper |
o.c.xml.support.XmlValidationHelper |
Validation helper |
o.c.dsl.{XmlSupport,XpathSupport} |
o.c.xml.dsl.* |
DSL support |
o.c.functions.core.{Xpath,EscapeXml,CreateCData} |
o.c.xml.functions.core.* |
XML functions |
o.c.message.builder.MarshallingPayloadBuilder |
o.c.xml.message.builder.MarshallingPayloadBuilder |
Marshalling payload builder |
o.c.message.selector.* (XPath/RootQName) |
o.c.xml.message.selector.* |
Message selectors |
o.c.config.xml.* (schema parsers) |
o.c.xml.config.xml.* |
XML config parsers |
| Old package | New package | Description |
|---|---|---|
o.c.variable.dictionary.json.* |
o.c.json.variable.dictionary.* |
JSON data dictionaries |
o.c.dsl.{JsonSupport,JsonPathSupport} |
o.c.json.dsl.* |
DSL support |
o.c.functions.core.{JsonPatch,JsonPath} |
o.c.json.functions.core.* |
JSON functions |
o.c.message.builder.ObjectMappingPayloadBuilder |
o.c.json.message.builder.ObjectMappingPayloadBuilder |
Object mapping payload builder |
o.c.message.selector.JsonPathPayload* |
o.c.json.message.selector.* |
Message selectors |
o.c.config.xml.* (JSON parsers) |
o.c.json.config.xml.* |
JSON config parsers |
| Old package | New package | Description |
|---|---|---|
o.c.validation.script.* |
o.c.validation.groovy.* |
Groovy validators |
o.c.validation.script.sql.* |
o.c.validation.groovy.sql.* |
Groovy SQL validator |
| Old package | New package | Description |
|---|---|---|
o.c.validation.matcher.hamcrest.* |
o.c.validation.hamcrest.matcher.* |
Hamcrest matchers |
o.c.validation.{HamcrestHeaderValidator,HamcrestValueMatcher} |
o.c.validation.hamcrest.* |
Hamcrest validators |
o.c.container.HamcrestConditionExpression |
o.c.validation.hamcrest.HamcrestConditionExpression |
Condition expression |
| Old package | New package | Description |
|---|---|---|
o.c.jbang.* |
o.c.jbang.cli.* |
JBang main classes |
o.c.jbang.commands.* |
o.c.jbang.cli.commands.* |
CLI commands |
o.c.jbang.util.* |
o.c.jbang.cli.util.* |
Code analyzers |
o.c.jbang.maven.* |
o.c.jbang.cli.maven.* |
Maven resolver |
| Old package | New package | Description |
|---|---|---|
o.c.xml.namespace.CitrusNamespacePrefixMapper |
o.c.generate.xml.namespace.CitrusNamespacePrefixMapper |
Namespace mapper |
| Service file | Implementation |
|---|---|
META-INF/services/org.citrusframework.CitrusContext |
o.c.base.DefaultCitrusContext |
META-INF/services/org.citrusframework.context.TestContextFactory |
o.c.base.context.DefaultTestContextFactory |
- ~43 internal
META-INF/citrus/SPI files updated with new fully-qualified class names - Spring
spring.handlersupdated for bothcitrus-springandcitrus-spring-integrationto reflect new namespace handler packages
If you maintain custom SPI registrations referencing Citrus classes, update the fully-qualified class names accordingly.
If you use Spring XML namespace configuration (<citrus:...> elements), no changes are needed in your XML files — the namespace URIs remain the same. The internal handler classes have moved but the spring.handlers mappings are updated automatically.
However, if you reference Citrus Spring classes directly in your applicationContext.xml (e.g. factory beans by class name), update those references to use the org.citrusframework.spring.* packages.
o.c. = org.citrusframework. throughout this document.