2

JTA がオンになっている Websphere Application Server 7 の Web アプリケーションで JMX (「標準」MBean を使用) 経由でビジネス ロジックを呼び出そうとしています。 MBean (Web アプリの UI を介して呼び出すことができるため)。

hibernate が「java:comp/UserTransaction」を介して UserTransaction を検索しようとすると、次の例外がスローされます。

org.hibernate.TransactionException: Could not find UserTransaction in JNDI [java:comp/UserTransaction]
    at org.hibernate.transaction.JTATransactionFactory.getUserTransaction(JTATransactionFactory.java:173)
    at org.hibernate.transaction.JTATransactionFactory.createTransaction(JTATransactionFactory.java:149)

    ...

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    at java.lang.reflect.Method.invoke(Method.java:600)
    at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:105)
    at com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:39)
    at com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:220)
    at com.sun.jmx.mbeanserver.PerInterface.getAttribute(PerInterface.java:77)
    at com.sun.jmx.mbeanserver.MBeanSupport.getAttribute(MBeanSupport.java:228)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:678)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:650)
    at com.ibm.ws.management.AdminServiceImpl.getAttribute(AdminServiceImpl.java:853)
    at com.ibm.ws.management.remote.AdminServiceForwarder.getAttribute(AdminServiceForwarder.java:270)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1415)
    at javax.management.remote.rmi.RMIConnectionImpl.access$200(RMIConnectionImpl.java:84)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1276)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1371)
    at javax.management.remote.rmi.RMIConnectionImpl.getAttribute(RMIConnectionImpl.java:612)
    at javax.management.remote.rmi._RMIConnectionImpl_Tie.getAttribute(_RMIConnectionImpl_Tie.java:578)
    at javax.management.remote.rmi._RMIConnectionImpl_Tie._invoke(_RMIConnectionImpl_Tie.java:98)
    at com.ibm.CORBA.iiop.ServerDelegate.dispatchInvokeHandler(ServerDelegate.java:622)
    at com.ibm.CORBA.iiop.ServerDelegate.dispatch(ServerDelegate.java:475)
    at com.ibm.rmi.iiop.ORB.process(ORB.java:513)
    at com.ibm.CORBA.iiop.ORB.process(ORB.java:1574)
    at com.ibm.rmi.iiop.Connection.respondTo(Connection.java:2841)
    at com.ibm.rmi.iiop.Connection.doWork(Connection.java:2714)
    at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:63)
    at com.ibm.ejs.oa.pool.PooledThread.run(ThreadPool.java:118)
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1563)
Caused by: javax.naming.ConfigurationException: A JNDI operation on a "java:" name cannot be completed because the server runtime is not able to associate the operation's thread with any J2EE application component.  This condition can occur when the JNDI client using the "java:" name is not executed on the thread of a server application request.  Make sure that a J2EE application does not execute JNDI operations on "java:" names within static code blocks or in threads created by that J2EE application.  Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on "java:" names. [Root exception is javax.naming.NameNotFoundException: Name "comp/UserTransaction" not found in context "java:".]
    at com.ibm.ws.naming.java.javaURLContextImpl.throwConfigurationExceptionWithDefaultJavaNS(javaURLContextImpl.java:428)
    at com.ibm.ws.naming.java.javaURLContextImpl.lookup(javaURLContextImpl.java:399)
    at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:214)
    at com.ibm.ws.naming.java.javaURLContextRoot.lookup(javaURLContextRoot.java:154)
    at javax.naming.InitialContext.lookup(InitialContext.java:455)
    at org.hibernate.transaction.JTATransactionFactory.getUserTransaction(JTATransactionFactory.java:163)
    ... 53 more
Caused by: javax.naming.NameNotFoundException: Name "comp/UserTransaction" not found in context "java:".
    at com.ibm.ws.naming.ipbase.NameSpace.lookupInternal(NameSpace.java:1178)
    at com.ibm.ws.naming.ipbase.NameSpace.lookup(NameSpace.java:1095)
    at com.ibm.ws.naming.urlbase.UrlContextImpl.lookup(UrlContextImpl.java:1233)
    at com.ibm.ws.naming.java.javaURLContextImpl.lookup(javaURLContextImpl.java:395)
    ... 57 more

この問題は単なる休止状態の構成の問題ではないようです。休止状態は、IBM が正しい UserTransaction JNDI の場所 ('java:comp/UserTransaction') であると言っている場所で UserTransaction を探しています。この infocenter ドキュメントを参照してください。

さらに、ルックアップを行う MBean を持つ単純な Web アプリで問題を再現できます。

public class JTALookup extends NotificationBroadcasterSupport implements JTALookupMBean {
  Log log = LogFactory.getLog(JTALookup.class);

