Discussion:
[XOM-interest] XOM bug error in static initializer while used in an agent
Arshan Dabirsiaghi
2010-02-11 20:13:37 UTC
Permalink
There is a bug in the static initializer of Verifier.java. It is similar or
the same as a bug discussed previously on this list [1]. To start, I'm
running into this unusual error with XOM 1.2.4 stable JAR when using it with
a Java agent:

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
at
sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:348)
Caused by: java.lang.ExceptionInInitializerError
at nu.xom.Element.build(Unknown Source)
at nu.xom.NodeFactory.startMakingDocument(Unknown Source)
at nu.xom.XOMHandler.startDocument(Unknown Source)
at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startDocument(AbstractSAXParser.java:284)
at
com.sun.org.apache.xerces.internal.impl.XMLNamespaceBinder.startDocument(XMLNamespaceBinder.java:462)
at
com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator.startDocument(XMLDTDValidator.java:663)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.startEntity(XMLDocumentScannerImpl.java:588)
at
com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1335)
at
com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDocumentEntity(XMLEntityManager.java:1267)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.setInputSource(XMLDocumentScannerImpl.java:281)
at
com.sun.org.apache.xerces.internal.parsers.DTDConfiguration.parse(DTDConfiguration.java:470)
at
com.sun.org.apache.xerces.internal.parsers.DTDConfiguration.parse(DTDConfiguration.java:552)
at
com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at nu.xom.Builder.build(Unknown Source)
at nu.xom.Builder.build(Unknown Source)
at aspect.foo.loadPolicy(PolicyReader.java:53)
... 6 more
Caused by: java.lang.RuntimeException: Broken XOM installation: could not
load nu/xom/characters.dat
at nu.xom.Verifier.loadFlags(Unknown Source)
at nu.xom.Verifier.<clinit>(Unknown Source)
... 25 more

This is definitely caused by this static initailizing block in Verifier.java
(line 58):

static {
ClassLoader loader = Verifier.class.getClassLoader();
if (loader != null) loadFlags(loader);
// If that didn't work, try a different ClassLoader
if (flags == null) {
loader = Thread.currentThread().getContextClassLoader();
loadFlags(loader);
}
}

The logic here is supposed to be as follows:
1. Get Verifier's class loader, and if its not null, loadFlags() with it.
2. If the flags are still null after that loadFlags() is done executing,
then try again with the current Thread's classloader

Unfortunately, the second step will never happen, because if Verfier's
classloader doesn't find the character file, loadFlags() will always throw
an unchecked RuntimeException, as can be seen here (Verifier.java, line 75):

InputStream raw = loader.getResourceAsStream("nu/xom/characters.dat");
if (raw == null) {
throw new RuntimeException("Broken XOM installation: " + "could not load
nu/xom/characters.dat");
}

So again, it will never check the Thread's classloader. I think this logical
bug is why my program doesn't work. My patch is simple. I changed the above
code to this:

InputStream raw = loader.getResourceAsStream("nu/xom/characters.dat");
if (raw == null) {
return;
}

I hope that helps.

Thanks,
Arshan

[1] http://lists.ibiblio.org/pipermail/xom-interest/2004-May/001177.html
Loading...