.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を使用しています。