I've written a custom classloader 'JarClassLoader', which itself works ok, since the following test case is green:
public void testJarClassLoader() throws Exception
{
JarClassLoader cl = new JarClassLoader();
cl.addURLsByClassPath("lib/a-lot-of-jars.jar|lib/more-jars.jar", "\\|");
Class c = cl.loadClass("com.packagepath.classname");
assertNotNull(c);
System.out.println("Class: "+ c);
}
But, the following test case would not work:
public void testSetThreadClassLoader() throws Exception
{
JarClassLoader cl = new JarClassLoader();
cl.addURLsByClassPath("lib/a-lot-of-jars.jar|lib/more-jars.jar", "\\|");
Thread t = new Thread() {
public void run()
{
TestCase.assertEquals("com.packagepath.JarClassLoader",
Thread.currentThread().getContextClassLoader().getClass().getName());
//this assertion passed
try
{
Class c = Class.forName("com.packagepath.classname");
//it doesn't work, throws ClassNotFoundException
TestCase.assertNotNull(c);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
**com.packagepath.classname.methodname("params");**
//it doesn't work, throws java.lang.ClassNotFoundException
}
};
t.setContextClassLoader(cl);
t.start();
}
notice the stared line, I wanted to use thread context classloader when I literally call a method.
I've read dozens of web pages and docs, none of them tells me certainly whether the bold line should work or not. I can't understand where went wrong.
Can literally called method use classloader to load the corresponding class? If not, why can't? I need it to work, since the calling in the jars that vendors provides are literally, not using reflection or anything else, and I have to assign different classloader for different threads to avoid name collision in the vendor jars.
Can anybody help me? Thanks a million!