// OSSeva Blog
MigrationMigrating Apache Camel 3 to 4: Java 17, Jakarta, and the Components That No Longer Exist
Why this cannot wait indefinitely
Apache Camel 3 is end of life. Its final release was 3.22.4 on 9 March 2025, and Camel's download page now lists only 4.x LTS releases as supported. Camel routes sit directly on untrusted input — file drops, queues, partner endpoints, unmarshalled XML and JSON — so an unpatched Camel is not an internal-only risk even when it is deployed as one.
The hard requirements
From Camel's own 3.x to 4.0 migration guide:
- Java 17. Camel 4 supports Java 17; support for Java 11 is dropped. Estates on Java 8 or 11 have a JVM migration inside the Camel one.
- Jakarta EE namespaces. Camel 4 moved from
javax.*tojakarta.*. Every such import in routes, processors, type converters and tests changes. - Spring Boot 3 / Quarkus 3. Camel Spring Boot is released in lockstep with Camel core, so Camel 4 means Spring Boot 3 — itself a Jakarta migration with its own Spring Framework 6 and Spring Security 6 consequences.
- JUnit 5. All JUnit 4 based
camel-testmodules were removed. Test suites written against them have to be ported before they can tell you whether the migration worked — which is an uncomfortable ordering problem worth solving first.
Components that were removed
Camel 4 deleted a set of components outright. The migration guide lists each with its alternative, and for several the alternative is “none”. Examples from that list: camel-any23, camel-atlasmap and camel-atmos have no replacement; camel-caffeine-lrucache points to camel-cache, camel-ignite or camel-infinispan; camel-cdi points to Camel Spring Boot or Camel Quarkus.
A removed component with no alternative is not a migration task, it is a redesign. Find these first:
# Every Camel component your build actually resolves
mvn dependency:tree -Dincludes=org.apache.camel \
| grep -oE 'camel-[a-z0-9-]+' | sort -u > components-in-use.txt
# Every endpoint URI scheme used in routes (Java DSL)
grep -rhoE '(from|to|toD|enrich|pollEnrich)\("[a-z0-9+-]+:' src/main \
| grep -oE '"[a-z0-9+-]+:' | tr -d '":' | sort | uniq -c | sort -rn
Compare components-in-use.txt against the “Removed Components” table in the migration guide. That comparison is the single highest-value hour in the project.
API changes that break compilation
The migration guide documents a long list. The ones that turn up most in real route bases:
@Produce(uri = "kafka:cheese")becomes@Produce("kafka:cheese")— theuriattribute was removed from@EndpointInject,@Produceand@Consume.@FallbackConverteris replaced by@Converter(fallback = true).InOptionalOutwas removed fromExchangePattern; useInOut.- The
InOnlyandInOutEIPs were removed. - All
asyncCallbackmethods onProducerTemplatewere removed in favour ofasyncSendandasyncRequest. getExtensiononCamelContextwas replaced bygetCamelContextExtension.- The String to
java.io.Filetype converter was removed — code that relied on the implicit conversion now fails at runtime rather than compile time, which makes it the one to grep for. - In the bean component, class types in method signatures now need
.classsyntax:method=foo(com.foo.MyOrder.class, true).
Most of these are mechanical. The type-converter removal and the YAML DSL change — the backwards-compatible mode that allowed steps as a child of route, from Camel 3.14 and older, is gone — are the ones that surface late.
Behaviour changes that do not break compilation
These are more dangerous, because nothing fails until production:
- Health checks. The guide notes, for example, that camel-kafka's producer-based health check behaves differently in Camel 4 and ends up disabled — so a readiness probe that passed in Camel 3 may no longer be checking what you think.
- XML serialization of routes now uses a generated serializer in
camel-xml-iorather than the JAXB one. Tooling that parses dumped route XML may see different output. - Third-party client swaps. Several components changed the library underneath them — camel-atom moved from Apache Abdera to RSSReader, camel-box moved from Box SDK v2 to v4 — so component options and edge-case behaviour shift even where the URI does not.
A sequence that works
- Inventory components and URI schemes. Diff against the removed list.
- Get to the last Camel 3 LTS (3.22.x) first and clear its deprecation warnings. They are the migration guide in executable form.
- Port tests to JUnit 5 while still on Camel 3. This is possible, and it means you arrive at Camel 4 with a working safety net instead of rebuilding it mid-flight.
- Move to Java 17 on Camel 3 so the JVM change is isolated.
- Then take Camel 4 and Spring Boot 3 together, with the javax to jakarta rewrite. OpenRewrite recipes handle the bulk of the namespace change; Camel ships its own upgrade recipes.
- Regression-test on real message samples, not synthetic ones. Integration bugs live in the edge cases of real payloads.
And then it starts again
The uncomfortable part: arriving on Camel 4 does not end the problem. Camel supports only its two most recent LTS lines, each for about a year. An integration estate that upgrades every two or three years — which is most of them — will be unsupported again within twelve months of finishing this migration.
That cadence mismatch is what OSSeva addresses: patched builds for Camel 2.x, 3.x and expired 4.x LTS lines, so your upgrade schedule is set by your release calendar rather than by Camel's.
Related
- Apache Camel 3 end of life · Camel 4.18 LTS
- Apache Camel extended support
- Spring Boot 2.x support — the other half of the Jakarta move
Tags
Related articles
Apache Camel vs Spring Integration: Differences, When to Use Each and Support Windows
October 8, 2026MigrationMongoDB vs MySQL vs PostgreSQL: Data Model, Transactions, Scaling, Licensing and Which to Choose
October 8, 2026MigrationPostgreSQL vs Aurora PostgreSQL vs RDS: Architecture, Billing, Version Support and When to Self-Manage
October 8, 2026Ready to get your open source under control?
Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.