  /**
   * {@inheritDoc}
   * @see JTALookupMBean#lookupUserTransaction()
   */
  @Override
  public void lookupUserTransaction() {
    try {
      log.info("Attempting 'java:comp/UserTransaction' lookup");
      Object usrTxn = new InitialContext().lookup("java:comp/UserTransaction");
      log.info("Successfully looked up 'java:comp/UserTransaction' [" + usrTxn + "]." );
    } catch (NamingException e) {
      log.info("'java:comp/UserTransaction' lookup failed");
      throw new RuntimeException("Failed to lookup JTA user transaction", e);
    }
  }

起動時にルックアップを呼び出してから MBean を登録するコンテキスト リスナー:

public void contextInitialized(ServletContextEvent sce) {

    log.info("Initialising context");

    JTALookup jtaLookup = new JTALookup();
    jtaLookup.lookupUserTransaction(); // This succeeds
    log.info("Looked up JTA transaction");

    MBeanServer mbServer = AdminServiceFactory.getMBeanFactory().getMBeanServer();
    log.info("Got MBeanServer");

    try {
      mbServer.registerMBean(jtaLookup, new ObjectName("webJTALookupStub:type=JTALookup"));
      log.info("Registered dummy MBean");
    } catch (Exception e) {
      log.info("Failed to register dummy MBean");
      throw new RuntimeException("Failed to register dummy MBean", e);
    }
}

'java:comp/UserTransaction' のルックアップは、コンテキストの初期化中に成功しますが、次のように、jmx 経由で呼び出されると (上記と同様のスタック トレースで) 失敗します。

public static void main(String[] args) {

    JMXServiceURL url = new JMXServiceURL(
        "service:jmx:rmi://" + "your.server.name.co.uk" + ":" + "2809" + "/jndi/JMXConnector"
    );

    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env.put(Context.PROVIDER_URL, "corbaloc:iiop:gbbldd66.sys.chp.co.uk:2809/WsnAdminNameService");
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");

    // Establish the JMX connection.
    JMXConnector jmxc = JMXConnectorFactory.connect(url, env);

    // Get the MBean server connection instance.
    MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

    ObjectName mbeanName = new ObjectName("webJTALookupStub:type=JTALookup");

    JTALookupMBean mBean = JMX.newMBeanProxy(mbsc, mbeanName, JTALookupMBean.class, true);

    mBean.lookupUserTransaction(); // This fails

IBMのインフォセンターにある「カスタム MBean を使用した WebSphere Application Server 管理システムの拡張」ドキュメントは、WAS 以外のアプリケーションでテストされた標準 MBean が問題なく機能することを示唆しています。

IBM は、UserTransaction ルックアップは以下では利用できないと述べています。

  • CMT エンタープライズ Bean `http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.base.doc/info/aes/ae/cjta_glotran.html

  • EJB によって作成された非同期 Bean `http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/com/ibm/websphere/asynchbeans/package- summary.html?resultof=%22%61%73%79%6e%63%68%62%65%61%6e%22%20%22%75%73%65%72%74%72%61%6e %73%61%63%74%69%6f%6e%22%20%22%75%73%65%72%74%72%61%6e%73%61%63%74%22%20

機能しないリンクについてお詫び申し上げます - 私は新しいユーザーなので、2 つの有効なリンクしか投稿できません。

IBM の観点からすると、単純な古い MBean はこれらのカテゴリのいずれかに分類されますか?

興味深いことに、UserTransaction は JNDI ルックアップ 'jta/UserTransaction' で利用できるように見え、それをフォールバック オプションとして使用するとうまくいくようですが、次のようになります。

  • WAS 7 は Java EE 5 に準拠しており、J2EE 1.3 では「java:comp/UserTransaction」が UserTransaction 用に指定された JNDI の場所です。J2EE 1.3 仕様「http://java.sun.com/j2ee/j2ee-1_3-」を参照してください。 fr-spec.pdf

  • 以前のバージョンの EE 仕様からルックアップを使用することは、他のバグの潜在的な原因のように思われ、私の問題の一部に対処しているだけかもしれません.WAS が私の MBean のスレッドがアプリケーションに関連付けられていないと考えるという事実は、他の問題を引き起こす可能性があります.

もう 1 つの注意点は、MBean からアプリケーションのワーク マネージャー (IBM ワーク マネージャー) に送信された作業のスレッドに対しても UserTransaction が隠されていることです。

私が思いついた考えられる説明は次のとおりです。

  • IBM が WAS 7 で MBean スレッドをセットアップし、MBean を登録するアプリケーションに関連付ける方法に問題がある可能性があります。

  • MBean を登録したアプリケーションに MBean を関連付ける必要があることを WAS に知らせる、MBean 登録用の追加の構成オプションがいくつかある場合があります。いくつかの代替アプローチを試しましたが、毎回同じ例外が見られました。

    • UserCollaborators および xml 記述子を使用した MBean の登録

    • ModelMBeanInfo への登録

    • それらを MBeanServer ではなく AdminService に登録する

    • 登録時の追加プロパティー (Application、J2EEApplication) による MBean の ObjectName の拡張

  • MBean 呼び出しを適切なアプリケーションに関連付ける必要があることを WAS に知らせる、jmx クライアント要求用の追加の構成オプションがいくつかある場合があります。このフォーラムの投稿では、初期コンテキストにアクセスできるようにクライアント アプリケーションを構成できることが示唆されています。

  • 私は MBean をこのように使おうとするべきではないかもしれません。この種の要件には、EJB が適切なソリューションであることが示唆されています。

この問題に光を当てていただければ幸いです。

4

2 に答える 2

2

MBean はアプリケーションとは別のスレッドで実行されるため、JNDI のアプリケーション ネーミング コンテキストにアクセスできないため、UserTransaction にアクセスできません。

あなたの最終的な潜在的な説明がおそらく最も正確だと思います:

私がこのように MBean を使用しようとすることは想定されていないかもしれません - IBM の声明にもかかわらず、私はできるはずです。この種の要件には、EJB が適切なソリューションであることが示唆されています。

MBean は、この種の作業には適していない場合があります。むしろ、EJB または Web サービスを使用する方が適切な場合があります。

于 2011-12-01T15:44:32.607 に答える
0

TransactionManagementType.BEAN次のように transactionManagementを設定する必要があります。

@TransactionManagement(TransactionManagementType.BEAN) 
于 2014-06-30T16:27:13.840 に答える