Apache Camel 4.x Upgrade Guide

This document is for helping you upgrade your Apache Camel application from Camel 4.x to 4.y. For example, if you are upgrading Camel 4.0 to 4.2, then you should follow the guides from both 4.0 to 4.1 and 4.1 to 4.2.

The Camel Upgrade Recipes project provides automated assistance for some common migration tasks. Note that manual migration is still required. See the documentation page for details.

Upgrading Camel 4.18 to 4.19

camel-bom

The camel-test module has been removed from camel-bom. This module was included by mistake, as since Camel 4, this is not a JAR but a pom.xml file. Camel end users should use the camel-test-junit5 / camel-test-junit6 JARs and the others directly.

camel-cloud (Removal)

The camel-cloud module and the serviceCall EIP have been removed. These were deprecated in Camel 3.19 and 4.7. The camel-service component has also been removed.

The cloud integration from the following components has been removed: camel-consul, camel-dns, camel-http, camel-jetty, camel-kubernetes, camel-netty-http, and camel-zookeeper.

camel-core

PQC TLS Auto-Configuration

When running on a JDK that supports X25519MLKEM768 (typically JDK 25+), Camel now automatically configures post-quantum hybrid named groups on all SSLContextParameters instances. The preferred group ordering is: X25519MLKEM768, x25519, secp256r1, secp384r1, followed by the remaining JVM defaults.

This auto-configuration activates only when the user has not explicitly set namedGroups or namedGroupsFilter. No changes are required for existing applications — the hybrid key exchange is backward-compatible with peers that do not support PQC.

See JSSE Utility for full details on PQC TLS configuration.

The WireTap EIP has removed the pattern option from its model (not in use) as wiretap always uses InOnly pattern.

Removed 2 deprecated methods in Java DSL for throttler EIP.

ErrorRegistry

A new ErrorRegistry SPI has been added to CamelContext for capturing routing errors. See Error Registry for more details.

Saga EIP

The Saga EIP has fixed the model for how to configure completion and compensation URIs.

For Java DSL there is no changes, but XML and YAML DSL is affected. Here the <compensation> and <completion> tags has been changed to be an attribute on <saga> instead as shown below:

Before:

<route>
    <from uri="direct:start"/>
    <saga sagaService="mySagaService">
        <compensation uri="mock:compensation"/>
        <completion uri="mock:completion"/>
        <option key="myOptionKey">
            <constant>myOptionValue</constant>
        </option>
        <option key="myOptionKey2">
            <constant>myOptionValue2</constant>
        </option>
    </saga>
    <choice>
        <when>
            <simple>${body} == 'fail'</simple>
            <throwException exceptionType="java.lang.RuntimeException" message="fail"/>
        </when>
    </choice>
    <to uri="mock:end"/>
</route>

In YAML DSL the changes are even simpler as the endpoint is moved from uri to the value of completion or compensation.

- route:
    from:
      uri: direct:start
      steps:
        - saga:
            sagaService: mySagaService
            compensation:
              uri: mock:compensation
            completion:
              uri: mock:completion
            key: myOptionKey2
        - choice:
            when:
              - expression:
                  simple:
                    expression: "${body} == 'fail'"
                steps:
                  - throwException:
                      message: fail
                      exceptionType: java.lang.RuntimeException
        - to:
            uri: mock:end

After:

<route>
    <from uri="direct:start"/>
    <saga sagaService="mySagaService" compensation="mock:compensation" completion="mock:completion">
        <option key="myOptionKey">
            <constant>myOptionValue</constant>
        </option>
        <option key="myOptionKey2">
            <constant>myOptionValue2</constant>
        </option>
    </saga>
    <choice>
        <when>
            <simple>${body} == 'fail'</simple>
            <throwException exceptionType="java.lang.RuntimeException" message="fail"/>
        </when>
    </choice>
    <to uri="mock:end"/>
