Details
-
Type: Bug
-
Status: Closed
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 1.2
-
Component/s: None
-
Labels:None
-
JDK version and platform:Sun 1.4.2_05
Description
I have written a testing tool that loads an
application package and will exercise the methods of various classes in
the package, and when it detects a problem, it serializes (using
XStream) the data necessary to reproduce the test case. Think of it as
JUnit on autopilot and steroids. The end result will be running
billions of test cases and boiling the error cases down to a handful
that can be reproduced at will.
Now, the problem: Since the application under test can depend upon a
large variety of libraries, I create a new URLClassLoader that
references all of the resources in the application package, create a
thread that uses the new classloader as its context classloader, and
start the thread. Thus my classloader hierarchy would look something
like this:
system -> rt.jar
parent -> tester.jar, xstream.jar ==> system
target -> foo.jar, bar.jar ==> parent
This works fine to run the tests and serialize the errors. When I go to
play back (ie: deserialize) the error cases, XStream throws
ConversionException, complaining that it can't find the class under
test.
Here's how I'm calling XStream to retrieve the serialized test case:
private static final XStream xstream = new XStream(new DomDriver());
public static Object readXML(ClassLoader classloader, File file) {
xstream.setClassLoader(classloader);
FileReader reader = null;
Object object = null;
try
catch (Exception e)
{ logger.error("Failed to recreate object", e); } finally {
if (reader != null) {
try
catch (IOException e) {}
}
}
return object;
}
I traced through everything and I discovered that the
JavaMethodConverter defaults to using the same classloader that loaded
JavaMethodConverter.class, and not the default classloader from the
active thread (ie: Thread.currentThread().getContextClassLoader()), or
the classloader that I set with xstream.setClassLoader().
This causes problems in my case because the application under test
doesn't use XStream, JavaMethodConverter is loaded from the parent
classloader, and thus can't load any classes from the target
classloader.
I can work around this by registering a new JavaMethodConverter that
uses my target classloader instead of the default, but how many other
converters will I need to register in order to ensure that all of
XStream is using the correct classloader?
Fixed. We do not have a lot of places, where we load classes directly. Should work all for now.