ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Filip Cruz <>
Subject Re: Class Loading Problems
Date Tue, 31 Jul 2001 16:15:56 GMT
This is interesting. I got the same kind of error (java.lang.LinkageError 
"loader constraints violated when linking org/xml/sax/InputSource 
class)when I ran JUnit from within JBuilder (without Ant) so I would agree 
that it is a fix that needs to happen in JUnit.

At 09:09 AM 7/31/2001 -0700, you wrote:
>Hello, I'm using Ant 1.3 to run JUnit 3.7 tests for an
>application that uses Xerces 1.4.1 and Xalan 2.1.
>However, my tests fail on trying to parse a DOM
>document because of a problem with a class loader (I'm
>not sure which loader). java.lang.LinkageError
>"loader constraints violated when linking
>org/xml/sax/InputSource class" I've had the same
>problem when running the same tests
>on the same application using the Swing or AWT JUnit
>test runner (and NOT using Ant). I managed to fix
>this problem thanks to a suggestion on the JUnit
>mailing list from Scott Stirling. He suggests a change
>to the file in the JUnit jar.
>This file tells the JUnit TestCaseClassLoader which
>classes it should not try to load. Instead these
>classes should be left to the JVM class loader.
>His suggestion was to supplement the list of excluded
>classes to exclude all org.w3c.dom.* and or.xml.sax.*
>classes. However, this workaround does not fix the
>problem of
>running JUnit tests from Ant where the tests (or the
>application being tested) involve org.xml.sax.*
>classes. Has anyone else experienced this problem?
>Does anyone
>know of any other fix that could solve this problem?
>Perhaps, it's a flaw in the AntClassLoader but as I
>don't know much about class loading matters I need
>some assistance in pin pointing the problem. Does
>anyone have any suggestions? Incidentally, I tried
>removing the JAXP jars (jaxp.jar
>and parser.jar) that come with Ant and replacing them
>with the Xalan and Xerces jars that my application
>uses. Ant continues to work fine but the tests still
>won't run. The reason I made this change was that I
>was under the impression (from reading the Java Spec
>that there would be no problem having two class
>loaders loading the same class. I also tried adding
>org.apache.* to the
> file (so that junit
>wouldn't try loading Ant/Xerces/Xalan classes!) but
>this didn't work either. Thanks,
>Jim. P.S. This is what Scott Stirling had to say about
>matter: The JUnit TestCaseClassLoader (the reloadable
>one) has
>a fundamental problem that results in frequent
>LinkageErrors under the following conditions: 1.  You
>use the JUnit Swing UI.
>2.  You use JAXP in your test cases or any classes
>referenced in your test cases, or even any
>"instanceof" expressions that reference JAXP classes.
>(By JAXP I mean the whole set of javax.* classes plus
>the org.w3c.dom.* and org.xml.sax.* classes) I can go
>into this in depth, but the bottom line
>problems are that JUnit loads classes from the same
>place as the JVM's system loader; the classpath.
>This necessitates the use of an exclusion list to
>filter out certain class names that either must be
>loaded by the system loader, or you would like to
>have loaded by the system loader.  The JUnit loader
>does not always delegate to the system loader when it
>should, particularly in the case of JAXP, which
>is a weird mix of classes whose names begin with the
>filtered "javax.*" and the unfiltered "org.w3c.*" and
>org.xml.*". JAXP is a special case because it is based
>on a set of
>javax.* classes.  All javax.* classes are excluded
>from the JUnit loader by default (in the
>default file) in junit.jar.  But
>JAXP, as shipped from Sun, comes with a bunch of other
>classes in org.w3c.* and org.xml.*.  The
>interesting thing is a direct dependency between
>javax.* classes and some other classes not in the
>usual exclusion list of com.sun.*, javax.*, etc. So
>what can happen, and frequently does when using the
>JUnit Swing UI with test cases or other classes, such
>as Log4J, that use JAXP, is that the JUnit
>class loader (properly) delegates javax.xml.* classes
>it "sees" to the system loader.  But then the system
>loader loads up a bunch of org.w3c.dom
>and/or org.xml.sax classes as the result of
>initializing and loading that JAXP class.  Later, if
>the JUnit loader comes across some org.w3c/xml class
>that it's never seen before, it tries to load it
>because the classname doesn't match one of the
>patterns in the exclude list. But it's already been
>loaded through the "backdoor" as
>the result of some other class loaded by the system
>loader (remember, the JVM keeps classes in
>their own namespace by identifying them by their fully
>qualified name plus the instance of their _defining_
>(not initiating) loader, AND, the JVM will
>attempt to assign all unloaded classes referenced by a
>defined class to that defining class's loader).  The
>JVM's classresolver routine keeps track of
>all these class loading events and "sees" that the
>JUnit loader is attempting to define a class that has
>already been defined by the system loader.  That's
>wrong because according to the rules of loader
>constraints, JUnit should delegate this load to the
>system loader. You can hack around this (I did) by
>catching the
>LinkageError in TestCaseClassLoader's loadClass()
>method and then making a recovery call to
>findSystemClass() -- thereby delegating to the system
>loader after the fact (which is OK).  This hack only
>works some of the time, though, because now
>you can have the reverse problem where the JUnit
>loader loads a host of org.*.* classes, and then the
>system loader violates the loader contraints
>at some point when it tries to do exactly what I
>described above with JAXP because it doesn't ever
>delegate to its child (the JUnit loader).
>Inevitably, if your test cases use many JAXP and
>related XML classes, one or the other ClassLoader will
>end violating the constraints whatever you do. So the
>solution in the existing JUnit is to definitely
>add org.w3c.dom.* and org.xml.sax.* to your
> if you're using any JAXP stuff.
>What can we learn from this?  Well, one thing is that
>it's a good idea to have your custom class loaders
>load classes from repositories other than the
>system classpath.  Note that the JVM's built-in
>classloaders work that way (one for the jre/ext dirs,
>another for the java.class.path). Anyway, the
> fix is just a matter
>of time before it becomes standard in JUnit, since
>JAXP will be a standard part of the 1.4
>JDK.  It'll be just like having org.omg.* excluded.
>Do You Yahoo!?
>Make international calls for as low as $.04/minute with Yahoo! Messenger

View raw message