</route>
- route:
    from:
      uri: direct:start
      steps:
        - saga:
            sagaService: mySagaService
            compensation: mock:compensation
            completion: mock:completion
            key: myOptionKey2
        - choice:
            when:
              - expression:
                  simple:
                    expression: "${body} == 'fail'"
                steps:
                  - throwException:
                      message: fail
                      exceptionType: java.lang.RuntimeException
        - to:
            uri: mock:end

camel-csimple (Deprecation)

The csimple (compiled simple) language has been deprecated. Use the simple language instead. The camel-csimple-joor module is also deprecated. The csimple language and related modules will be removed in a future release.

camel-simple

In the simple language then init blocks syntax has changed to require that each variable ends with a semicolon and new line (no trailing comments etc is allowed)

For example

    - setBody:
        simple:
          expression: |-
            $init{
              // this is a java like comment
              $sum := ${sum(${header.lines},100)}

              $sku := ${iif(${body} contains 'Camel',123,999)}
            }init$
            orderId=$sku,total=$sum

Should be changed to have semicolons as shown below:

    - setBody:
        simple:
          expression: |-
            $init{
              // this is a java like comment
              $sum := ${sum(${header.lines},100)};

              $sku := ${iif(${body} contains 'Camel',123,999)};
            }init$
            orderId=$sku,total=$sum

camel-test-infra

The test infrastructure modules no longer produce test-jar artifacts. All classes (service interfaces, container implementations, JUnit extensions, and service factories) are now packaged in the regular JAR artifact.

If your project depends on camel-test-infra-* modules with <type>test-jar</type>, remove the <type> element:

Before:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-test-infra-kafka</artifactId>
    <version>${camel.version}</version>
    <type>test-jar</type>
    <scope>test</scope>
</dependency>

After:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-test-infra-kafka</artifactId>
    <version>${camel.version}</version>
    <scope>test</scope>
</dependency>

This applies to all camel-test-infra-* artifacts, including camel-test-infra-common.

camel-yaml-io / camel-xml-io

In the YAML DSL we have renamed routePolicy to routePolicyRef on the route node, as that is the correct name.

When dumping routes in YAML or XML format via camel-yaml-io or camel-xml-io then the structure of routes and all the EIP options now respect the intended order in the model.

For example id is always first, and the following attributes are ordered so the most commonly used at in the top. EIPs such as circuitBreaker now has onFallback last.

This order is also the same order that UI builders like Camel Karavan and Kaoto do as well.

Jackson 3 components

Four new components have been added which provide Jackson 3 support - they are named similarly to the previously existing camel-jackson components. Jackson 3 operates under a different package name (tools.jackson.* vs. com.fasterxml.jackson) and there are a number of API changes between Jackson 2 and Jackson 3 - see the Jackson Migration Guide for details.

.Jackson Components
[cols="1,1",options="header"]
|===
|Jackson 2 component |Jackson 3 component
|camel-jackson
|camel-jackson3
|camel-jackson-avro
|camel-jackson3-avro
|camel-jackson-protobuf
|camel-jackson3-protobuf
|camel-jacksonxml
|camel-jackson3xml
|===

The camel-jackson3 component shares a unified DSL with the camel-jackson component under the "jackson" name. DefaultDataFormatResolver and DefaultTransformerResolver resolve which Jackson library version is available on the classpath and choose the appropriate data format or transformer. This allows easy migration from the camel-jackson component to the camel-jackson3 component and a consistent interface between the two.

The same detection mechanism and combined interface extends to the other Jackson data formats (avroJackson, protobufJackson, and jacksonXml).

camel-jbang

Support for exporting to use Gradle as build tool has been removed (it was deprecated and not working well) The deprecated options buildToool and gradleWrapper has been removed.

The camel-tooling-maven which is used for downloading JARs from Maven has been refactored to use the new MIMA project (jbang is using this also).

camel-groovy

The Groovy library has been upgraded from 4.0.x to 5.0.x. This is a major version upgrade. If you use Groovy scripts or the Groovy DSL, review the Groovy 5.0 release notes for potential breaking changes. The Spock testing framework has also been upgraded to 2.4-groovy-5.0.

camel-groovy-xml

