1

.jarファイルに含まれるクラスを動的にロードしようとしています。私はクラス名全体を知っており、クラスがインターフェースAlgorithmClassを実装していることを確信しています。私のコードは次のようになります。

addURLToSystemClassLoader(dir.toURI().toURL());
Class cl = Class.forName(algorithm.getClassName());
AlgorithmClass algorithmClass = (AlgorithmClass)cl.newInstance();

ここで、 dirは.jarファイルのFileオブジェクトであり、addURLToSystemClassLoader(URL)は次のようになります。

private void addURLToSystemClassLoader(URL url) throws IntrospectionException {
        URLClassLoader systemClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        Class<URLClassLoader> classLoaderClass = URLClassLoader.class; 
        try {
            Method method = classLoaderClass.getDeclaredMethod("addURL", new Class[]{URL.class});
            method.setAccessible(true);
            method.invoke(systemClassLoader, new Object[]{url});
        } catch (Throwable t) {
            t.printStackTrace();
            throw new IntrospectionException("Error when adding url to system ClassLoader ");
        }
    }

チェックしたところ、URLがクラスローダーに追加されています。

Classオブジェクトを取得しようとすると、次のエラーが発生します。

重大:javax.servlet.ServletException:java.lang.ClassNotFoundException:id3.Algorithm

(id3.Algorithmは、ロードしようとしているクラスのフルネームです)

以下のような新しいClassLoaderを作成してみました。

ClassLoader cload = new URLClassLoader(new URL[]{dir.toURI().toURL()}, ClassLoader.getSystemClassLoader());
Class cl = Class.forName(algorithm.getClassName(), false, cload);
AlgorithmClass algorithmClass = (AlgorithmClass)cl.newInstance();

しかし、エラーが発生します。

java.lang.NoClassDefFoundError:lib / Algorithm / AlgorithmClass

システムクラスローダーが持つすべてのURLを使用して新しいURLClassLoaderを作成しようとしましたが、効果は同じでした。

これの「最悪の」部分は、コードのこの部分をテストするために持っているjUnitテストで両方の方法が完全に正常に機能していることです。

アプリサーバーとしてGlassfish3.1.1を使用しています。

4

2 に答える 2

1

dir に「lib」を含めないでください。これを試して:

 ClassLoader cload = new URLClassLoader(new URL[]{dir.toURI().toURL()}, Thread.currentThread().getContextClassLoader());
 Class cl = Class.forName(algorithm.getClassName(), true, cload);
 AlgorithmClass algorithmClass = (AlgorithmClass)cl.newInstance();
于 2012-05-09T08:20:02.240 に答える
0

クラスローディングの問題があります。addURLToSystemClassLoader()あなたは、あなたが実際に一体であることに注意する必要があります...

jar をクラスパスに配置します。Class.forName()イディオムを使用します。失敗した場合は、ClassLoader をパラメーターとして受け取るバージョンを使用します。

   public static Class<?> forName(String name, boolean initialize,
                               ClassLoader loader)

Thread.currentThread().getContextClassLoader()ClassLoader パラメータとしてのパス。

以下の私の別の回答も参照してください。

于 2012-05-09T08:15:45.473 に答える