1

この質問は、私が数週間前に投稿した別のものです: log4j2 logging of code in EJB jar on JBoss EAP 7。その記事では、JBoss EAP 7サーバーにEJB JAR(EARではなく)としてデプロイされ、別のサーブレットから呼び出されたEJBで初期化をログに記録する問題がありました。これらのEJBは、ローカルインタフェースを介して呼び出されます。@PostConstructはステートフルEJB呼び出しで呼び出されましたが、ステートレスではありません。なぜですか?

私がこのリンクで提示した解決策は、最初のEJB、つまりステートフルEJBでうまく動作しました。 @ PostConstructアノテーション付きメソッドが呼び出され、ロギングコンテキストが初期化され、すべてがうまく動作します。

私が試した2番目のEJBでソリューションが失敗しました。このEJBはステートレスでした。 @PostConstructメソッドが呼び出されることはなく、ロガーがnullであるため、ロギングの最初の試みは問題を引き起こします。私が2つの豆の間で見ることができる唯一の違いは、第2のものがステートレスであったのに対して、第1のものはステートフルであったことであった。実験として、私は第2のものをステートフルにしました。私がそれをしたら、@ PostConstructが呼び出され、ログが初期化され、基本的にすべてうまくいった。

Oracle JavaEE6 tutorialによれば、@PostConstructメソッドは、ステートレスBeanのインスタンス化で呼び出されることになっています。だから、なぜステートフルセッションBeanのインスタンス化は@PostConstructを呼びますが、ステートレスセッションBeanのインスタンス化は行われません。どうすればよいでしょうか?

ありがとうございました。

更新:ソースコードの追加

EJB-jar.xmlの

<?xml version="1.0" encoding="UTF-8"?> 
<ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     version="3.2" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd"> 
    <module-name>DealerLocatorBean</module-name> 
    <enterprise-beans> 
     <session> 
      <ejb-name>DealerLocatorBean</ejb-name> 
      <home>com.whatever.ServiceLogicHome</home> 
      <remote>com.whatever.ServiceLogic</remote> 
      <local-home>com.whatever.ServiceLogicLocalHome</local-home> 
      <local>com.whatever.ServiceLogicLocal</local> 
      <ejb-class>com.whatever.ejbs.DealerLocatorBean</ejb-class> 
      <session-type>Stateless</session-type> 
      <!-- <session-type>Stateful</session-type> No problem if this is made stateful--> 
      <transaction-type>Bean</transaction-type> 
     </session> 
    </enterprise-beans> 
</ejb-jar> 

DealerLocatorBean.java:

public class DealerLocatorBean implements SessionBean 
{ 

    private static final String LOGGER_CONFIG = "/path/to/log4j2.xml"; 
    private static final String LOGGER_CONTEXT_NAME = "VTDLLOC-EJB"; 
    private static LoggerContext logctx; 
    private static Logger logger = null; 

    public DealerLocatorBean() { 
     System.out.println("calling DealerLocatorBean() constructor"); 
    } 
    @PostConstruct 
    @TransactionAttribute(value=TransactionAttributeType.NOT_SUPPORTED) 
    private void postConstruct() { 
     System.out.println("DealerLocatorBean.postConstruct()"); 
     logctx = Configurator.initialize(LOGGER_CONTEXT_NAME, LOGGER_CONFIG); 
     logger = logctx.getLogger(getClass().getName()); 
     logger.log(Level.INFO, ("postConstruct() in DealerLocatorBean called")); 
     logger.log(Level.INFO, ("******END OF THE postConstruct() CALL******")); 
    } 

    @PreDestroy 
    @TransactionAttribute(value=TransactionAttributeType.NOT_SUPPORTED) 
    private void preDestroy() { 
     logger.log(Level.INFO, ("preDestroy() in DealerLocatorBean called. Shutting down logging.")); 
     Configurator.shutdown(logctx); 
    } 

Beanは(EJB-jar.xmlの)ステートフルとして展開されている場合は、@PostConstructデプロイ後に初めてBeanが使用され、すべてが動作します。 DealerLocatorBean.postConstruct()が出力に表示され、すべての下位ログが機能します。

Beanがステートレス(ejb-jar.xml)としてデプロイされている場合、@ postConstructは決して呼び出されません。 DealerLocatorBean.postConstruct()は出力には表示されません。ロギングは初期化されず、コードがロガーを介して何かをログに記録しようとするとすぐにNullPointerExceptionsが発生します。

+0

私は「@PostConstruct」で働いていたすべてのJBOSSコミュニティEE6とEE7エディションで、完璧に動作し、より安定したEAPバージョンが必要です。最終的に特定のSLSBの "@PostConstruct"中に発生したランタイム例外をログから検索します。 – garfield

+0

ありがとう、しかし、私はこれが原因であるとは思わない。 @PostConstructメソッドの最初の行にSystem.out.printlnステートメントを追加しました。ステートレス(メソッド呼び出しがないことを示す)のときにserver.logには表示されず、ステートフルになったときに表示されます。いずれの場合も実行時の例外は発生しません。 –

+0

特定のSLSBのコードを投稿する必要があります。 – garfield

答えて

0

このBeanはデプロイ時にログに記録されていますか?また、最終的な統計はSLSBでは許可されていません。プライベート静的LoggerContext logctxを変更することをお勧めします。プライベート静的最終LoggerContextにlogctx = Configurator.initialize(LOGGER_CONTEXT_NAME、LOGGER_CONFIG);可能な場合はloggerと同じものを使用し、対応する文を@PostConstructから削除するか、logctxとloggerの宣言でstaticキーワードを削除してください。

関連する問題