La búsqueda de JNDI para la JTA UserTransaction no está disponible para MBean Threads en WebSphere Application Server 7

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

  •  27-10-2019
  •  | 
  •  

Pregunta

Estoy tratando de invocar la lógica comercial a través de JMX (usando 'MBeans estándar') en una aplicación web en WebSphere Application Server 7 con JTA encendido y me gustaría saber por qué esta lógica comercial no puede ver la JTA UserTransaction cuando se invoca desde un Mbean (porque puede cuando se invoca a través de la interfaz de usuario de la aplicación web).

Cuando Hibernate intenta buscar la transacción de usuario a través de 'java: comp/userTransaction', se lanza la siguiente excepción:

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

Parece que este problema es más que un solo problema de configuración de hibernado: Hibernate está buscando la transacción de usuario en lo que IBM dice que es la ubicación correcta de usertransaction JNDI ('java: comp/userTransaction') - ver Este documento de Infocenter.

Además, puedo reproducir el problema en una aplicación web simple que tiene un MBean que hace la búsqueda:

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

y un oyente de contexto que invoca la búsqueda durante el inicio y luego registra el 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);
    }
}

La búsqueda en 'java: comp/userTransaction' tiene éxito durante la inicialización del contexto, pero falla (con un rastro de pila similar a la anterior) cuando se invoca a través de JMX, como así:

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

los 'Extender el sistema administrativo del servidor de aplicaciones de WebSphere con documento de MBeans' En el Infocenter de IBM sugiere que los MBeans estándar que se han probado en aplicaciones externas deberían funcionar.

IBM dice que la búsqueda de INSERTRANSACTION no está disponible para:

  • Frijoles empresariales CMT `http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.base.doc/info/ae/cjta_glotran.html

  • Los granos asíncronos creados por EJBS `http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/com/ibm/websphere/asynchbeans/package- resumen.html? resultado de =%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 20

Disculpas por los enlaces no funcionales: soy un nuevo usuario y, por lo tanto, solo puedo publicar dos enlaces de trabajo.

¿Se dividen en cualquiera de estas categorías desde el punto de vista de IBM?

Curiosamente, el usuario de userTransaction parece estar disponible en la búsqueda de JNDI 'JTA/UserTransaction' y usarlo como una opción de respuesta parece funcionar, pero::

  • Was 7 anda Java Ee 5 que cumple con J2EE 1.3 'java: comp/userTransaction' es la ubicación JNDI especificada para el userTransaction- consulte la especificación J2EE 1.3 `http://java.sun.com/j2ee/j2ee-1_3-- FR-spec.pdf

  • El uso de una búsqueda de una versión anterior de la especificación EE parece una fuente potencial de otros errores, y podría estar abordando parte de mi problema: el hecho de que el hilo de mi MBean no está asociado con una aplicación podría causar otros problemas.

Otro punto a tener en cuenta es que la Transaction de User también está oculta a los subprocesos para el trabajo enviado desde el MBean al Gerente de Trabajo de la Aplicación (un Gerente de Trabajo de IBM), lo que podría ser porque está tratando ese trabajo como si fuera un Bean Async enviado por un EJB?

Las posibles explicaciones que me han ocurrido son:

  • Podría problemas con cómo IBM configuró MBean Threads en fue 7 y se asociaron con las solicitudes que registran los MBeans.

  • Puede haber algunas opciones de configuración adicionales para el registro de MBean que le haría saber que debería asociar al MBean con la aplicación que la registró. He probado varios enfoques alternativos, pero vi la misma excepción cada vez:

    • Registro de MBeans con Usercolaboradores y descriptores XML

    • Registrándolos con modelmbeaninfo

    • Registrándolos con el servicio de administración en lugar del mbeanserver

    • Mejorar el nombre de objeto para el MBean con propiedades adicionales (aplicación, J2EEApplication) en el registro

  • Puede haber algunas opciones de configuración adicionales para la solicitud del cliente JMX que lo haría saber que debería asociar la invocación de MBean con la aplicación apropiada. Esta publicación del foro sugiere que es posible configurar una aplicación cliente para tener acceso al contexto inicial: `http://www.ibm.com/developerworks/forums/thread.jspa?MessageId=14021995

  • Es posible que no se suponga que deba usar MBeans de esta manera, a pesar de las declaraciones de IBM que debería poder. Se ha sugerido que los EJB son la solución apropiada para este tipo de requisito.

Cualquier luz que se pueda arrojar sobre este problema sería muy apreciada.

¿Fue útil?

Solución

Los MBeans se ejecutan en un hilo separado que su aplicación, por lo que no tienen acceso al contexto de nombres de aplicaciones en JNDI y, por lo tanto, no tienen acceso a su transacción de usuario.

Creo que su explicación potencial final es probablemente más precisa:

Es posible que no se suponga que deba usar MBeans de esta manera, a pesar de las declaraciones de IBM que debería poder. Se ha sugerido que los EJB son la solución apropiada para este tipo de requisito.

Los MBeans pueden no ser apropiados para este tipo de trabajo. Más bien, usar EJBS o un servicio web podría ser más apropiado.

Otros consejos

Tienes que configurar TransactionManagementType.BEAN en la gestión de transacciones como así:

@TransactionManagement(TransactionManagementType.BEAN) 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top