1

次のテストケースは緑色なので、それ自体は問題なく動作するカスタムクラスローダー「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での名前の衝突を避けるために、異なるスレッドに異なるクラスローダーを割り当てる必要があります。

誰でも私を助けることができますか?どうもありがとう!

4

1 に答える 1

2

各クラスは、独自のクラス ローダーを使用して他のクラスにリンクします。クラスローダーは通常、親に委譲します。スレッド コンテキスト クラス ローダーを変更して、クラスがリンク解除され、別のクラスに再リンクされることを期待することはできません。

したがって、リンクされたクラスが、リンクしているクラスと同じクラス ローダー インスタンス (または親) にあることを確認する必要があります。

于 2010-03-01T05:43:33.210 に答える