I have a number of applications that I am trying to deploy in the same JBoss 3.2.5 app server instance. Each of these applications is really just a collection of web services deployed via Axis. I am not using any EJBs (although I may in the future) so the ear files I deploy really just contain a war file. The web services in each application uses some common code packaged in separate jar files which are in turn packaged in the WEB-INF/lib directory inside the war file.
Until recently I had been running these apps in JBoss using the default "flat" unified class loading configuration. However I ran into problems when one of the apps was deployed with a different version of the common code. The unified class loader picked up the first version of a given class regardless of which application it is in (as expected). Naturally I started seeing all NoSuchMethodExceptions etc since some of the method signatures had changed.
In an attempt to solve this problem I tried to isolate the applications by enabling hierarchical class loading as documented in the JBoss Administration and Development manual as well as the Wikis on the JBoss web site. All seemed to be going OK, apps deployed, web services deployed and I could call some of web service the methods.
Then I hit a snag. One of the web services contains a factory that uses Digester to parse an xml configuration file and instate objects. The factory loads OK but when Digester tries to instantiate an object I get ClassNotFoundExceptions with an error string indicating that a suitable ClassLoader could not be found. I turned on tracing for the org.jboss.mx.loading package and it looks like the Digester object is being instantiated from the Digester class loaded from the jbossweb-tomcat50.sar archive. It looks like Digester objects created from this class cant see the classes in the war file.
I have configured the class loading in my jboss-web.xml file and set java2ParentDelegation to false to force hierarchical loading starting with the war file. Commons-digester.jar is in the WEB-INF/lib directory so I would have expected the Digester class to be loaded from my ear/war file(s) rather than from the jbossweb-tomcat50.sar archive. The Digester class should then be loaded by the same ClassLoader as the objects it is trying to instantiate.
I have also set UseJBossWebLoader to false in the jboss-service.xml file in jbossweb-tomcat50.sar. I am just trying to get JBoss/Tomcat to load classes from the application ear/war files before trying to load them from container.
Does any one have any idea what I am doing wrong here?
I see a similar issue in a similar setup, only different in that I have virtual hosts (on 3.2.5).
If I have 2 virtual hosts, with a different version of the same class (ie same name and package, different methods) , in each context of each virtual host , at run time you may not get the class you expect, in that virtual host 1 might use virtual host 2 class. It seems really wrong to me that this could happen.
I'll try your tips and see if I can get around it.
#UseJBossWebLoader to false in the jboss-service.xml
#enabling hierarchical class loading
To solve my simple problem I just needed to set false in:
set what to 'false'?
I was reading the Servlet 2.4 specification. The spec suggests that servlet containers should give preference to classes and resources that are contained in WEB-INF
[...] It is recommended also that the application class loader be implemented so that classes and resources packaged within the WAR are loaded in preference to classes and resources residing in container-wide library JARs.
Based upon my limited work with JBoss 4.0.0, the default configuration for JBoss does not comply with this recommendation. (Please correct me if I am wrong)