1. ホーム
  2. java

[解決済み] javaでクラスをアンロードする?

2022-04-15 01:27:18

質問

私はカスタムクラスローダーを持っていて、デスクトップアプリケーションが、私が話す必要のあるAppServerからクラスを動的にロードし始めることができるようにしています。これを行うために必要なjarの量は、(それらを出荷したい場合)ばかげているので、我々はこれを行いました。また、実行時にAppServerライブラリからクラスを動的にロードしない場合、バージョンの問題が発生します。

今、2つの異なるAppServersと話す必要がある問題にぶつかり、どちらのクラスを最初にロードするかによって、ひどく破損する可能性があることがわかりました...。実際にJVMを殺すことなく、クラスのアンロードを強制する方法はありますか?

これが意味をなすことを願う

解決方法は?

クラスがアンロードされる唯一の方法は、使用されたクラスローダーがガベージコレクションされる場合です。 つまり、すべてのクラスとクラスローダー自体への参照は、ドードーの道を行く必要があります。

あなたの問題に対する1つの可能な解決策は、すべてのjarファイルに対してクラスローダーを持ち、実際のクラスのロードを特定のjarクラスローダーに委ねるAppServersのそれぞれに対してクラスローダーを持つことです。 そうすれば、アプリサーバーごとに異なるバージョンのjarファイルを指定することができます。

しかし、これは些細なことではありません。 OSGiプラットフォームは、各バンドルが異なるクラスローダーを持ち、依存関係がプラットフォームによって解決されるため、まさにこれを実現しようと努力しています。 多分、良い解決策は、それを見てみることでしょう。

OSGIを使いたくない場合、一つの可能な実装として、1つのインスタンスで JarClassloader クラスは、すべての JAR ファイルに適用されます。

そして、クラスローダーを継承した新しいマルチクラスローダークラスを作成します。 このクラスは内部的に JarClassloader の配列(またはリスト)を持ち、defineClass() メソッドでは定義が見つかるか NoClassDefFoundException がスローされるまで内部のすべてのクラスローダーを繰り返し処理します。 新しい JarClassloaders をクラスに追加するために、いくつかのアクセッサ・メソッドを提供することができます。MultiClassLoader の実装はネット上にいくつか存在するので、自分で書く必要はないかもしれません。

サーバーへの接続ごとに MultiClassloader をインスタンス化すると、原理的には、サーバーごとに同じクラスの異なるバージョンを使用することが可能です。

ユーザー定義のスクリプトを含むクラスをメモリからロードおよびアンロードする必要があるプロジェクトで、MultiClassloaderのアイデアを使用したことがありますが、非常にうまく機能しました。