Der JNDI-lookup für die JTA-UserTransaction ist nicht verfügbar, um die MBean-threads, die in Websphere Application Server 7

Ich versuche zu aufrufen der Geschäftslogik via JMX (mit "standard" - MBeans) in eine web-Anwendung in Websphere Application Server 7 mit JTA eingeschaltet und würde gerne wissen, warum das business-Logik kann nicht sehen, die JTA-UserTransaction, wenn Sie angerufen werden von einem MBean (denn es kann beim Aufruf über das web-app-UI).

Wenn hibernate versucht, sich die UserTransaction über "java:comp/UserTransaction", die folgende Ausnahme ausgelöst:

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

Diesem problem wie es aussieht ist mehr als nur ein hibernate-problem mit der Konfiguration - hibernate ist auf der Suche nach der UserTransaction, was IBM sagen, ist die richtige UserTransaction JNDI-Speicherort ("java:comp/UserTransaction") - das sehen das infocenter-Dokument.

Weiterhin kann ich das problem reproduzieren in einer einfachen web-app, die eine MBean, die die lookup:

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);
    }
  }

- und eine Kontext-listener ruft die lookup während der start-und registriert dann die 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);
    }
}

Den lookup "java:comp/UserTransaction' gelingt es, während der Kontext der Initialisierung, aber nicht (mit einem ähnlichen stack-trace zu dem oben) wenn Sie angerufen werden, über jmx, etwa so:

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

Den "Ausweitung der WebSphere Application Server administrative system mit custom MBeans' document in IBMs infocenter deutet darauf hin, dass standard-MBeans, die getestet wurden, in Anwendungen außerhalb WAR, sollte nur funktionieren.

IBM Stand, dass die UserTransaction-Suche nicht zur Verfügung:

  • CMT Enterprise-beans`http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.base.doc/info/aes/ae/cjta_glotran.html
  • Async-Bohnen erstellt von EJBs`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

Entschuldige mich für die nicht-funktionalen links - ich bin ein neuer user und kann deshalb nur post zwei links arbeitet.

Tun plain old MBeans fallen in eine dieser Kategorien aus IBM-Sicht?

Interessant, die UserTransaction erscheint auf JNDI-lookup 'jta/UserTransaction" und mit, dass als fallback-option scheint zu funktionieren - aber:

  • WAR 7 ist Java EE 5-kompatibler und als J2EE 1.3 java:comp/UserTransaction " ist der angegebene JNDI-Speicherort für die UserTransaction - siehe die J2EE 1.3 Spezifikation `http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf
  • Mittels einer lookup aus einer früheren version des EE-Spezifikation scheint wie eine potenzielle Quelle für weitere Fehler, und möglicherweise nur auf einen Teil meines Problems - die Tatsache, dass WAR der Meinung, mein MBean-thread ist nicht mit einem Programm verbunden ist, könnte dazu führen, andere Probleme.

Einen weiteren Punkt zu beachten ist, dass die UserTransaction auch versteckte threads für Arbeit eingereicht, die von der MBean der Anwendung work manager (eine Arbeit bei IBM-manager), und das könnte sein, weil es die Behandlung, die wie es ist eine asynchrone bean verfasst von EJB?

Mögliche Erklärungen, die mir eingefallen sind:

  • Könnte es Probleme mit wie IBM einrichten MBean-threads in WAR 7, und ordnen Sie dann mit den Anwendungen, die register der MBeans.
  • Möglicherweise gibt es einige zusätzliche Konfigurationsoptionen für die MBean-Registrierung hat, dass wusste, WAR, dass es sollte ordnen Sie die MBean mit der Anwendung, die es registriert. Ich habe versucht mehrere alternative Ansätze, sah aber die gleiche Ausnahme jedes mal:
    • Registrierung der MBeans mit UserCollaborators und xml-Deskriptoren
    • Registrierung mit ModelMBeanInfo
    • Registrierung mit der AdminService anstatt den MBeanServer
    • Verbesserung der Objektname für die MBean mit zusätzlichen Eigenschaften, (Anwendung, J2EEApplication) bei der Anmeldung
  • Möglicherweise gibt es einige zusätzliche Konfigurationsoptionen für die jmx-client-Anfrage, dass wusste, WAR, dass es sollte ordnen Sie die MBean Aufruf mit der entsprechenden Anwendung. Dieser forum post schon andeutet, ist möglich, konfigurieren Sie eine client-Anwendung, die Zugriff auf den ursprünglichen Kontext: `http://www.ibm.com/developerworks/forums/thread.jspa?messageID=14021995
  • Ich es vielleicht einfach nicht sein soll, zu versuchen, zu verwenden, MBeans auf diese Weise - trotz IBM-Aussagen, dass ich sollte in der Lage sein. Es ist vorgeschlagen worden, dass EJBs sind die geeignete Lösung für diese Art von Anforderung.

Kein Licht, kann Schuppen auf dieses problem würde sehr geschätzt werden.

InformationsquelleAutor Joseph MacFarlane | 2011-12-01

Schreibe einen Kommentar