1. ホーム
  2. java

実行時にjarファイルを読み込む方法 [重複]について

2023-09-24 22:03:59

質問

実行中に新しいコード(拡張)をロードする機能を持つjavaシステムを構築するよう依頼されました。 コードが実行されている間に jar ファイルを再ロードするにはどうすればよいですか? または、新しい jar をロードするにはどうすればよいですか?

明らかに、一定のアップタイムが重要であるため、(物事をあまり複雑にしないのであれば)既存のクラスを実行中に再ロードする能力を追加したいと思います。

私が気をつけるべきことは何でしょうか? (実行時にクラスを再ロードすることに関する質問と、新しいクラスを追加することに関する質問という、2つの異なる質問だと考えてください)。

どのように解決するのですか?

既存のクラスを既存のデータで再読み込みすると、事態が悪化する可能性が高いです。

新しいクラスローダーに新しいコードを比較的容易にロードすることができます。

ClassLoader loader = URLClassLoader.newInstance(
    new URL[] { yourURL },
    getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class);
// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();
doRun.run();

使われなくなったクラスローダーはガベージコレクションされます(ThreadLocalやJDBCドライバの使用でよくあるような、メモリリークがない限り)。 java.beans など)。

オブジェクトのデータを保持したいのであれば、Serialisationなどの永続化メカニズムや、あなたが慣れ親しんでいるものをお勧めします。

もちろん、デバッグシステムはより派手なことができますが、よりハチャメチャで信頼性が低いです。

クラスローダーに新しいクラスを追加することは可能です。例えば URLClassLoader.addURL . しかし、もしクラスがロードに失敗したら(例えば、あなたがそれを追加していないから)、そのクラスはそのクラスローダーのインスタンスでロードされることは決してありません。