Apache Camel 3 migration guide


Table of content

Apache Camel 3, included in release 20210412, is not compatible with previous versions and requires manual migration operations

Introduction

In release 20210412, Apache Camel is updated from the now deprecated 2.x version to the 3.x version. For this major release, they did lots of source code cleanups and refactorings that were postponed due to backward compatibility breaks. There were able to provide a cleaner API with improved performance, lower memory footprint and they split the Apache Camel monolithic core into multiple lightweight modules. The Apache Camel community wrote an official Apache Camel migration guide from 2.x to 3.0.

As this node upgrade requires also an application upgrade, this page presents the step-by-step guide to follow. It assumes that all application changes will be performed on a development environment and then the application is deployed on a production environment.

Migrating the development environment

Step 1: Upgrading the development environment

Follow Upgrade documentation up until the verification as data integration needs to be updated

Step 2: Update libraries

All previous Apache Camel libraries won't work, other libraries (such as drivers) will still work.

Managed libraries

Update all libraries in all spaces, see Managed libraries - Update documentation. Be aware that this operation needs to be done in all spaces with managed libraries.

Manual libraries

Update the libraries jar files of all libraries, retrieving them the way you usually do. You can also recreate them as managed libraries, they can be easily installed and updated on the development environment and are included inside appx files exactly like manual libraries so they behave like any other library on the production environment.

Notable library changes

Library Notable changes
camel-ahc
  • the standard Apache Camel AHC component now properly works on the node, no need for custom repackage
camel-http
  • camel-http now uses HTTPClient 4 instead of HTTPClient 3
  • camel-http4 is deleted
  • it's no longer http4s://my-server but simply https://my-server (automatically migrated)
camel-jetty
  • camel-jetty9 is renamed camel-jetty
  • it's no longer possible to write <to uri="jetty:http://my-server" /> you should use camel-http instead
camel-netty
  • camel-netty now uses Netty 4 instead of Netty 3
  • camel-netty4 is deleted
camel-quartz
  • camel-quartz now uses Quartz 2 instead of Quartz 1
  • camel-quartz2 is deleted
  • no longer need to write quartz2:// but simply quartz://
camel-restlet
  • camel-restlet is deleted
  • it's no longer possible to write <to uri="restlet:..." /> you should use camel-http instead
  • usage in <from uri="restlet:..." /> is no longer possible
camel-stream
  • no longer possible to use it to load an URL, you should use camel-http instead

Step 3: Update connectors

Once the libraries are updated, the connectors need to be refreshed.

SSL configuration package (automatic migration)

The package of SSL configuration objects has changed from org.apache.camel.util.jsse to org.apache.camel.support.jsse 

(info) This change is done automatically during the upgrade process.

TLS support update

For security reasons, SSL configurations only support TLSv1.2. To enable all TLS versions, configure the secureSocketPrototolsList attribute on your SSL configuration object to "TLSv1.2,TLSv1.1,TLSv1"

Step 4: Update routes

The routes are mostly automatically updated, few migrations cannot be performed automatically.

We'll first present the 2 manual migrations (but uncommon use-cases) then the automatic migrations.

Manual migration: <threads> is used differently

In Apache Camel 3.x, the way <threads> tags are used has changed

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<threads>
<log message="Using another thread" />
</threads>
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
      <threads />
<log message="Using another thread" />
</route>
</routes>

Manual migration: Simple no longer able to call clone method

In Apache Camel 2.x it was possible for the simple expression to call the clone method, it's no longer possible and you need to use groovy

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<setBody>
<simple>${body.clone}</simple>
</setBody>
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<setBody>
<groovy>body.clone()</groovy>
</setBody>
</route>
</routes>

Manual migration: Registry method changes

In Apache Camel 2.x it was possible to call deprecated lookup() methods on the Apache Camel Registry for accessing the connectors. They are now deleted as methods with more explicit names already exist for 8 years.

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:single?repeatCount=1" />
<setBody>
<groovy>
[
name: camelContext.registry.lookup('connector'),
nameAndType: camelContext.registry.lookup('connector', Date.class),
list: camelContext.registry.lookupByType(Date.class)
]
</groovy>
</setBody>
<log message="${body}" />
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:single?repeatCount=1" />
<setBody>
<groovy>
[
// lookup(String) is replaced by lookupByName(String)
name: camelContext.registry.lookupByName('connector'),
// lookup(String, Class) is replaced by lookupByNameAndType(String, Class)
nameAndType: camelContext.registry.lookupByNameAndType('connector', Date.class),
// lookupByType(Class) is replaced by findByTypeWithName(Class)
list: camelContext.registry.findByTypeWithName(Date.class)
]
</groovy>
</setBody>
<log message="${body}" />
</route>
</routes>

Automatic migration: Single "from" input

It's no longer to have a single <route> node with multiple <from uri="..." /> nodes. You can have multiple <route> nodes, one for each <from> node.

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:two?period=2s"/>
<from uri="timer:five?period=5s"/>
<!-- some process -->
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<!-- Only one "from" possible, sending to "direct" -->
<from uri="timer:two?period=2s"/>
<to uri="direct:process"/>
</route>
<route>
<!-- Only one "from" possible, sending to "direct" -->
<from uri="timer:five?period=5s"/>
<to uri="direct:process"/>
</route>
<route>
<!-- Starting from "direct" -->
<from uri="direct:process" />
<!-- some process -->
</route>
</routes>

Automatic migration: Set header/property notation

