This article introduces you to the latest major version of Apache Camel framework highlighting some noteworthy new features and updates available in Camel 4.
Camel 4 Highlights
In Camel 4, the primary focus revolves around several key advancements:
- The migration from
javax
tojakarta
APIs, aligned with the Java EE 10 standard, is a pivotal aspect. This upgrade facilitates compatibility with modern runtimes like Spring Boot 3 and Quarkus 3. - Camel 4 mandates Java 17 as the minimum requirement, with plans to support Java 21 in the subsequent LTS release by year-end.
- Another significant aspect of Camel 4 is performance optimization. Internal enhancements to the Camel routing engine and framework have significantly improved overall performance.
- Notably, the integration of Camel 4 with Spring Boot 3 showcases advancements in the Camel Spring Boot project. The usage of Spring Boot’s embedded HTTP server directly enhances performance, deviating from Servlet APIs previously employed.
A Camel 4 example
You can kick-start a Camel 4 application with any of the available Camel Maven archetypes . For example, if you want to bootstrap a new Camel 4 application using the Main Java archetype:
mvn archetype:generate \ -DarchetypeGroupId=org.apache.camel.archetypes \ -DarchetypeArtifactId=camel-archetype-java \ -DarchetypeVersion=4.3.0
Then, we will import the Camel 4 example in a IDE and so that we can customize it.
Customize the Camel 4 example
Firstly, replace the default Camel Route with something a bit more interesting:
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:beanToJson") .marshal().json(JsonLibrary.Jackson) .log("${prettyBody}"); } }
This Camel Route will marshal a Java Class into JSON using Jackson Library and produce the output in the log. Notice the usage of ${prettyBody}
which is a construct available of Camel 4 to pretty print JSON. To know more about this topic, we recommend reading this article: How to pretty print JSON in Java
Then, to be able to marshall your Beans, you will need to add the following dependency to your project:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jackson</artifactId> </dependency>
Next, add a Java Class or Record which will be marshalled into JSON:
public record Person(String name, int age) {}
Finally, we will modify the Main Camel Class to include a ProducerTemplate
that will send a Person Record to the Route:
public class MainApp { public static void main(String... args) throws Exception { Main main = new Main(); main.configure().addRoutesBuilder(new MyRouteBuilder()); main.start(); CamelContext context = main.getCamelContext(); ProducerTemplate producerTemplate = context.createProducerTemplate(); Person person = new Person("Alice", 30); // Sending the Person object to the route producerTemplate.sendBody("direct:beanToJson", person); Thread.sleep(2000); // Sleep to allow time for the route to process main.run(args); } }
Running the Camel 4 Route
You can run the main Class from your IDE or from the command line as follows:
mvn camel:run
From the Console output, expect to see the output of the Person Class transformed in a JSON as follows:
As you can see, the Route prints on the Console the Person Record in JSON format.
Camel Main noteworthy features
This example is a basic overview of the Camel Main framework which allows several advanced features. For example, you can add a listener to the Main Class to capture the beginning and the stop of a Camel Route. For example:
main.addMainListener(new MyListener()); .... public static class MyListener extends MainListenerSupport { @Override public void afterStart(BaseMainSupport main) { System.out.println("Main Camel Route started!"); } @Override public void beforeStop(BaseMainSupport main) { System.out.println("Main Camel Route stopped!"); } }
Let’s see another example: here is how you can bind a Bean in the Camel Main context. For example, here we are binding the Bean MyBean
as foo in the Main Context:
main.bind("mybean", new MyBean());
Then, you can refer to the Bean in any of your Camel Routes. For example:
private static class MyRouteBuilder extends RouteBuilder { @Override public void configure() throws Exception { from("timer:foo?delay={{millisecs}}") .bean("mybean"); } } public static class MyBean { public void echo() { System.out.println("You called MyBean"); } }
How to set Properties in your Camel main Route
Finally, we will mention something more about the properties you can use in a Camel Main Route. Out of the box, you will be able to inject properties in your Route which are present in the file application.properties.
For example, if you set the greeting properties in resources/application.properties you will be able to use it in your Route with:
log("{{greeting}}");
You can use it as well in your Beans by Injecting the Property as follows:
@Value("${greeting}") private String greeting;
On the other hand, if you want to use a different file as source of properties, then you can set the Property Placeholder location as follows:
main.setPropertyPlaceholderLocations("example.properties");
The following option sets a global option for the Camel Main application. Global options are available to all routes in the application.
main.configure().withGlobalOption("myglobal", "value")
You can also set Property as follows, however the difference is that you will not be able to modify them once you set them:
main.addInitialProperty("camel.variable.global:greeting", "Random number");
Lastly, to set Properties for a specific component, you can use the addProperty
method as in the following example which sets a Property for the SEDA component:
main.addProperty("camel.component.seda.defaultQueueFactory.counter", "123");
Conclusion
This article was a walk through some key features of Apache Camel 4 using as example the Camel Main framework. We encourage to migrate to this new Camel Release before the planned End of Life of Camel 3.22 which is set to December 2024
Source code for this article: https://github.com/fmarchioni/masterspringboot/tree/master/camel/camel4/camel4-main
Found the article helpful? if so please follow us on Socials