この質問は、私が数週間前に投稿した別のものです: 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が発生します。
私は「@PostConstruct」で働いていたすべてのJBOSSコミュニティEE6とEE7エディションで、完璧に動作し、より安定したEAPバージョンが必要です。最終的に特定のSLSBの "@PostConstruct"中に発生したランタイム例外をログから検索します。 – garfield
ありがとう、しかし、私はこれが原因であるとは思わない。 @PostConstructメソッドの最初の行にSystem.out.printlnステートメントを追加しました。ステートレス(メソッド呼び出しがないことを示す)のときにserver.logには表示されず、ステートフルになったときに表示されます。いずれの場合も実行時の例外は発生しません。 –
特定のSLSBのコードを投稿する必要があります。 – garfield