Я должен добавить сменную функциональность к существующему приложению для определенных частей приложения. Я хочу смочь добавить банку во времени выполнения, и приложение должно смочь загрузить класс из банки, не перезапуская приложение.Пока все хорошо. Я нашел некоторые образцы онлайн с помощью URLClassLoader, и он хорошо работает.
Я также хотел способность перезагрузить тот же класс, когда обновленная версия банки доступна. Я снова нашел некоторые образцы и ключ к достижению этого, как я понимаю, то, что я должен использовать новый classloader экземпляр для каждой новой загрузки.
Я написал некоторый код кода, но поразил 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 в банку, названную test.jar и местом это под C:\plugins and run this code. Первое повторение работает гладко и загрузки класса без проблем.
Когда программа выполняет оператор сна, я заменяю C:\plugins\test.jar новой банкой, содержащей обновленную версию того же класса, и ожидаю следующего повторения в то время как. Теперь вот то, что я не понимаю. Иногда обновленный класс перезагружается без проблем, т.е. следующее повторение хорошо работает. Но иногда, я вижу выданное исключение:
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)
Я искал в сети и поцарапал голову, но не могу действительно прийти ни к какому выводу относительно того, почему это исключение выдается и что также - только иногда, не всегда.
Мне нужны Ваш опыт и экспертные знания для понимания этого. Что случилось с этим кодом? Помогите!!
Сообщите мне, нужна ли Вам больше информация. Спасибо за взгляд!