The header attribute name is no longer headerName but name. Same for property which is no longer propertyName by name.

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:two?period=2s"/>
<setHeader headerName="my-header">
<constant>my-value</constant>
</setHeader>
<setProperty propertyName="my-property">
<constant>my-value</constant>
</setProperty >
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:two?period=2s"/>
<!-- Attribute is "name" and no longer "headerName" -->
<setHeader name="my-header">
<constant>my-value</constant>
</setHeader>
<!-- Attribute is "name" and no longer "propertyName" -->
<setProperty name="my-property">
<constant>my-value</constant>
</setProperty >
</route>
</routes>

Automatic migration: HTTP component URI

Now that camel-http uses HTTPClient 4 and camel-http4 is deleted you no longer need to write http4s://my-server but simply https://my-server 

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:two?period=2s"/>
<to uri="http4s://my-server" />
</route>
<route>
<from uri="timer:five?period=5s"/>
<to uri="http4://my-server" />
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:two?period=2s"/>
<!-- URI is "https://" and no longer "http4s://" -->
<to uri="https://my-server" />
</route>
<route>
<from uri="timer:five?period=5s"/>
<!-- URI is "http://" and no longer "http4s://" -->
<to uri="http://my-server" />
</route>
</routes>

Automatic migration: Simple parsing update

In Apache Camel 2.x it was possible to write "simple" expressions variables without the ${} notation, it was deprecated and discouraged but was possible. It's no longer the case you have to surround your variable with the ${} notation.

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<setBody>
<simple>exchangeProperty.CamelTimerCounter</simple>
</setBody>
<log message="body" />
<toD uri="body" />
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<setBody>
<!-- Simple's exchangeProperty variable surrounded by ${} -->
<simple>${exchangeProperty.CamelTimerCounter}</simple>
</setBody>
<!-- Simple's body variable surrounded by ${} -->
<log message="${body}" />
  <!-- Simple's body variable surrounded by ${} -->
<toD uri="${body}" />
</route>
</routes>


Only the legacy simple expressions with the following formats are automatically migrated

  • <simple>a</simple>
  • <simple>a.b</simple>
  • <simple>a[b]</simple>

Other legacy simple expressions cannot be migrated automatically

Automatic migration: Simple property function

In Apache Camel 2.x it was possible to write "simple" expressions to access exchange properties with the ${property[name]} notation, it was deprecated and discouraged but was possible. It's no longer the case you have to access your exchange properties with the ${exchangeProperty[name]} notation.

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<setBody>
<simple>${property.CamelTimerCounter}</simple>
</setBody>
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<setBody>
<!-- Now named exchangeProperty instead of property -->
<simple>${exchangeProperty.CamelTimerCounter}</simple>
</setBody>
</route>
</routes>

Automatic migration: Simple and/or operators

In Apache Camel 2.x it was possible to write "simple" expressions with "and" and "or" operator. Now it's only possible to use "&&" (escaped "&amp;&amp;") and "||"

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<choice>
<when>
<simple>${header[A]} and ${header[B]}</simple>
<log message="Using and operator"/>
</when>
<when>
<simple>${header[A]} or ${header[B]}</simple>
<log message="Using or operator"/>
</when>
</choice>
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<choice>
<when>
<!-- Operator is replaced by "&&" (escaped) -->
<simple>${header[A]} &amp;&amp; ${header[B]}</simple>
<log message="Using and operator"/>
</when>
<when>
<!-- Operator is replaced by "||" -->
<simple>${header[A]} || ${header[B]}</simple>
<log message="Using or operator"/>
</when>
</choice>
</route>
</routes>

Automatic migration: Custom marshal/unmarshal

When using a data format defined in connectors you have to use the <custom /> generic data format

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<unmarshal ref="csv"/>
<log message="${body}"/>
<marshal ref="csv"/>
<log message="${body}"/>
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<unmarshal>
<!-- Connector data format referenced using "custom" -->
<custom ref="csv"/>
</unmarshal>
<log message="${body}"/>
<marshal>
<!-- Connector data format referenced using "custom" -->
<custom ref="csv"/>
</marshal>
<log message="${body}"/>
</route>
</routes>

Automatic migration: Zipfile data format name change

The zipFile data format is now named zipfile with a lowercase "f".

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<unmarshal>
<zipFile usingIterator="true"/>
</unmarshal>
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="direct-vm:test"/>
<unmarshal>
<!-- zipfile with a lowercase "f" -->
<zipfile usingIterator="true"/>
</unmarshal>
</route>
</routes>

Automatic migration: Context global options

It was possible to configure options at the Apache Camel context level and was misleading named properties, it's now named global options.

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:two?period=2s"/>
<script>
<simple>${camelContext.getProperties().put('isItASuccess', 'true')}</simple>
</script>
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:two?period=2s"/>
<script>
<!-- Context options now named "globalOptions" and no "properties" -->
<simple>${camelContext.getGlobalOptions().put('isItASuccess', 'true')}</simple>
</script>
</route>
</routes>

Automatic migration: Method call language connector

It was possible to configure the connector of a method tag using the bean attribute (which was deprecated), now only ref is supported (same behavior than before).

(error) Apache Camel 2.x, no longer supported (tick) Apache Camel 3.x
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:two?period=2s"/>
<setBody>
<method bean="connector" method="initialize()" />
</setBody>
</route>
</routes>
<routes xmlns="http://camel.apache.org/schema/spring"
xmlns:u="http://www.systar.com/aluminium/camel-util">
<route>
<from uri="timer:two?period=2s"/>
<setBody>
<!-- "bean" attribute is now "ref" -->
<method ref="connector" method="initialize()" />
</setBody>
</route>
</routes>

Step 5: Restart, validate and export

  • Restart the node
  • Verify that everything is working and finish the Upgrade documentation
  • Export the application

Migrating the production environment

Follow Upgrade documentation up until the verification

  • Import appx application updated to Apache Camel 3.x
  • Restart node
  • Verify that everything is working and finish the Upgrade documentation

Related Links