I did find an example of how to use Guice with Apache Camel but it wasn’t commented well and involved doing a lot of extra work that didn’t provide me any benefits. So below I’ve listed the things that you’ll need to do to get Guice and Camel working together. What we are doing here is setting up Guice as a JNDI provider and automatically loading a Guice CamelModule via JNDI.
Step 1: Create a jndi.properties file in your project’s resources directory. The java.naming.factory.initial line tells JNDI to use Guice, the org.guiceyfruit.modules tells the javax.naming.InitialContext class which module it should run at startup.
jndi.properties
12345
# Guice JNDI providerjava.naming.factory.initial=org.apache.camel.guice.jndi.GuiceInitialContextFactory# list of guice modules to boot up (space separated)org.guiceyfruit.modules=com.timmattison.CamelGuiceApplicationModule
Step 2: Create a class with a static main method that will run your Camel routes. Because JNDI and Guice do most of the work there isn’t much to do here.
com.timmattison.CamelApplication
12345678910111213141516171819
packagecom.timmattison;importjavax.naming.InitialContext;/** * Created by timmattison on 10/27/14. */publicclassCamelApplication{publicstaticvoidmain(String[]args)throwsException{// Create the Camel context with GuiceInitialContextcontext=newInitialContext();// Loop foreverwhile(true){// Sleep so we don't kill the CPUThread.sleep(10000);}}}
Step 3: Create a class that extends RouteBuilder that implements a route (or multiple routes).
I moved the constants out to separate classes so they’d be easier to refer to in other places if necessary.
com.timmattison.CamelConstants
12345678
packagecom.timmattison;/** * Created by timmattison on 10/27/14. */publicclassCamelConstants{publicstaticfinalStringDIRECT_TEST_ROUTE_1="direct:testRoute1";}
com.timmattison.HttpConstants
12345678910
packagecom.timmattison;/** * Created by timmattison on 10/27/14. */publicclassHttpConstants{publicstaticfinalStringTEST_URL_1="/test1";publicstaticfinalStringTEST_URL_2="/test2";publicstaticfinalStringTEST_URL_3="/test3";}
com.timmattison.RestRoutes
1234567891011121314151617181920
packagecom.timmattison;importorg.apache.camel.builder.RouteBuilder;importorg.apache.camel.model.rest.RestBindingMode;/** * Created by timmattison on 10/27/14. */publicclassRestRoutesextendsRouteBuilder{publicstaticfinalStringRESTLET="restlet";publicstaticfinalintPORT=8000;@Overridepublicvoidconfigure()throwsException{restConfiguration().bindingMode(RestBindingMode.auto).component(RESTLET).port(PORT);rest(HttpConstants.TEST_URL_1).get().to(CamelConstants.DIRECT_TEST_ROUTE_1);}}
Step 4: Create the interfaces and the implementations that we’re going to use in our route.
Here we’re creating four things:
The interface that we’re implementing that handles the route (SayHello1) that gets injected with Guice via JNDI. This interface doesn’t do anything other than give Guice a way to reference implementations of it.
An implementation of that interface (BasicSayHello1). Also, BasicSayHello1 is going to have a dependency that we want injected with Guice to make the example more complete.
The interface for the class that we want Guice to inject (MessageHandler)
The implementation that gets injected (BasicMessageHandler)
com.timmattison.jndibeans.interfaces.SayHello1
123456789
packagecom.timmattison.jndibeans.interfaces;importorg.apache.camel.Processor;/** * Created by timmattison on 10/27/14. */publicinterfaceSayHello1extendsProcessor{}
com.timmattison.jndibeans.BasicSayHello1
123456789101112131415161718192021222324
packagecom.timmattison.jndibeans;importcom.timmattison.jndibeans.interfaces.SayHello1;importcom.timmattison.nonjndibeans.interfaces.MessageHandler;importorg.apache.camel.Exchange;importjavax.inject.Inject;/** * Created by timmattison on 10/27/14. */publicclassBasicSayHello1implementsSayHello1{privatefinalMessageHandlermessageHandler;@InjectpublicBasicSayHello1(MessageHandlermessageHandler){this.messageHandler=messageHandler;}@Overridepublicvoidprocess(Exchangeexchange)throwsException{exchange.getOut().setBody(messageHandler.getMessage(getClass().getName()));}}
packagecom.timmattison.nonjndibeans.interfaces;/** * Created by timmattison on 10/28/14. */publicinterfaceMessageHandler{publicStringgetMessage(Stringinput);}
com.timmattison.nonjndibeans.BasicMessageHandler
12345678910111213
packagecom.timmattison.nonjndibeans;importcom.timmattison.nonjndibeans.interfaces.MessageHandler;/** * Created by timmattison on 10/28/14. */publicclassBasicMessageHandlerimplementsMessageHandler{@OverridepublicStringgetMessage(Stringinput){return"Hello "+input+"!";}}
Step 5: Create the direct route that handles the route from RestRoutes
com.timmattison.DirectTestRoutes
1234567891011121314151617
packagecom.timmattison;importcom.timmattison.jndibeans.interfaces.SayHello1;importcom.timmattison.jndibeans.interfaces.SayHello2;importcom.timmattison.jndibeans.interfaces.SayHello3;importorg.apache.camel.builder.RouteBuilder;/** * Created by timmattison on 10/27/14. */publicclassDirectTestRoutesextendsRouteBuilder{@Overridepublicvoidconfigure()throwsException{from(CamelConstants.DIRECT_TEST_ROUTE_1).beanRef(SayHello1.class.getName());}}
Step 6: Create a Guice module that extends CamelModuleWithMatchingRoutes. I bound my SayHello1 interface to BasicSayHello1, MessageHandler to BasicMessageHandler, and included my RestRoutes and DirectTestRoutes.
com.timmattison.CamelGuiceApplicationModule
123456789101112131415161718192021222324
packagecom.timmattison;importcom.timmattison.jndibeans.BasicSayHello1;importcom.timmattison.jndibeans.interfaces.SayHello1;importcom.timmattison.nonjndibeans.BasicMessageHandler;importcom.timmattison.nonjndibeans.interfaces.MessageHandler;importorg.apache.camel.guice.CamelModuleWithMatchingRoutes;/** * Created by timmattison on 10/27/14. */publicclassCamelGuiceApplicationModuleextendsCamelModuleWithMatchingRoutes{@Overrideprotectedvoidconfigure(){super.configure();bind(SayHello1.class).to(BasicSayHello1.class);bind(MessageHandler.class).to(BasicMessageHandler.class);bind(RestRoutes.class);bind(DirectTestRoutes.class);}}
Now if you don’t want Guice to handle any external JNDI bindings then you’re done. You can run this application as-is and it will serve up the RESTlet route.
If you want to have Guice handle JNDI bindings you can easily add those into your module. For example, if I wanted to be able to get an instance of SayHello1 by using the JNDI name sayHello1FromGuice I could add this to my module:
This tells JNDI that our Guice provider will handle any JNDI requests for this name. Luckily, we didn’t have to create any of these manually because Guice automatically creates JNDI bindings for anything that you’ve called bind on using its class name.
For example there is an automatic JNDI binding for com.timmattison.jndibeans.interfaces.SayHello1 because we called bind(SayHello1.class).to(BasicSayHello1.class). If we ever want an instance of whatever Guice has bound to this we can ask JNDI for it using SayHello1.class.getName().
You’ll notice that in our DirectTestRoutes class we routed the direct test route to beanRef with the parameter SayHello1.class.getName(). That’s all you need to do as you add more classes to your Camel routes.