// 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
Migrating ActiveMQ Classic to Artemis: What Actually Changes
September 21, 2026MigrationUpgrading Apache NiFi 1.x to 2.0: The Sequence, What Breaks, and How to Scope It
September 20, 2026MigrationUpgrading Apache Solr 8 to 9: Reindexing, Java 11, and the Relevance Regression Nobody Budgets For
September 20, 2026Ready to get your open source under control?
Talk to an OSSeva engineer about CVE coverage, compliance, and migration support for your stack.