JTAユーザートランザクションのJNDI検索は、WebSphereアプリケーションサーバー7のMBEANスレッドでは利用できません

StackOverflow https://stackoverflow.com/questions/8343533

  •  27-10-2019
  •  | 
  •  

質問

JTAをオンにしてWebSphere Application Server 7のWebアプリケーションでJMX( 'Standard' MBEANを使用)を介してビジネスロジックを呼び出しようとしています。 Mbean(WebアプリのUIを介して呼び出されたときにできるから)。

Hibernateが「Java:comp/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が正しいユーザートランザクションJNDIの場所( 'java:comp/usertransaction')であると言うユーザートランザクションを探しています - 参照 このインフォセンタードキュメント.

さらに、ルックアップを行う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

「カスタムMBEANSを使用してWebSphereアプリケーションサーバー管理システムを拡張する」ドキュメント IBMのInfocenterでは、外部のアプリケーションでテストされた標準的なMBEANが機能するはずであることを示唆しています。

IBMは、ユーザートランザクションルックアップが利用できないと述べています。

  • cmt Enterprise Beans `http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.doc/info/aes/aes/ae/cjta_glotran.html

  • ejbs `http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/com/ibm/websphere/asynchbeans/package-package- summary.html?result of =%22%61%73%79%6e%63%68%62%65%61%6E%22%20%22%75%73%65%72%74%72%61%6e 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つの作業リンクしか投稿できません。

プレーンな古いMBeansは、IBMの観点からこれらのカテゴリのいずれかに分類されますか?

興味深いことに、ユーザートランザクションはJNDIルックアップ「JTA/ユーザートランザクション」で利用可能であるように見え、それをフォールバックオプションとして使用することは機能しているようです - しかし:

  • 7はJava EE 5に準拠しており、J2EE 1.3 'Java:comp/userTransaction'はユーザー翻訳の指定されたJNDIロケーションです - J2EE 1.3 Spec `http://java.sun.com/j2ee/j2ee-1_3-を参照してくださいfr-spec.pdf

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

さらに注意すべき点は、ユーザートランザクションがMBEANからアプリケーションのワークマネージャー(IBMワークマネージャー)に提出された作業のスレッドにも隠されていることです。

私に起こった可能性のある説明は次のとおりです。

  • IBMがMbeanスレッドをどのように設定しているかについての問題は7でした。MBEANを登録するアプリケーションに関連しています。

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

    • UserCollaboratorsおよびXML記述子にMBEANを登録します

    • ModelMbeanInfoに登録します

    • Mbeanserverではなく、Adminserviceに登録します

    • 登録時に追加のプロパティ(アプリケーション、j2eeapplication)を使用して、Mbeanのオブジェクト名を強化する

  • JMXクライアントリクエストには、MBEANの呼び出しを適切なアプリケーションに関連付ける必要があることを知らせる追加の構成オプションがある場合があります。このフォーラムの投稿は、クライアントアプリケーションを構成することが可能であることを示唆しています。初期コンテキストにアクセスできるようになります: `http://www.ibm.com/developerworks/forums/thread.jspa?messageid=14021995

  • IBMの声明にもかかわらず、このようにMBEANを使用しようとすることは想定されていないかもしれません。 EJBSがこの種の要件の適切な解決策であることが示唆されています。

この問題に当てはまることができる光は大歓迎です。

役に立ちましたか?

解決

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

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

IBMの声明にもかかわらず、このようにMBEANを使用しようとすることは想定されていないかもしれません。 EJBSがこの種の要件の適切な解決策であることが示唆されています。

MBEANは、この種の作業に適していない場合があります。むしろ、EJBSまたはWebサービスを使用する方が適切かもしれません。

他のヒント

設定する必要があります TransactionManagementType.BEAN SOのようなトランザクションマネージメントについて:

@TransactionManagement(TransactionManagementType.BEAN) 
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top