I was quite busy in the last weeks, we are starting couple of new projects for a long time customer so I had lot’s of work to do and very few time for blogging. On the other hand side I have some new topics to blog about, so it was quite a fair deal.
The last days I had some fun trying to access some Glassfish EJB from a Tomcat web container. Some of you will now start to suggest to use only the Glassfish, so that is the whole story: There is a service layer which provides access to services on the different backend systems. This service layer is provided by our customer using the Glassfish J2EE container. Our application is planned to run on a Tomcat 6 web container - which is some kind of work horse in the company.
I was quite busy in the last weeks, we are starting couple of new projects for a long time customer so I had lot’s of work to do and very few time for blogging. On the other hand side I have some new topics to blog about, so it was quite a fair deal.
The last days I had some fun trying to access some Glassfish EJB from a Tomcat web container. Some of you will now start to suggest to use only the Glassfish, so that is the whole story: There is a service layer which provides access to services on the different backend systems. This service layer is provided by our customer using the Glassfish J2EE container. Our application is planned to run on a Tomcat 6 web container - which is some kind of work horse in the company.
I would like to say this is a quit typical setup for EJB usage in the last years (EJB 1.x / EJB 2.x) so I didn’t expect any problems. I confess it was quit a time ago I used EJB, but I fooled around with EJB in BEA and JBoss a couple of years ago.
So we started very naive deploying the appserv-rt.jar and the dependencies into WEB-INF/lib directory of our web application automatically with the maven build. It turned out to be a bad idea. The Tomcat kind of started but the web application could not access any JNDI resources.
As a first fix we moved the Glassfish jars to the $TOMCAT_HOME/lib with basically the same result. So where is the glitch?
I decided to take a closer look to the appserv-rt.jar of the glassfish. I first thought this jar contains some kind of client runtime. You may imagine my … suprise … when I realized that this jar contains the application server runtime, which is almost the whole application server. At this point I decided to have a break and go home.
Some times the best ideas come, when you are distracted. So this morning under the shower I thougt that I have an idea who the bad guy is. I suspected the jndi.properties in the appserv-rt.jar to confuse the JNDI initialisation of the Tomcat.
The first thing I tried in the office, was to remove the file from the appserv-rt.jar but it didn’t work out. So I really stated to wonder. So consulted to web again and found a nice blog entry concerning the topic, the only difference was the Tomcat version (6 vs. 5.5). It proved my theory on one hand but it doesn’t work with the Tomcat 6. So I had to compare the two setups and elaborate the key differences.
In the Tomcat 5.5 the Glassfish jar files had to be put into the $TOMCAT_HOME/shared/lib folder. The Tomcat 6 only provides one library folder at $TOMCAT_HOME/lib. A very imporant difference to the classloading behaviuor between the two Tomcat versions. The Tomcat 5.5 classloader hierachy is to load from the tomcat common lib classloader first and use the shared lib classloader “afterwards”. In this configuration the classloader which is responsible for loading the Tomcat system classes has a higher priority to the classloader which loads the glassfish classes, so the JNDI startup could be performed by the Tomcat properly.
The Tomcat 6 doesn’t seem to have this mechanism an longer, but why are the glassfish classes are preferred? The answer to this question is as simple as it is painflul. The Glassfish libraries are beginning the the letter a (i.e. appserv-rt.jar) the tomcat libraries are starting the the letters c or t so that the glassfish libraries are earlier in the classpath and preffered to the Tomcat libraries.
This insight was the key to solving the problem. I renamed the appserv-rt.jar (and the dependencies) to xappserv-rt.jar and voilá it worked.
Edit: Sometimes later I discovered a better way to combine the Glassfish EJBs and the Tomcat Webcontainer.



#1 by Martin on 23. Februar 2009
Thank you for your article. It safed me a lot of time.
But I have still a prolem getting Tomcat 6.0.18 running after I copied the mentioned jar files and renamed it. Now Tomcat can’t create the resource instance processing the Global JNDI Resources.
Any idea what’s wrong here or how you solved this problem?