我正在尝试动态加载.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测试中都能正常工作。
我正在使用Glassfish 3.1.1作为我的应用服务器。
答案 0 :(得分:1)
dir不应该包含&#39; lib&#39;。 试试这个:
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();
答案 1 :(得分:0)
您有类加载问题。你应该知道你的addURLToSystemClassLoader()
实际上是哎......
将你的jar放到classpath中。使用Class.forName()
成语。如果失败则使用接收ClassLoader作为参数的版本
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
和路径Thread.currentThread().getContextClassLoader()
作为ClassLoader参数。
另见下面我的另一个答案。