12 Replies Latest reply on May 13, 2006 3:01 AM by 807581

    DTX5001 using JTA from a servlet

    807581
      I am using JTA from within a servlet (actually from a Quartz scheduler that was setup from within the init() method of a servlet). I see the following intermittent errors in the log (sometimes it works just fine).

      I am using Sun AS 7 service pack 5 on Solaris with JDK 1.4.2_06.

      Any ideas how to avoid this problem? Is this a known issue?

      SEVERE ( 8709): DTX5001:Exception in enlistComponentResources.
      java.lang.NullPointerException
           at com.sun.appserv.util.cache.BaseCache.hash(BaseCache.java:165)
           at com.sun.appserv.util.cache.BaseCache.get(BaseCache.java:286)
           at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.getResourceList(J2EETransactionManagerImpl.java:661)
           at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.enlistComponentResources(J2EETransactionManagerImpl.java:476)
           at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.enlistComponentResources(J2EETransactionManagerImpl.java:317)
           at com.sun.enterprise.distributedtx.UserTransactionImpl.begin(UserTransactionImpl.java:102)
           ...
        • 1. Re: DTX5001 using JTA from a servlet
          807581
          Does anyone have any ideas on this? I have exactly the same issues with the distributed transaction.
          • 2. Re: DTX5001 using JTA from a servlet
            807581
            Transaction can not be started on any user thread. Looks like, in this specific case, some other thread is trying call UserTransaction.begin().

            regards
            sankar
            • 3. Re: DTX5001 using JTA from a servlet
              807581
              Here is the debug information and stack trace:

              [#|2005-03-11T10:53:26.056-0700|INFO|sun-appserver-pe8.1|org.apache.catalina.core.StandardEngine|_ThreadID=10;|Starting Servlet Engine: Sun-Java-System/Application-Server|#]

              [#|2005-03-11T10:53:28.649-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.container.web|_ThreadID=10;|WebModule[/itc]Loading Spring root WebApplicationContext|#]

              [#|2005-03-11T10:53:42.353-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.container.web|_ThreadID=10;|WEB0703: Initializing Sun-Java-System/Application-Server-PE HTTP/1.1 on 8080|#]

              [#|2005-03-11T10:53:42.368-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.container.web|_ThreadID=10;|WEB0712: Starting Sun-Java-System/Application-Server-PE HTTP/1.1 on 8080|#]

              [#|2005-03-11T10:53:42.462-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.container.web|_ThreadID=10;|WEB0703: Initializing Sun-Java-System/Application-Server-PE HTTP/1.1 on 8181|#]

              [#|2005-03-11T10:53:42.478-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.container.web|_ThreadID=10;|WEB0712: Starting Sun-Java-System/Application-Server-PE HTTP/1.1 on 8181|#]

              [#|2005-03-11T10:53:42.509-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.container.web|_ThreadID=10;|WEB0703: Initializing Sun-Java-System/Application-Server-PE HTTP/1.1 on 4848|#]

              [#|2005-03-11T10:53:42.509-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.container.web|_ThreadID=10;|WEB0712: Starting Sun-Java-System/Application-Server-PE HTTP/1.1 on 4848|#]

              [#|2005-03-11T10:53:42.806-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.tools.admin|_ThreadID=10;|ADM1501: Here is the JMXServiceURL for the JMXConnectorServer: [service:jmx:rmi:///jndi/rmi://A0282.aesodev.ca:8686/management/rmi-jmx-connector]. This is where the remote administrative clients should connect using the JSR 160 JMX Connectors.|#]

              [#|2005-03-11T10:53:42.806-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.tools.admin|_ThreadID=10;|ADM1502: Status of System JMX Connector: Active = [true]|#]

              [#|2005-03-11T10:53:42.853-0700|INFO|sun-appserver-pe8.1|javax.enterprise.system.core|_ThreadID=10;|Application server startup complete.|#]

              [#|2005-03-11T10:54:09.040-0700|FINE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=11;|--Created new J2EETransaction, txId = 2|#]

              [#|2005-03-11T10:54:09.040-0700|FINE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=11;|TM: enlistComponentResources|#]

              [#|2005-03-11T10:54:09.040-0700|SEVERE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=11;|DTX5001:Exception in enlistComponentResources.
              java.lang.NullPointerException
                   at com.sun.appserv.util.cache.BaseCache.hash(BaseCache.java:174)
                   at com.sun.appserv.util.cache.BaseCache.get(BaseCache.java:295)
                   at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.getResourceList(J2EETransactionManagerImpl.java:733)
                   at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.enlistComponentResources(J2EETransactionManagerImpl.java:500)
                   at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.enlistComponentResources(J2EETransactionManagerImpl.java:347)
                   at com.sun.enterprise.distributedtx.UserTransactionImpl.begin(UserTransactionImpl.java:130)
                   at org.springframework.transaction.jta.JtaTransactionManager.doBegin(JtaTransactionManager.java:437)
                   at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:271)
                   at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:201)
                   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:49)
                   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
                   at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:619)
                   at ca.aeso.itc.service.LockManager$$EnhancerByCGLIB$$936cdaf9.lock(<generated>)
                   at ca.aeso.itc.job.SynchronizedJob.execute(SynchronizedJob.java:44)
                   at com.aptc.corp.schedule.Scheduler$ThreadPool$WorkerThread.run(Scheduler.java:498)
              |#]

              [#|2005-03-11T10:54:09.134-0700|FINE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=11;|

              In J2EETransactionManagerOpt.enlistResource, h=1 h.xares=com.sun.gjc.spi.XAResourceImpl@56a1b6 h.alloc=com.sun.enterprise.resource.ConnectorAllocator@192d8d4 tx=J2EETransaction: txId=2 nonXAResource=null jtsTx=null localTxStatus=0 syncs=[]|#]

              [#|2005-03-11T10:54:09.150-0700|FINE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=11;|TM: enlistResource|#]

              [#|2005-03-11T10:54:09.150-0700|FINE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=11;|--In J2EETransaction.enlistResource, jtsTx=com.sun.jts.jta.TransactionImpl@aba3041e nonXAResource=null|#]

              [#|2005-03-11T10:54:09.931-0700|FINE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=11;|--In J2EETransaction.registerSynchronization, jtsTx=com.sun.jts.jta.TransactionImpl@aba3041e nonXAResource=null|#]

              [#|2005-03-11T10:54:09.978-0700|FINE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=11;|TM: delistComponentResources|#]

              [#|2005-03-11T10:54:09.978-0700|SEVERE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=11;|DTX5002:Exception in delistComponentResources.
              java.lang.NullPointerException
                   at com.sun.appserv.util.cache.BaseCache.hash(BaseCache.java:174)
                   at com.sun.appserv.util.cache.BaseCache.get(BaseCache.java:295)
                   at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.getExistingResourceList(J2EETransactionManagerImpl.java:705)
                   at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.delistComponentResources(J2EETransactionManagerImpl.java:551)
                   at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.delistComponentResources(J2EETransactionManagerImpl.java:381)
                   at com.sun.enterprise.distributedtx.UserTransactionImpl.commit(UserTransactionImpl.java:157)
                   at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:533)
                   at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:376)
                   at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:242)
                   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:66)
                   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
                   at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:619)
                   at ca.aeso.itc.service.LockManager$$EnhancerByCGLIB$$936cdaf9.lock(<generated>)
                   at ca.aeso.itc.job.SynchronizedJob.execute(SynchronizedJob.java:44)
                   at com.aptc.corp.schedule.Scheduler$ThreadPool$WorkerThread.run(Scheduler.java:498)
              |#]
              • 4. Re: DTX5001 using JTA from a servlet
                807581
                Can you point me at the spec that says that? On my reading of the JTA spec, it shouldn't matter who created the thread using the UserTransaction interface. In section 3.1, paragraph 1 of the JTA 1.0.1 spec:

                The javax.transaction.UserTransaction interface provides the application the ability to control transaction boundaries programmatically. This interface may be used by Java client programs or EJB beans.

                Also note the behavior is not consistent (sometimes it works, sometimes it fails), and differs from WebLogic (which always works).
                • 5. Re: DTX5001 using JTA from a servlet
                  807581
                  My application also works with Oracle App Server 10g. We are doing a proof-of-concept project for migrating the application from Oracle App Server to SunOne. I had troubles in the past 3 days trying to figure out the distributed transaction issue. I'm using Oracle JDBC drivers, and I set up the JDBC pools and JMS with distributed transaction support. I'm testing this on Sun Java Application Server Platform Edition 8.1. This error is consistent.
                  • 6. Re: DTX5001 using JTA from a servlet
                    807581
                    Does anyone have any ideas about this? It looks like very few people are using SunOne App Server and JTA in a user thread.
                    • 7. Re: DTX5001 using JTA from a servlet
                      807581
                      In general, we shouldn't write any incompatible code. I am not sure, if BEA and oracle officially support this or just happen to work.

                      According to the J2EE Spec, user threads shouldn't start a JTA transaction.

                      See the Java 2 Platform Enterprise Edition Specification, v1.4

                      Section J2EE.4.2.3 Transactions and Thread
                      Things are metnioned clearly, what can be done and what can't be done.
                      Just FYI, I am posting the contents of one paragraph in that section.

                      "JTA transactions should be started and completed in the thread which the service method is called. Additional threads that are created for any purpose, should not attempt to start JTA transactions."



                      Hope things are clear now.


                      regards
                      sankar
                      • 8. Re: DTX5001 using JTA from a servlet
                        807581
                        Thanks for the reply. Now the question is: does this mean I have to define two transaction managers in spring config so the JTA transaction manager is used by web components and the normal transaction manager is used by user threads? Honestly this is so ugly. Lots of applications need the scheduler support for their business process.

                        Oracle offically supports this by setting the userThreads flag to true.
                        • 9. Re: DTX5001 using JTA from a servlet
                          807581
                          One more question: if JTA transaction is not allowed in user threads, how can a user thread do if it needs to do distributed transaction, for example, it needs to do some database operation and publish a JMS message? The JMS message publishing and the database operation should be in one transaction in order to make sure rollback of the database operation should lead to the discard of the JMS message.
                          • 10. Re: DTX5001 using JTA from a servlet
                            807581
                            The spec only says if the user threads are created in a servlet's service method, JTA transactions are not support. It does not mention if a JMS listener that is created by ContextLoaderListener can use JTA transaction. Defintely SunOne app server does not allow this either. Check the following stack trace:

                            =======================
                            [#|2005-03-23T12:25:36.676-0700|FINE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=10;|--Created new J2EETransaction, txId = 2|#]

                            [#|2005-03-23T12:25:36.676-0700|FINE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=10;|TM: enlistComponentResources|#]

                            [#|2005-03-23T12:25:36.676-0700|SEVERE|sun-appserver-pe8.1|javax.enterprise.resource.jta|_ThreadID=10;|DTX5001:Exception in enlistComponentResources.
                            java.lang.NullPointerException
                                 at com.sun.appserv.util.cache.BaseCache.hash(BaseCache.java:174)
                                 at com.sun.appserv.util.cache.BaseCache.get(BaseCache.java:295)
                                 at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.getResourceList(J2EETransactionManagerImpl.java:733)
                                 at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.enlistComponentResources(J2EETransactionManagerImpl.java:500)
                                 at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.enlistComponentResources(J2EETransactionManagerImpl.java:347)
                                 at com.sun.enterprise.distributedtx.UserTransactionImpl.begin(UserTransactionImpl.java:130)
                                 at org.springframework.transaction.jta.JtaTransactionManager.doBegin(JtaTransactionManager.java:437)
                                 at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:271)
                                 at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:201)
                                 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:49)
                                 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
                                 at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:619)
                                 at ca.aeso.itc.service.PostingService$$EnhancerByCGLIB$$3626918a.getPostingTopic(<generated>)
                                 at ca.aeso.itc.jms.PostingChangedListener.initialize(PostingChangedListener.java:45)
                                 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                                 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                                 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                                 at java.lang.reflect.Method.invoke(Method.java:324)
                                 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1071)
                                 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1041)
                                 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:305)
                                 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:223)
                                 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:236)
                                 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:159)
                                 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:261)
                                 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:317)
                                 at org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.refresh(AbstractRefreshableWebApplicationContext.java:131)
                                 at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:177)
                                 at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:105)
                                 at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:48)
                                 at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4010)
                                 at org.apache.catalina.core.StandardContext.start(StandardContext.java:4525)
                                 at com.sun.enterprise.web.WebModule.start(WebModule.java:241)
                                 at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1086)
                                 at org.apache.catalina.core.StandardHost.start(StandardHost.java:833)
                                 at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1086)
                                 at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:483)
                                 at org.apache.catalina.startup.Embedded.start(Embedded.java:894)
                                 at com.sun.enterprise.web.WebContainer.start(WebContainer.java:688)
                                 at com.sun.enterprise.web.PEWebContainer.startInstance(PEWebContainer.java:507)
                                 at com.sun.enterprise.web.PEWebContainerLifecycle.onStartup(PEWebContainerLifecycle.java:54)
                                 at com.sun.enterprise.server.ApplicationServer.onStartup(ApplicationServer.java:300)
                                 at com.sun.enterprise.server.PEMain.run(PEMain.java:294)
                                 at com.sun.enterprise.server.PEMain.main(PEMain.java:220)
                            |#]
                            • 11. Re: DTX5001 using JTA from a servlet
                              807581
                              JTA support from any threads other than the threads given to the J2EE application by the container is not supported.
                              If you believe some user threads can create JTA transactions, you might request for a spec clarification by sending a mail to
                              "j2ee-spec-feedback@sun.com", if you get a positive answer from the spec, I am sure you can get this fixed.

                              regards
                              sankar
                              • 12. Re: DTX5001 using JTA from a servlet
                                807581
                                JTA support from any threads other than the threads
                                given to the J2EE application by the container is not
                                supported.
                                If you believe some user threads can create JTA
                                transactions, you might request for a spec
                                clarification by sending a mail to
                                "j2ee-spec-feedback@sun.com", if you get a positive
                                answer from the spec, I am sure you can get this
                                fixed.

                                regards
                                sankar
                                Sankar,

                                Your argument is flawed. The section of the J2EE 1.4 platform specifications you refer to clearly says a web component should work with JTA transactions in the same thread that called a service method.

                                Now the wording of this section is quite confusing which may lead to some confusion. Any service method will always be called in the scope of a JTA transaction - if the method is configured to work inside a transactional.

                                In case of an EJB container, the stub class returned by the container starts a JTA transaction in the client thread before calling a EJB session bean method. Now, clients may access EJB session beans locally or remotely.

                                I'm sure that up to this point you agree. If a client accesses an EJB session bean remotely it will do so from another thread, probably in a different VM. It's perfectly valid to start a JTA transaction from a thread in a client VM and then call one or more EJB session bean methods on a server in another VM. The server should orchestrate the transaction outcome on the server when the client thread ends the transaction.

                                I'm not sure about Oracle but BEA officially supports this, as you can verify here:

                                http://e-docs.bea.com/wls/docs81/jta/gstrx.html#1071279

                                The scenario described in the document above in no way conflicts with the J2EE 1.4 specifications so I see no reason why Sun Application Server doesn't support it.