The Artima Developer Community
Sponsored Link

Java Buzz Forum
JUnit ClassLoader proposed fix

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Scott Stirling

Posts: 54
Nickname: sstirling
Registered: Jan, 2003

Scott Stirling is a Senior Software Engineer at Workscape, Inc.
JUnit ClassLoader proposed fix Posted: Jul 20, 2003 9:49 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Scott Stirling.
Original Post: JUnit ClassLoader proposed fix
Feed Title: Blaug Blawg Blog
Feed URL: http://users.rcn.com/scottstirling/rss.xml
Feed Description: Java Testing, Tools and Engineering
Latest Java Buzz Posts
Latest Java Buzz Posts by Scott Stirling
Latest Posts From Blaug Blawg Blog

Advertisement

Here's a patch for JUnit's busted classloader: junit-patch.jar.  And below is XmlTest.java, a regression test that breaks (with a java.lang.LinkageError) with the old classloader and the swingui/awtui TestRunners, but passes with the patch.

junit-patch.jar contains two classes (source included):

  1. ReloadableTestClassLoader - a properly delegating custom ClassLoader that currently relies on a System property value for its classpath: junit.test.path. The fix can be ported to junit.runner.TestCaseClassLoader or it can be effected through a new ClassLoader like this one.
  2. ReloadingTestSuiteLoader - modified to return this custom ClassLoader. If I can get this fix applied to the real JUnit, this class wouldn't necessarily need to be modified (it's only like 5 lines) because we could fix the original TestCaseClassLoader instead of writing a new one. Whatever; minor detail.

XmlTest.java:

import junit.framework.TestCase;
import javax.xml.parsers.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class XmlTest extends TestCase { 
    Document doc = null;

    public void testXml() throws ParserConfigurationException { 
        doc = DocumentBuilderFactory.newInstance()
                                    .newDocumentBuilder()
                                    .newDocument();
        // System.out.println("Hello! I changed again");
        Element root = doc.createElement("xml-test"); 
        assertNotNull(root); 
    }
}

This is a simple test that reproduces a LinkageError with the JUnit buggy ClassLoader under the following conditions:

  1. Use Sun JDK 1.4.x
  2. Edit JUnit's excluded.properties so that you comment out the exclusion of org.w3c.dom.* -- this is necessary to reveal the bug and is the easiest test I could think of. Make sure your edited excluded.properties is first in the classpath or updated into junit.jar at junit/runner/excluded.properties (BTW, obviously the new ReloadableTestClassLoader doesn't use or rely on excluded.properties at all).
  3. Put the DOM interfaces (in Xerces these are in xml-apis.jar) and an XML parser impl, such as Xerces, in your classpath to reproduce the bug. Why? Since you will have unexcluded org.w3c.dom.* in excluded.properties, JUnit will attempt to load those interfaces rather than delegate to the system loader. But they aren't in the scope of JUnit's buggy classloader if they aren't in the JVM's system classpath, so you have to add them. I.e., the 1.4.x JVM loads these in its boot loader, whose classpath JUnit's buggy loader doesn't know about.
  4. Example of command line to use to reproduce the bug (using junit.jar from JUnit 3.8.1, but any version should work): java -cp .;junit.jar;xml-apis.jar;xerces.jar junit.swingui.TestRunner XmlTest

You should see this in the runner's error display window:

java.lang.LinkageError: Class org/w3c/dom/Document violates loader constraints
   at java.lang.ClassLoader.defineClass0(Native Method)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:502)
   at java.lang.ClassLoader.defineClass(ClassLoader.java:431)
   at junit.runner.TestCaseClassLoader.loadClass(TestCaseClassLoader.java:104) 
   at java.lang.ClassLoader.loadClass(ClassLoader.java:255)
   at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:315)
   at XmlTest.testXml(XmlTest.java:16)
   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:324)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at junit.swingui.TestRunner$16.run(TestRunner.java:623)

Now run the same test with the fixed ClassLoader:

  1. shadow classes in junit.jar by listing junit-patch.jar first in the classpath
  2. set junit.test.path property to include the path to XmlTest.class
  3. run XmlTest with the Swing or AWT test runner:
    java -cp junit-patch.jar;junit.jar -Djunit.test.path=. junit.swingui.TestRunner XmlTest

Read: JUnit ClassLoader proposed fix

Topic: GarbageColleciton in JavaGames Previous Topic   Next Topic Topic: Cycling

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use