views:

769

answers:

3

I run iplanet's java applcation server, something in it is loading commons-logging-1.0.4.jar

That's fine until one of my applications calls AuthSSLProtocolSocketFactory which is another apache library that also uses commons logging. I put the jar on the jvm classpath and get this error

Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy....

It seems that commons logger doesn't like having two instances of itself loaded in different classloaders. I assume the application server has its own classloader that's loading it the first time (Although I can't find any appserver configuration that mentions it) so when my application goes to load it a second time it throws that exception.

I can't change the webserver, and I can't change the apache library. Suggestions?

+2  A: 

Take a look at SLF4J.

Additionally, http://www.qos.ch/logging/classloader.jsp will help.

grayger
A: 

Not familiar with iplanet, but in WebSphere you can set your applications classloading policy to be PARENT_LAST. This will then load everything in your applications classloader before looking at the parent. This should resolve this kind of problem, assuming your have a similar setting.

This does mean that you will have to supply all the dependencies in your own application (which is the best practice anyway).

Robin
The default Java class loading strategy - PARENT FIRST - is baked into nearly all Java classes that have ever been written. These classes have been tested and tried under that strategy. There is however no guarantee they'll work under any other class loading strategy.Switching to a PARENT LAST class loading strategy is almost always something you'll come to regret, sometimes right away, something after months of development. Using PARENT LAST - although it may solve your current problem - is most likely not what you want.
Steven Devijver
@Steven Devijver I have not had any such problem, and it is the only way to get some applications to work in a JEE type environment. It is also the only way to guarantee that you are using the versions of dependent classes that you think you are. There are always classes on the servers classpath (especially for xml parsing) that can easily interfere with the independence of your own application. What exactly is it that you think will fail in this scenario? Classes will still get resolved, and the versions that you bundle with your application are used instead of those defined elsewhere.
Robin
A: 

Are you putting commons logging in your classpath explicitly? You said jvm classpath, so I assume you are specifying it on the command line when you start iPlanet. That's not the recommended way to load jars in J2EE apps.

The easiest thing is to just let the Apache library use the commons logging jar that comes with iPlanet. Don't put commons-logging.jar in your WEB-INF/lib dir or in any classpath setting and the iPlanet one should be picked up automatically.

AngerClown