9

CDI オブザーバー メソッドを持つシングルトン EJB (javax.ejb.Singleton バージョン。ため息) があります。これを Glassfish 3.1 にデプロイしようとすると、サーバーは実際の説明なしに EAR ファイルのデプロイに失敗します。デプロイ中に例外があったとだけ言って、詳細はありません。

SEVERE: Exception while loading the app
SEVERE: Exception while shutting down application container
....
SEVERE: Exception while shutting down application container : java.lang.NullPointerException

これは CDI イベント リスナーです。

public void updateFromGranule(@Observes @CloudMask GranuleAvailableEvent granuleEvent) {
    LOG.info("updating cloud map");
    update(granuleEvent.getGranule(), CloudMask.class);
    fireUpdate();
}

Singleton Bean を @ApplicationScoped Bean に変更すると、アプリは正常にデプロイされます。同様に、CDI イベント オブザーバー メソッドを削除すると、アプリケーションは正常にデプロイされます。EJBのトランザクション、スレッドセーフなどが必要なため、実際にはクラスをEJBシングルトンにする必要があるため、これを@ApplicationScoped POJOのままにしておくだけではあまり役に立ちません。ただし、問題は Singleton Bean に限定されているようには見えません。アノテーションを @Stateless および @Stateful に変更して実験したところ、同じ問題が発生しました。

これは Weld のバグであると思われます。おそらく、Weld と EJB はそのメソッドをプロキシする方法について争っています。おそらく、EJB はインターセプタ クラスを追加し、そのメソッドをラップしてスレッドの安全性を確保する必要があり、Weld は何かをしようとしています。他にイベントリスナーを機能させるには?

ここで何か誤解しているのでしょうか?EJB で CDI イベント ハンドラーを使用しないでください (その場合、glassfish からのエラー メッセージが改善されます)。それとも、これは実際には CDI または EJB 実装の単なるバグですか?

4

2 に答える 2

9

これが答えだと思います:

EJB がローカル インターフェースを宣言している場合、CDI オブザーバー メソッドは明らかに静的であるか、EJB のローカル インターフェースで宣言されている必要があります。通常、ローカル インターフェイスにないオブザーバー メソッドを宣言しようとすると、次のように Weld から例外が発生します。

org.jboss.weld.exceptions.DefinitionException: WELD-000088 Observer method must be static or local business method:  [method] public org.stain.ObserverBean.testMethod(EventClass) on public@Singleton class org.stain.ObserverBean

なんらかの理由で、EAR ファイルをロードするときに、glassfish がこの例外を適切に報告せず、単純にException while loading the app.

メソッドをローカル インターフェイスに追加する (またはクラスのインターフェイス宣言を削除する) と、問題が修正され、アプリケーションが正常に読み込まれるようになります。

于 2011-05-15T21:07:44.510 に答える
5

最新バージョンの溶接で同じ問題に気付きました。ただし、@LocalBean アノテーションを追加すると、@Singleton および @Singleton @Startup で機能します。

于 2011-06-28T15:04:52.317 に答える