Deployment isolation and loader repositories have no effect
randahl Feb 18, 2006 1:20 PMINTRODUCTION
------------------
On a JBoss 4.0.3sp1 I am deplying two instances of the same application as two ear files
ApplicationA.ear
ApplicationB.ear
Inside each ear I have a jar containing some EJBs, and this jar actually contains several other jars containing the EJB classes. Like this for ApplicationA:
ApplicationA.ear/my-ejbs.jar/module1.jar
ApplicationA.ear/my-ejbs.jar/module2.jar
and similarly for ApplicationB:
ApplicationB.ear/my-ejbs.jar/module1.jar
ApplicatoinB.ear/my-ejbs.jar/module2.jar
The reason why I have module1 and module2 in both applications is that each application may be using different versions of the modules.
THE PROBLEM
----------------
The module1.jar contains both some classes and some configuration xml files. I use Hibernate, so for instance the module1.jar contains a hibernate.cfg.xml configuration file. This means that on my class path I have the following:
ApplicationA.ear/my-ejbs.jar/module1.jar/hibernate.cfg.xml
ApplicationB.ear/my-ejbs.jar/module1.jar/hibernate.cfg.xml
Now since ApplicationA and ApplicationB are different applications their hibernate.cfg.xml files are different. The hibernate.cfg.xml file nested inside ApplicationA.ear tells ApplicationA to use DatabaseA, and the file nested inside ApplicationB.ear tells ApplicationB to use DatabaseB.
However, my tests have shown that the way I have configured JBoss does not allow this to work. When I restart JBoss and start interacting with ApplicationA the code inside it requests the hibernate.cfg.xml file like this
getClass().getResource("/hibernate.cfg.xml");
This makes JBoss load the hibernate.cfg.xml file nested inside the ApplicationA.ear which says ApplicationA should use DatabaseA.
Then when I start interacting with ApplicationB and its code also makes a getResource(...) call that application is served the wrong hibernate.cfg.xml file from ApplicationA - the one that has already been loaded.
Informally speaking it looks as if JBoss thinks that because both hibernate.cfg.xml files share the same name and reside the same place on the classpath, they must be similar, and thus JBoss asumes it is safe to use the hibernate.cfg.xml file already loaded (which is wrong, of course).
MY CONFIGURATION
------------------------
Yes, I have already enabled application isolation like this (from ear-deployer.xml):
<attribute name="Isolated">true</attribute> <attribute name="CallByValue">true</attribute>
Yes, I have already assigned a unique class loader repository for each ear file like this for ApplicationA (from jboss-app.xml):
<loader-repository> ApplicationA:loader=ApplicationA.ear <loader-repository-config> java2ParentDelegation=false </loader-repository-config> </loader-repository>
This information is stored int the jboss-app.xml file inside the META-INF folder of each ear file and the folder also contains an application.xml file which says that the ear contains module1 and module2. Like this:
<application> <module> <ejb>module1.jar</ejb> <ejb>module2.jar</ejb> </module> </application>
So what I am trying to tell JBoss here is that each application ear contains its own module1.jar which should be loaded using a class loader which is unique for the ear.
ROUND UP
------------
Throughout the last weeks I have tried a huge number of possible configuration options but for unknown reasons I simply cannot make JBoss separate the application's resources from each other. I thought about simply renaming my hibernate.cfg.xml files so that the class path would look like
ApplicationA.ear/my-ejbs.jar/module1.jar/ApplicationA-hibernate.cfg.xml
ApplicationB.ear/my-ejbs.jar/module1.jar/ApplicationB-hibernate.cfg.xml
but I feel this is an impossible solution because I have lots of other xml files in each module and managing unique names for each and every xml file simply is not practical.
I think there must be a silver bullet configuration option that I have simply overlooked. If anyone have any suggestions I will be grateful for hearing from you.
Yours
Randahl