views:

321

answers:

1

We have encountered a very strange class not found problem in our web app running on Weblogic 10.3. In our code we do a pretty standard XSLT transformation.

UtilRequestManagerBean.java:

TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new StreamSource(new StringReader(xslBuffer.toString())));            
transformer.transform(new StreamSource(new StringReader(sourceBuffer.toString())), new StreamResult(sw));

This fails in our production environment (Solaris 10, if that matters) and produces a java.lang.NoClassDefFoundError:

<Mar 11, 2010 1:44:08 PM EET> <Info> <EJB> <BEA-010227> <EJB Exception occurred during invocation from home or business: com.company.basicservice.ejb.util.UtilRequestManagerBean_temuyq_HomeImpl@1737be7 threw exception: java.lang.NoClassDefFoundError: Could not initialize class com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary>

This class is part of rt.jar and is definitely in classpath. This is verified by the following Weblogic log snippet:

sun.boot.class.path = /opt/jdk1.6.0_12/jre/lib/resources.jar:/opt/jdk1.6.0_12/jre/lib/rt.jar:/opt/jdk1.6.0_12/jre/lib/sunrsasign.jar:/opt/jdk1.6.0_12/jre/lib/jsse.jar:/opt/jdk1.6.0_12/jre/lib/jce.jar:/opt/jdk1.6.0_12/jre/lib/charsets.jar:/opt/jdk1.6.0_12/jre/classes

And finally listing the contents of rt.jar shows that the class is there:

jar tvf /opt/jdk1.6.0_12/jre/lib/rt.jar | grep BasisLibrary.class
24787 Sat Jan 17 02:25:58 EET 2009 com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.class

So, what on earth could be the problem here?

+3  A: 

NoClassDefFoundError does not necessarily mean the Class was not found - it means the correct version of the class was not loaded.

Most likely multiple versions of the class getting loaded. Can you check if there is a source of conflict - example some classes are bundled in weblogic.jar as well.

Check for this package org/apache/xalan/internal/xsltc/runtime/BasisLibrary or the BasisLibrary class itself - is it present ?

Or try by putting rt.jar as the first jar in the classpath

JoseK
Yes, this indeed was the problem. There was an ancient xerces.jar lying aroung in the classpath of this legacy web application. This resulted in a wrong version of SAXParser being loaded and ended up in the confusing NoClassDefFoundException.BTW, is there a way to force the classloading order? I was under the impression that bootstrap classes are always in the beginning of the classpath, but this seems not to be always the case.
MarkoU
That should in theory never happen. It's always the bootstrap before extensions, then application. By any chance does your weblogic.xml have <prefer-web-inf-classes> set to true? Setting this element to True subverts the classloader delegation model so that class definitions from the Web application are loaded in preference to class definitions in higher-level classloaders.As far as I've used - this property was to load classes from WEB-INF instead of the EAR lib,and I've not seen it beat the bootstrap classpath.
JoseK
My theory is, that the classes were loaded in the following order:1. Legacy code is executed and a class from xerces.jar gets loaded2. Newer code (which is copied above) is executed. A class with similar name as in step 1 is requested and the already loaded legacy class is returned, which causes the errorThis would also explain the observed fact that the new piece of code sometimes works and sometimes not, depending on whether the legacy code has been executed first.Looking at the sources of TransformerFactory (and further into SecuritySupport) reveals some custom classloading also.
MarkoU