使用 URLClassLoader 重新加载 jar 时出现问题
我需要为应用程序的某些部分向现有应用程序添加插件功能。我希望能够在运行时添加一个jar,并且应用程序应该能够在不重新启动应用程序的情况下从jar加载类。目前为止,一切都好。我使用URLClassLoader在线找到了一些示例,它工作正常。
我还希望能够在jar的更新版本可用时重新加载相同的类。我再次找到了一些示例,并且我所理解的实现这一目标的关键是我需要为每个新加载使用一个新的类加载器实例。
我写了一些示例代码,但遇到了NullPointerException。首先让我向你们展示代码:
package test.misc;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import plugin.misc.IPlugin;
public class TestJarLoading {
public static void main(String[] args) {
IPlugin plugin = null;
while(true) {
try {
File file = new File("C:\\plugins\\test.jar");
String classToLoad = "jartest.TestPlugin";
URL jarUrl = new URL("jar", "","file:" + file.getAbsolutePath()+"!/");
URLClassLoader cl = new URLClassLoader(new URL[] {jarUrl}, TestJarLoading.class.getClassLoader());
Class loadedClass = cl.loadClass(classToLoad);
plugin = (IPlugin) loadedClass.newInstance();
plugin.doProc();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
IPlugin是一个简单的界面,只有一个方法doProc:
public interface IPlugin {
void doProc();
}
和罐头。TestPlugin是这个接口的实现,doProc只打印出一些语句。
现在,我打包了jartest。TestPlugin 类放入一个名为 test 的 jar 中.jar并将其放在 C:\plugins 下并运行此代码。第一次迭代运行平稳,类加载没有问题。
当程序执行 sleep 语句时,我将 C:\plugins\test.jar 替换为包含同一类的更新版本的新 jar,并等待 while 的下一次迭代。这是我不明白的。有时,更新的类会重新加载而不会出现问题,即下一次迭代运行良好。但有时,我看到一个异常被抛出:
java.lang.NullPointerException
at java.io.FilterInputStream.close(FilterInputStream.java:155)
at sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream.close(JarURLConnection.java:90)
at sun.misc.Resource.getBytes(Resource.java:137)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:256)
at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at test.misc.TestJarLoading.main(TestJarLoading.java:22)
我在网上搜索并挠了挠头,但无法真正得出任何结论,为什么会抛出这个例外,而且也是如此 - 只是有时,并非总是如此。
我需要你的经验和专业知识来理解这一点。此代码有什么问题?请帮忙!!
如果您需要更多信息,请告诉我。感谢您的光临!