1. I need to package Camel dependencies into my WAR
TL;DR Try to avoid doing this. These dependencies are already provided for you by the container.
A more comprehensive answer as to why, is as follows.
First, a quick refresher on WildFly / EAP class loading fundamentals. The container leverages JBoss Modules. Modules can have dependencies on other modules, import specific package paths from other modules and apply restrictions to paths exported (or re-exported) from itself. Modules have their own class loader and the classes that are visible to it are governed by its module XML definition.
The Camel subsystem organizes Camel functionality into individual modules. In fact, there’s a module for each supported Camel component.
When you deploy a ‘fat’ WAR Camel application into the container, classes from libraries within
WEB-INF/lib are loaded by the deployment class loader. If your deployment happens to activate the Camel subsystem, it will automatically expose Camel (and many other) packages to the deployment class loader.
As things turn out, the container does a pretty good job in preventing class loading issues which can result from this scenario. But, there’s still no guarantee that your application will function 100% correctly.
In short, you’re better off scoping any Camel related dependencies as ‘provided’. If for some reason you need access to specific classes within any of the Camel component modules, you can always add module dependencies to your deployment with
jboss-deployment-structure.xml or via the
Dependencies: manifest header.
There’s more information about that here:
From a support and maintenance perspective, making use of the container provided dependencies is better because you only need to upgrade & patch the container, instead of rebuilding and redeploying all of your Camel applications.
If for some reason you really must bundle your application dependencies into the WAR, then consider disabling the Camel subsystem for your deployment.
2. I need spring-web to bootstrap my Camel Spring application
One of the nice features of the Camel subsystem is that it takes care of bootstrapping Spring for you.
All you need to do is to have appropriately named XML file(s) somewhere within your deployment. More on that here:
web.xml or the Spring
ContextLoaderListener is not mandatory at all.
In fact, you can drop an XML file containing a
<CamelContext> definition into the container deployments directory and it will attempt to bootstrap your Camel application.
3. I can’t add extra Camel components
If you want to work with a component that’s not provided by the Camel Subsystem, you can add it yourself by the following methods.
1. Custom component module
You can add to the collection of Camel component modules by following this guide. This is the preferred option.
2. Module dependencies
Another option is to use a combination of module dependencies and libraries within
WEB-INF/lib. Here’s an example application which uses this approach to add the camel-jetty component.
If you follow any of the above, ensure the component libraries you add match up with the Camel version provided by the container.
4. I need to use CDI or Spring beans to configure everything
You can wire up your own beans for things like JDBC
ConnectionFactory, Java Mail
MailSession, connection pools etc. But this can be quite laborious.
You can simplify your application by configuring these things as managed container resources and have them injected into your app. Or you can look them up via JNDI.
When using camel-cdi you can use the
@Produces annotation to help discover container managed resources. For example:
Then camel can reference the bean:
In Spring XML, you can use the
JndiObjectFactoryBean or the shortened ‘jee’ namespace:
One common pattern for testing that I see, is to write unit tests in the traditional way with JUnit and maybe some of the helper classes provided by Camel and Spring.
This is all good, but often it leads to tests being executed on a ‘flat’ class path. Remember from point 1, this is not how the WildFly / EAP runtime works. Within the container we run in a modular class loading environment.
If you run your WildFly / EAP Camel application tests exclusively on a flat class path, they’re not really proving that your app will behave properly when deployed into the container.
Hopefully this post helps to clarify some misconceptions about the Camel subsystem. Following the above advice should help you avoid some common problems & mistakes.