I have a legacy
J2EE application where the .ear is structureed like this:
.ear
META-INF
webapp1.war
webapp2.war
webapp3.war
archive1.jar
archive2.jar
...
archiveN.jar
I'm deploying this in
JBoss 4.0.3 SP1.
The problem is that all three .war files include the archiveX.jar files in their WEB-INF/lib directory as well. So there are 3 copies of each .jar (sometimes more) in the .ear.
I'm fixing the build.xml files so that the .war applications will share the .jar files at the top level of the .ear file and eliminiate the .jars from each WEB-INF/lib. I've modified each .war file to include a Class-Path: in its Manifest.mf so that they all use the .jar files at the top of the .ear file:
Class-Path: commons-beanutils.jar commons-codec-1.3.jar ...
The .war applications find the classes they need so the Class-Path: setting works as far as sharing common .jar files among multiple .war applications.
There's a new problem, however. The applications need to load some .properties files that are in the WEB-INF/classes directories of the respective .war files. Inside webapp2.war, for example, these .properties files are in
WEB-INF/classes
The old application (no Class-Path: entry in Manifest.mf and the .jar files in WEB-INF/lib) was able to load these .properties files from WEB-INF/classes. After putting the Class-Path: in the Manifest.mf so that the top level .jar files are used the .war applications can't load .properties files from WEB-INF/classes.
It appears that putting a Class-Path: in the Manifest.mf of a .war drops the WEB-INF/classes directory from the .war classpath in JBoss 4.0.3.
I've solved this by putting the .properties files in the top level of the .ear file, but I don't understand why I have to do this.
Here's how the code loads the .properties files works.
The files to be loaded are prefixed with a '/' like "/WebServices.properties". The loading is done by a shared utility class in one of the shared top level .jar files. It creates a FileInputStream like this:
is = this.getClass().getResourceAsStream(fileName);
The javadocs for Class.getResourceAsStream() say:
"The rules for searching resources associated with a given class are implemented by the defining class loader of the class. This method delegates to this object's class loader."
So maybe the issue isn't with with the Class-Path: dropping WEB-INF/lib from the class loader's classpath.
I believe that JBoss uses one class loader to load the top level .jar files and different class loaders for the .war applications. I'm speculating that when code in a .war calls a method in a class in one of the top level .jar files the relevant class loader is the one that loaded the top level .jar file and not the one that loaded the .war file (which would include WEB-INF/lib in its classpath).
The JBoss docs are, uh, in flux at the moment so they haven't been much use.
Can anyone shed some light on what is going on?
Thanks.