The camel-groovy-xml has been moved into camel-groovy and this JAR is no longer shipped. So if you use camel-groovy-xml then change the dependency to camel-groovy.

camel-kafka

The Kafka client library has been upgraded from 3.9.1 to 4.2.0. This is a major version upgrade of Apache Kafka with several notable changes:

  • The default value of lingerMs (producer linger.ms) has been changed from 0 to 5 to align with the Kafka 4.x default. This improves batching efficiency as larger batches typically result in similar or lower producer latency.

  • Two new consumer configuration options have been added:

    • groupProtocol — Controls which consumer group protocol to use. Valid values are classic (default) and consumer. Setting this to consumer enables the new KIP-848 consumer rebalance protocol which provides faster and more efficient rebalancing.

    • groupRemoteAssignor — The name of the server-side assignor to use when groupProtocol is set to consumer. If not specified, the group coordinator will use the default assignor configured on the broker.

  • If you had explicitly configured the partitioner option to use org.apache.kafka.clients.producer.internals.DefaultPartitioner or org.apache.kafka.clients.producer.UniformStickyPartitioner, you must remove that configuration as these classes have been removed in Kafka 4.0. The built-in default partitioner (used when no partitioner is set) continues to work.

Camel will now defer starting Kafka consumers during startup of CamelContext to after the context is fully started, to ensure that any incoming message from Kafka brokers are only received by Camel when everything is fully started.

camel-google-pubsub-lite

The camel-google-pubsub-lite component has been removed. The component was deprecated in Camel 4.10 following Google Cloud Platform’s deprecation of the underlying Pub/Sub Lite service.

Google recommends migrating your Pub/Sub Lite workloads to either:

  • Google Cloud Pub/Sub → use the camel-google-pubsub component

  • Google Cloud Managed Service for Apache Kafka → use the camel-kafka component

camel-kafka

The Kafka client library has been upgraded from 3.9.x to 4.2.0. This is a major upgrade with the following notable changes:

  • The lingerMs option default value has changed from 0 to 5 to align with the Kafka 4.x client default for linger.ms.

  • Two new consumer options have been added: groupProtocol (default classic, enums: classic, consumer) and groupRemoteAssignor. These support the KIP-848 consumer rebalance protocol introduced in Kafka 4.0. When groupProtocol is set to consumer, the classic-only properties (heartbeatIntervalMs, sessionTimeoutMs, partitionAssignor) are automatically excluded from the consumer configuration.

  • The removed DefaultPartitioner and UniformStickyPartitioner classes are no longer available. If you were explicitly setting partitioner to one of these classes, remove the configuration as Kafka 4.x uses the default partitioner automatically.

The test infrastructure for Kafka has been updated:

  • The local-kafka3-container mapping has been renamed to local-kafka-container. If you were using -Dkafka.instance.type=local-kafka3-container, update to -Dkafka.instance.type=local-kafka-container.

  • The Strimzi test service now runs in KRaft mode (no ZooKeeper). The ZookeeperContainer class has been removed.

camel-json-patch

The camel-json-patch is now deprecated - the library it uses is not active maintained and this module does not work with Jackon 3.

camel-mail

When configured a custom IdempotentRepository on camel-mail endpoint, then Camel will now auto-start the bean which is similar to what camel-file do as well.

camel-openapi-java

When using code first Rest DSL and have configured base.path then this will now be exclusively used for the returned server url in the API specification.

For example here we set base.path=cheese:

restConfiguration().component("jetty").host("localhost").port(getPort())
        .contextPath("myapp")
        .apiContextPath("/api-doc")
        .apiProperty("cors", "true").apiProperty("base.path", "cheese")
        .apiProperty("api.title", "The hello rest thing").apiProperty("api.version", "1.2.3");

Then the generated API specification now returns:

  "servers" : [ {
    "url" : "http://localhost:58678/cheese"
  } ],

Previously the context-path would always be used:

  "servers" : [ {
    "url" : "http://localhost:58678/myapp"
  } ],

The intention is to allow to configure the base.path as is in the return API specification.

camel-as2

Some public constants were deprecated:

