Мне нужно добавить функциональность плагина в существующее приложение для определенных частей приложения.Я хочу иметь возможность добавить 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();
}
, а jartest.TestPlugin - реализация этого интерфейса, где doProcпросто выводит некоторые операторы.
Теперь я упаковываю класс jartest.TestPlugin в jar с именем test.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)
Я искал в сети и почесал голову, но не могу прийти к какому-либо заключению относительно того, почему выбрасывается это исключение и что тоже - только иногдаНе всегда.
Мне нужен ваш опыт и знания, чтобы понять это.Что не так с этим кодом?Пожалуйста, помогите !!
Дайте мне знать, если вам нужна дополнительная информация.Спасибо за внимание!