1

私はこの状況を持っています:

  • JBOSS インスタンス
  • アプリケーション client.war
  • アプリケーション server.war
  • インターフェイスのみを含む、適切にインストールされた jboss モジュール。

server.war アプリケーションは jboss モジュール インターフェイスを実装し、これらの実装を JNDI バインドで公開します。ルックアップを伴う client.war アプリケーションは、server.war の実装を使用します。

ランタイム client.war は、server.war によって公開された実装を呼び出すことができますが、休止状態のトランザクションを開始しようとするとすぐに、次のエラーが発生します。

エラー [stderr] java.lang.IllegalStateException: JBAS016071: Service Module Loader からのモジュール "client.war:main" の ModuleClassLoader にシングルトンが設定されていません。これは、デプロイメントに関連付けられていない Thread Context ClassLoader を使用して、Weld デプロイメントにアクセスしようとしていることを意味します。

そこで何日も頭をぶつけましたが、何が問題なのか理解できません。誰かが私を助けることができますか?

4

1 に答える 1

2

子スレッドのクラス ローダーを親と同じになるように設定します。

親クラス ローダーを取得します。

ClassLoader cl = Thread.currentThread().getContextClassLoader();

子クラス ローダーを設定します。

ClassLoader cl = Thread.currentThread().setContextClassLoader(cl);

子スレッドが完了したら、クラス ローダーを null に設定解除して、スレッド プールの場合のリークを回避してください。

CDI は子スレッドで機能しますが、リモート EJB 呼び出しや JNDI ルックアップなどは機能しません。

はるかに優れたアプローチは、非同期 EJB 呼び出しを使用することです。次のような EJB を作成できます。

@Singleton
public class AsyncBean {
@Asynchronous
public void performTask(int a, int b) {
// the client doesn't care what happens here
}

これは、非同期タスクに TCCL が正しく設定され、JNDI が機能することを意味します (基本的には完全な EE 呼び出しです)。

非同期呼び出しに使用されるスレッド プールは、standalone.xml で構成できますが@Asynchronous、アプリケーション内のすべてのメソッドに使用されます。

根本的な原因

アプリケーションが独自のスレッドを起動すると、新しいスレッドは元のスレッドのクラスローダーとは異なるクラスローダーを使用するため、インジェクションは失敗します。

参照

https://access.redhat.com/solutions/257663

于 2016-08-09T10:39:25.820 に答える