Configuring JMS in Apache CXF is possible but not really easy or nice. I have written a Tutorial on the Camel Wiki that shows how to use Apache Camel to provide a better JMS Transport for CXF.
Why not simply use JMS Features of Apache CXF
JMS configuration in Apache CXF is possible but the configuration is not very flexible and quite error prone. In CXF you have to configure a JMSConduit or a JMSDestination for each webservice. The connection between Conduit and the Service proxy is the endpoint name which looks like "{http://service.test\}HelloWorldPort.jms-conduit". As this name is never explicitly configured elsewhere it is quite probable that you misspell the name. If this happens then the JMS Transport just does not work. There is no good error reporting to show you what you did wrong. The next thing is that you have to use JNDI for the connectionFactory and the queue name. This is something that beginners with JMS have many problems with.
Why is using Apache Camel better in the JMS Transport layer
In apache camel you can simply reference the ConnectionFactory as a spring bean. This means you can either define it directly in a spring bean what is the ideal way to start or you can use spring´s JNDI binding to retrieve it from your application server for production use.
The next nice thing is that you can configure all JMS options like Receive Timeout or username / password in a central location, the JMSComponent and then share this config for several services. On the other hand you can easily configure different JMS providers.
The last thing that I do not need right now but is nice to have is that you have the full power of Camel´s routing config. So if you want to do additional things from simply calling the service it is easy.
How to do it
The Tutorial can be found in the Apache Camel Wiki
Better JMS Transport for CXF Webservice using Apache Camel
Thanks
Many thanks to Eduard Hildebrandt http://www.family-hildebrandt.com who helped a lot in making this example work by debugging all the problems we initially had and providing patches for the issues.
When I announced this Howto on the camel mailing list James Strachan told me that it is also possible to make your webservices transactional by using Spring declarative transactions. I will write a spearate article that focuses on how to do this.
Comments (5)
Aug 28, 2008
Eduard Hildebrandt says:
Thanks for the great article!Thanks for the great article!
Aug 31, 2008
Anonymous says:
Christian, thanks for this great tutorial. Much appreciated and thanks for donat...Christian, thanks for this great tutorial. Much appreciated and thanks for donating it to the Apache Camel documentation.
You can however use the links to the static html pages, they are much faster to load:
http://activemq.apache.org/camel/tutorials.html
And the direct link to you tutorial
http://activemq.apache.org/camel/better-jms-transport-for-cxf-webservice-using-apache-camel.html
Regards
Claus Ibsen
Apache Camel committer (davsclaus)
Oct 15, 2008
Anonymous says:
Is there an example for for CXF JMS transport with Spring running in a war? ...Is there an example for for CXF JMS transport with Spring running in a war? I can get the java stand alone to work following "Jax-WS Java First with jms Transport" from the cxf.apache.org tutorial. But I can't get it working when the service is deployed in a war? I can get the CXF client to send messages to the jms queue but the service (HelloWorld service) is not picking up the message. Are there any samples that has got it working in a web application?
thanks
Sonam
Oct 23, 2008
Christian Schneider says:
I have not tested with deployment in a war. But normally this should not matter....I have not tested with deployment in a war. But normally this should not matter. If you send me the project I can take a look at it.
Oct 27, 2008
Anonymous says:
Yes, you can edit the cornspoke under the main WSDL include directives. But that...Yes, you can edit the cornspoke under the main WSDL include directives. But that only works for version 1.9.x.SNAPSHOT. What I did was invert the compiler order and reset the context listener in web.xml, and it all worked perfectly for me.