アプリケーションの特定の部分について、既存のアプリケーションにプラグイン機能を追加する必要があります。実行時に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 を 1 つだけ持つ単純なインターフェイスです。
public interface IPlugin {
void doProc();
}
jartest.TestPlugin は、doProc がいくつかのステートメントを出力するだけのこのインターフェースの実装です。
ここで、jartest.TestPlugin クラスを test.jar という名前の jar にパッケージ化し、C:\plugins の下に配置して、このコードを実行します。最初の反復はスムーズに実行され、クラスは問題なくロードされます。
プログラムがスリープ ステートメントを実行しているときに、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)
私はネットで検索して頭をかきましたが、なぜこの例外がスローされるのか、そしてそれについても結論を出すことはできません-常にではなく、時々だけです.
これを理解するには、あなたの経験と専門知識が必要です。このコードの何が問題になっていますか? 助けてください!!
さらに情報が必要な場合はお知らせください。ご覧いただきありがとうございます。