views:

355

answers:

2

We have an application deployed in Websphere application server 7. Its deployed and functioning in various environments. But it gave a method not found exception in one new env. On digging deeper we found that a particular class was present in 2 jars and the class from the "wrong" jar was getting loaded in the new env. i went through the detailed class loader view and the sequence of the loading of jars were different in it.

On further investigation there seemed to be random variance in the order in which the jar files were loaded in each env.

2 questions:

1) On which factor does the WAS class loading policy depend & any suggestion for rectifying the problem?

2) More generally when we specify supposing *.jar in the classpath for any java program how does any JVM load the jars? Like is it alphabetical or according to time modified or any such file property?

A: 

When installing web-apps under WAS, you can set the classloading policy in the options for that application (or globally on server/node level)

If the policy options are (search) "parent first" / "parent last" and one class loader per application or per war. The default is "parent first / war". If your web-app comes with all jars it needs you'll be better off with the policy set to "parent last / application". Also if you edit your web.xml to reflect changes, be sure to set "use binary configuration" otherwise it will always use what it stored during install.

rsp
I have already completed those steps. The point of confusion is different. Supposing my web-app lib folder contains 4 jars like a.jar,b.jar,c.jar,d.jar, in what order are these 4 jars loaded? Hope I am making myself clear.Its not abut loading of jars relative to server and application. Rather the relative order of loading of the application jars.
Barun
If you need a specific sequence you can use the MANIFEST classpath setting (I've never done this but WAS docs mention it.) `WEB-INF/classes` is searched before the jars in `WEB-INF/lib` so you can extract the classes you need into that location. A workaround (to an unwanted situation) is to remove the offensive classes from the `.jar` before you package it into the `.war`
rsp
Hmm...both seem a bit ugly workarounds but then its fair as its a ugly problem. I had tried the second option. It gave more issues..basically because of a mixed up class environment at runtime.Any idea on what factors the loading of this jar depends?
Barun
Search order in /lib is undefined (as far as I know) when no classpath is set. So finding out how to define the web-app classpath in the MANIFEST file is your best bet. If you are able to place the `.jar` you want loaded first on the filesystem, you can define a shared library via the admin console and add it to your web-app's classpath. In WAS 6.1 the admin console contains a classloader explorer that might give insight in a solution.
rsp
A: 

Java loads classes in the order they are specified in the classpath. So if your classpath is "c:\jar1.jar;c:\jar2.jar" and jar1.jar and jar2.jar contain the same class, the class from jar1.jar will always be used. If the order was reversed, then the jar2.jar class would always be used.

Wikipedia explains how Class Loaders work pretty well http://en.wikipedia.org/wiki/Java_Classloader

The classpath can be configured through the WAS Admin Console on the Server under Server > Process Definition > Java Virtual Machine

It can also be configured per application.

Bert Lamb
I have already completed those steps. The point of confusion is different. Supposing my web-app lib folder contains 4 jars like a.jar,b.jar,c.jar,d.jar, in what order are these 4 jars loaded? Hope I am making myself clear.Its not abut loading of jars relative to server and application. Rather the relative order of loading of the application jars.
Barun
Gotcha, you may be able to specify the order for the WAR by adding a MANIFEST.MF file and specifying the Class-Path attribute there. More info here: http://java.sun.com/j2ee/verified/packaging.html
Bert Lamb