Name: nt126004 Date: 05/22/2003
FULL PRODUCT VERSION :
C:\jdk1.4.0\bin>java -version
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OS VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
settings a ClassLoader to a Thread doesn't work !
I have an object called 'AnObject' which is *not* part of the application classpath , i am trying to access this object via a thread which i customized
to use a specific ClassLoader,ClassLoader which *does* include this object.
What i found is :
1 - in the thread , using 'new AnObject()' ends with NoClassDefFoundError.
2 - in the thread , using Class.forName() to load the AnObject Class ends with
ClassNotFoundException.
3 - in the thread , when using Class.forName() with the context ClassLoader ,
the AnObject class is finnaly avaiable.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The source code contains 2 files :
1 - ThreadContextClassLoaderTester
2 - AnObject
Run the ThreadContextClassLoaderTester and follow the popup dialogs.
Note :
1 - When compiling the ThreadContextClassLoaderTester , the AnObject class
should be in the classpath , *BUT* when running it shouldn't be in the
classpath , therefor before running make sure you remove the AnObject.class
from the classpath.
2 - ThreadContextClassLoaderTester takes as argument a dir which contains
the AnObject.class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect that the JVM will use the thread context ClassLoader making
new AnObject() , Class.forName() avaiable.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
//
// save in 2 public classes , 2 java files :
// 1 - ThreadContextClassLoaderTester
// 2 - AnObject
//
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.lang.reflect.*;
/** This tests the Thread Context ClassLoader , it attached
* a ClassLoader ,with a classpath to the 'AnObject' class , to an
* executing Thread which tries to access the 'AnObject' class
* (which is *not* on the application classpath.)
*
*/
public class ThreadContextClassLoaderTester {
public static void main(String args[]) throws MalformedURLException {
if (args == null || args.length == 0) {
System.err.println( "Usage : ThreadContextClassLoaderTester <dir>\n"
+"where dir is the directory which contains the "
+"'AnObject' class , this dir should *not* be in "
+"the classpath.");
System.exit(0);
}
new ThreadContextClassLoaderTester().run(args[0]);
}//main
public void run(String dirWithResourcesNotInClassPath)
throws MalformedURLException {
try {
new AnObject();
JOptionPane.showMessageDialog(null,"The 'AnObject' class is on "
+"your classpath remove it from the classpath.");
System.exit(1);
} catch (Throwable e) {
if (e instanceof NoClassDefFoundError) {
//its ok , AnObject is not on classpath
}
}
//create the thread classloader
File dir = new File(dirWithResourcesNotInClassPath);
URL[] urls = new URL[] {dir.toURL()};
URLClassLoader threadCL = URLClassLoader.newInstance(urls,null);
Thread t = new Thread() {
public void run() {
//test if the JVM uses the thread classloader when using the new
//keyword
JOptionPane.showMessageDialog(null,"Press to test if the JVM "
+"is using the Thread Context ClassLoader on new() ...");
try {
new AnObject();
} catch (Throwable e) {
if (e instanceof NoClassDefFoundError) {
JOptionPane.showMessageDialog(null,"The 'AnObject'"
+" class wasn't found on by the thread class loader!");
}
}
//test if the JVM uses the thread classloader when using
// Class.forName
JOptionPane.showMessageDialog(null,"Press to test if the JVM is"
+" using the Thread Context ClassLoader on "
+"Class.forName() ...");
try {
Class clazz = Class.forName("AnObject");
Object o = clazz.newInstance();
Method m = clazz.getMethod("echo",null);
m.invoke(o,null);
System.exit(1);
} catch (ClassNotFoundException e) {
JOptionPane.showMessageDialog(null,"The 'AnObject' class "
+"wasn't found on by the thread class loader!");
} catch (Exception e) {
e.printStackTrace();
}
//try using the thread classloader directly
JOptionPane.showMessageDialog(null,"Press to test when "
+"explicitly using the Thread Context ClassLoader on"
+" Class.forName() ...");
try {
Class clazz = Class.forName("AnObject",true
,Thread.currentThread().getContextClassLoader());
Object o = clazz.newInstance();
Method m = clazz.getMethod("echo",null);
m.invoke(o,null);
System.exit(1);
} catch (ClassNotFoundException e) {
JOptionPane.showMessageDialog(null,"The 'AnObject' class"
+" wasn't found on by the thread class loader!");
} catch (Exception e) {
e.printStackTrace();
}
}//run
};
t.setContextClassLoader(threadCL);
t.start();
try {
t.join();
} catch (InterruptedException e) {
}
System.exit(0);
}//main
}//class
public class AnObject {
public void echo() {
javax.swing.JOptionPane.showMessageDialog(null,"This is hello from AnObject :-)");
}
}//class
---------- END SOURCE ----------
(Review ID: 185788)
======================================================================
FULL PRODUCT VERSION :
C:\jdk1.4.0\bin>java -version
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OS VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
settings a ClassLoader to a Thread doesn't work !
I have an object called 'AnObject' which is *not* part of the application classpath , i am trying to access this object via a thread which i customized
to use a specific ClassLoader,ClassLoader which *does* include this object.
What i found is :
1 - in the thread , using 'new AnObject()' ends with NoClassDefFoundError.
2 - in the thread , using Class.forName() to load the AnObject Class ends with
ClassNotFoundException.
3 - in the thread , when using Class.forName() with the context ClassLoader ,
the AnObject class is finnaly avaiable.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The source code contains 2 files :
1 - ThreadContextClassLoaderTester
2 - AnObject
Run the ThreadContextClassLoaderTester and follow the popup dialogs.
Note :
1 - When compiling the ThreadContextClassLoaderTester , the AnObject class
should be in the classpath , *BUT* when running it shouldn't be in the
classpath , therefor before running make sure you remove the AnObject.class
from the classpath.
2 - ThreadContextClassLoaderTester takes as argument a dir which contains
the AnObject.class
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect that the JVM will use the thread context ClassLoader making
new AnObject() , Class.forName() avaiable.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
//
// save in 2 public classes , 2 java files :
// 1 - ThreadContextClassLoaderTester
// 2 - AnObject
//
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.lang.reflect.*;
/** This tests the Thread Context ClassLoader , it attached
* a ClassLoader ,with a classpath to the 'AnObject' class , to an
* executing Thread which tries to access the 'AnObject' class
* (which is *not* on the application classpath.)
*
*/
public class ThreadContextClassLoaderTester {
public static void main(String args[]) throws MalformedURLException {
if (args == null || args.length == 0) {
System.err.println( "Usage : ThreadContextClassLoaderTester <dir>\n"
+"where dir is the directory which contains the "
+"'AnObject' class , this dir should *not* be in "
+"the classpath.");
System.exit(0);
}
new ThreadContextClassLoaderTester().run(args[0]);
}//main
public void run(String dirWithResourcesNotInClassPath)
throws MalformedURLException {
try {
new AnObject();
JOptionPane.showMessageDialog(null,"The 'AnObject' class is on "
+"your classpath remove it from the classpath.");
System.exit(1);
} catch (Throwable e) {
if (e instanceof NoClassDefFoundError) {
//its ok , AnObject is not on classpath
}
}
//create the thread classloader
File dir = new File(dirWithResourcesNotInClassPath);
URL[] urls = new URL[] {dir.toURL()};
URLClassLoader threadCL = URLClassLoader.newInstance(urls,null);
Thread t = new Thread() {
public void run() {
//test if the JVM uses the thread classloader when using the new
//keyword
JOptionPane.showMessageDialog(null,"Press to test if the JVM "
+"is using the Thread Context ClassLoader on new() ...");
try {
new AnObject();
} catch (Throwable e) {
if (e instanceof NoClassDefFoundError) {
JOptionPane.showMessageDialog(null,"The 'AnObject'"
+" class wasn't found on by the thread class loader!");
}
}
//test if the JVM uses the thread classloader when using
// Class.forName
JOptionPane.showMessageDialog(null,"Press to test if the JVM is"
+" using the Thread Context ClassLoader on "
+"Class.forName() ...");
try {
Class clazz = Class.forName("AnObject");
Object o = clazz.newInstance();
Method m = clazz.getMethod("echo",null);
m.invoke(o,null);
System.exit(1);
} catch (ClassNotFoundException e) {
JOptionPane.showMessageDialog(null,"The 'AnObject' class "
+"wasn't found on by the thread class loader!");
} catch (Exception e) {
e.printStackTrace();
}
//try using the thread classloader directly
JOptionPane.showMessageDialog(null,"Press to test when "
+"explicitly using the Thread Context ClassLoader on"
+" Class.forName() ...");
try {
Class clazz = Class.forName("AnObject",true
,Thread.currentThread().getContextClassLoader());
Object o = clazz.newInstance();
Method m = clazz.getMethod("echo",null);
m.invoke(o,null);
System.exit(1);
} catch (ClassNotFoundException e) {
JOptionPane.showMessageDialog(null,"The 'AnObject' class"
+" wasn't found on by the thread class loader!");
} catch (Exception e) {
e.printStackTrace();
}
}//run
};
t.setContextClassLoader(threadCL);
t.start();
try {
t.join();
} catch (InterruptedException e) {
}
System.exit(0);
}//main
}//class
public class AnObject {
public void echo() {
javax.swing.JOptionPane.showMessageDialog(null,"This is hello from AnObject :-)");
}
}//class
---------- END SOURCE ----------
(Review ID: 185788)
======================================================================