次のテストケースは緑色なので、それ自体は問題なく動作するカスタムクラスローダー「JarClassLoader」を作成しました。
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);
}
ただし、次のテスト ケースは機能しません。
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();
}
凝視された行に注目してください。文字通りメソッドを呼び出すときに、スレッド コンテキスト クラスローダーを使用したかったのです。
私は何十もの Web ページやドキュメントを読みましたが、太字の行が機能するかどうかを確実に教えてくれるものはありません。どこが間違っていたのか理解できません。
文字通り呼び出されたメソッドは、クラスローダーを使用して対応するクラスをロードできますか? そうでない場合、なぜできないのですか?ベンダーが提供するjarでの呼び出しは文字通り、リフレクションなどを使用していないため、機能する必要があり、ベンダーjarでの名前の衝突を避けるために、異なるスレッドに異なるクラスローダーを割り当てる必要があります。
誰でも私を助けることができますか?どうもありがとう!