miércoles, 19 de mayo de 2010

WSTX-SERVICE-5002: A JTA Transaction MUST NOT exist entering WS-TX Service Pipe procesing for binding... SOLUCIONADO

JAX-WS representó una revolución en la implementación de SOAP Web Services en JEE. Su aparición en JEE 5 nos permitió publicar como Web Service un Stateless Session EJB automáticamente, de forma declarativa, añadiendo simplemente la anotación @WebService. Sin embargo, bajo determinadas condiciones, nuestro cliente se puede encontrar con un error que, a priori, nos puede resultar desconcertante:

WSTX-SERVICE-5002: A JTA Transaction MUST NOT exist entering WS-TX Service Pipe procesing for binding '{http://jdialer.sgi.gesif/}dataproviderPortBinding' and operation 'getContacts'. JTA Transaction is  J2EETransaction: txId=51 nonXAResource=null jtsTx=com.sun.jts.jta.TransactionImpl@d419b987 localTxStatus=0 syncs=[]....


Tras este error suelen producirse otros dos igualmente desconcertantes: "HTTP transport error: java.net.UnknownHostException: host_cliente" o el clásico SSL Handshake "HTTP transport error: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target". Es decir, es como si nuestro servidor estuviese intentando contactar con nuestro cliente por HTTPS. ¿Por qué lo hace?

Una pista: las condiciones en las que se da este error es si el cliente es un EJB. Sólamente en ese caso. Si es un servlet, o una aplicación standalone, funciona perfectamente. ¿Esto te da una idea o aún te confunde más?

La explicación es, en realidad, muy sencilla: los EJB's tienen el atributo de transacción establecido por defecto a REQUIRED (@TransactionAttribute(TransactionAttributeType.REQUIRED)). El código cliente del Web Service lo tiene en cuenta y añade un contexto transaccional al mensaje SOAP. Si EJB "servidor" ha declarado que no necesita transacciones (@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)), ya tenemos el problema servido. La solución en estos casos es también sencilla, debemos indicar a nuestro cliente que no use un contexto transaccional en la petición, anotándolo con @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED), y así el servidor no usará el coordinador WSTX (Web Service Transactions).

Related Posts Plugin for WordPress, Blogger...
cookieassistant.com