1

だからここに私の問題があります:

DocuShare サーバーで特定のイベントが発生したときに呼び出されるコードがあります。私は自分のイベントリスナーでイベントをリッスンします。これまでのところ、これは問題なく動作します。

このリスナーは、個別に開発され、独自の jar ファイルに存在する他のコードを呼び出します。

現在、これらの jar の 1 つの新しいバージョンを使用できるようにするには、常にシステム全体をシャットダウンしなければならないというオーバーヘッドがあります。

そのため、そのjarファイル(クラスパス上ではなく)を別の一時的な場所(したがってjarlockなし)にコピーし、jarファイルを独自の異なるクラスローダーにロードして実行するシステムを作成しようとしています。このようにして、新しいバージョンが開発されたときに元の jarfile を簡単に上書きできます。その後、コードは jarfile に変更があったかどうかを確認し、変更があった場合は同じ手順を実行します。

私はこれをより単純なセットアップ (サーブレットが呼び出されている) で成功させたので、jar の「ホットデプロイ」のアプローチが機能することを知っています。

ただし、この場合、別のクラスローダーの使用を開始するまで、コードは正常に機能します。jarfile を見つけて違いを確認し、それに応じて jarfile をロードできますが、クラスにアクセスしようとすると、System.out または System.err に出力が得られなくなります。jar 内のコードが正しく実行されていませんが、その理由がわかりません。

追加情報: コードは独自のスレッドで実行されています

何が起こっているかの概要:

  1. DocuShare がイベントを送信する
  2. リスナーがイベントをピックアップ
  3. リスナー (java.util.concurrent.Executor を実装) が新しいスレッド (Runnable impl) を開始します
  4. Runnable impl は新しいクラスローダーを作成し、フォルダー内に新しいバージョンの jar ファイルがあるかどうかを確認します。ある場合は別のディレクトリにコピーし、そうでない場合は既存のバージョンを使用し、新しいバージョンのクラスパスにロードします。クラスローダーを実行して実行する
  5. 新しい ClassLoader を使用してクラスをロードした瞬間から、System.out/System.err に行が表示されません。

コード例 (Runnable.run() メソッド内):

URLClassLoader hotCL = new URLClassLoader(((URLClassLoader) systemCL).getURLs()); //new URLclassloader with URLs from system CL

//the following approach for putting the class on the classpath comes from another SO question from somebody else
Method m = cl.getClass().getDeclaredMethod("addURL", new Class[]{URL.class});
m.setAccessible(true);
m.invoke(cl, jar.toURI().toURL());
String cp = System.getProperty("java.class.path");
if (cp != null) {
    cp += File.pathSeparatorChar + jar.getCanonicalPath();
} else {
    cp = jar.toURI().getPath();
}

Logger.log(">>>>>>>> instantiating impl");  //this is printed in the System.out
Class<?> clsService = hotCL.loadClass(strService);  //strService is the class inside the separate jar
Object instance = clsService.newInstance();

Logger.log(">>>>>>>>>>>> class: " + clsService.getClass().toString()); //this is not printed in the System.out, neither is any log-statement after this or any error
//after this a method of the class instance is called but the code doesn't do anything.  Possibly an error but there's no error/stacktrace

ClassLoaders について欠けているものはありますか? エラーやコードが実行されていない理由がわかりません。

4

1 に答える 1

1

動的クラスから参照されている JDK クラスをロードしようとすると、クラスローダーがハングする可能性があります。これは、JDK クラスをロードできる親クラスローダーが必要なためです。現在のコンテキストから機能的な親を借用できます。つまり、次のようになります。

new URLClassLoader(urls, this.getClass().getClassLoader())

既にインスタンス化されたクラスをリロードした後に問題が発生した場合は、このスレッドを確認してください。

于 2013-06-23T05:19:30.747 に答える