org.apache.camel.component.as2.api.AS2AsynchronousMDNManager.HTTP_REQUEST
org.apache.camel.component.as2.api.AS2AsynchronousMDNManager.HTTP_RESPONSE
org.apache.camel.component.as2.api.AS2ClientManager.HTTP_REQUEST
org.apache.camel.component.as2.api.AS2ClientManager.HTTP_RESPONSE
org.apache.camel.component.as2.api.AS2Constants.HTTP_CLIENT_CONNECTION

They can be replaced by the the getter/setter method of the HttpContext implementation, for example:

// the deprecated way
HttpRequest request = context.getAttribute(AS2ClientManager.HTTP_REQUEST, HttpRequest.class);

// new way
HttpRequest request = context.getRequest();

camel-couchbase

The designDocumentName and viewName endpoint options are now deprecated. MapReduce Views were deprecated in Couchbase Server 7.0 and do not work with the Magma storage backend (default since Couchbase Server 8.0).

The consumer now defaults to SQL (N1QL) queries instead of MapReduce Views. A new `statement` endpoint option allows providing explicit SQL queries. When no statement is set and useView is false (the default), the consumer auto-generates a SQL++ query from the endpoint options (bucket, collection, limit, skip, descending, rangeStartKey, rangeEndKey).

To continue using the deprecated MapReduce Views, set useView=true explicitly. See the component documentation for migration guidance.

camel-ftp

The camel-ftp component has been refactored to extract shared FTP/SFTP code into a new camel-ftp-common module. Classes such as BaseSftpConfiguration and AbstractSftpConsumer have been moved from camel-ftp to camel-ftp-common.

This is an internal refactoring that should not affect most users. However, if you extend these classes directly, you will need to add the camel-ftp-common dependency to your project:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-ftp-common</artifactId>
    <version>${camel.version}</version>
</dependency>

camel-azure (CredentialType standardization)

The component-specific CredentialType enums in all Azure components have been deprecated in favor of a single shared org.apache.camel.component.azure.common.CredentialType enum in the new camel-azure-common module. This shared enum contains the union of all credential types across all Azure components.

URI-based configuration (e.g., credentialType=AZURE_IDENTITY) requires no changes, as the enum value names are identical.

The component configuration classes still use the component-specific enum types for now. A future release will migrate the configuration to use the shared enum, at which point Java API users should update their imports:

Before:

import org.apache.camel.component.azure.storage.blob.CredentialType;

After:

import org.apache.camel.component.azure.common.CredentialType;

The deprecated component-specific enums will be removed in a future release. The new camel-azure-common module is automatically included as a transitive dependency of all Azure components.

camel-quickfix

Upgraded QuickFixJ from 2.3.2 to 3.0.0 in camel-quickfix component.

camel-ssh

Five new configuration properties have been added to the SSH endpoint to expose additional Apache MINA SSHD CoreModuleProperties:

  • heartbeatInterval — interval for SSH keep-alive heartbeats.

  • heartbeatReplyMaxWait — maximum wait time for a heartbeat reply.

  • authTimeout — timeout for the SSH authentication phase.

  • connectTimeout — timeout for establishing the SSH connection.

  • channelOpenTimeout — timeout for opening an SSH channel.

All properties default to 0, which means the Apache MINA SSHD defaults are used. This is an additive change with no impact on existing configurations.

MDC older logic (Deprecation)

The older logic used for MDC (enabled via camel.main.useMdcLogging = true) is deprecated in favor of camel-mdc component.

camel-tracing (Deprecation)

The camel-tracing and related components (camel-opentelemetry and camel-observation) are now deprecated. You should move your implementation to the newer camel-telemetry components (camel-opentelemetry2 and camel-micrometer-observability). We have implemented these new components in order to fix certain design flaws (mainly, span duplications) identified in the older components.

Some minor difference may be expected when moving to the new components, make sure to read the documentation carefully.

Removed deprecated components

The following deprecated components has been removed:

  • camel-nitrite

  • camel-torchserve

  • camel-test-infra-torchserve