Hi Gary, Would that be possible for you to test with anther transaction implementation?
IIRC I add some issues with Atomikos and then switch to JBoss JTA / Narayana and it worked. I plan to add a Camel CDI / JMS / JTA example ASAP which should cover that. Antonin > On 28 Nov 2017, at 00:25, Gary Hodgson <gary.s.hodg...@gmail.com> wrote: > > Scratch that - setting > the activeMQConfiguration.setUseSingleConnection(true) causes everything to > run in the same thread and the problem still occurs. > > On 27 November 2017 at 23:59, Gary Hodgson <gary.s.hodg...@gmail.com> wrote: > >> Hi >> >> So after a hiatus I got time to look at this problem again. From delving >> into the atomikos code and the trace logs I believe the issue lies in >> threading. As shown in the logs below the atomikos jms factory bean >> appears to correctly create a composite transaction on the camel >> JmsConsumer thread. However the jms session requesting the transaction is >> running on the main thread and cannot find it. (The composite transaction >> managers appear to be stored in a map keyed by thread). >> >> I realise this is quite a specific problem which the majority of people >> avoid by (sensibly) running camel-cdi and jta in wildfly, but if anyone has >> experience or ideas on how to make camel and atomikos find each other here >> it would be most appreciated. I'll also have a go with Narayana whether >> that yields more success. >> >> Transaction created on this thread... >> >> [Camel (camel-1) thread #1 - JmsConsumer[start]] DEBUG >> com.atomikos.icatch.imp.CompositeTransactionManagerImp - >> createCompositeTransaction ( 10000 ): created new ROOT transaction with id >> 10.0.75.1.tm151182109511700001 >> [Camel (camel-1) thread #1 - JmsConsumer[start]] DEBUG >> com.atomikos.jms.AtomikosConnectionFactoryBean >> - AtomikosConnectionFactoryBean 'xamq': createConnection()... >> [Camel (camel-1) thread #1 - JmsConsumer[start]] INFO >> com.atomikos.jms.AtomikosConnectionFactoryBean >> - AtomikosConnectionFactoryBean 'xamq': init... >> [Camel (camel-1) thread #1 - JmsConsumer[start]] TRACE >> com.atomikos.icatch.imp.CompositeTransactionManagerImp - >> getCompositeTransaction() returning instance with id >> 10.0.75.1.tm151182109511700001 >> [Camel (camel-1) thread #1 - JmsConsumer[start]] TRACE >> com.atomikos.datasource.pool.ConnectionPool - atomikos connection pool >> 'xamq': about to wait for connection during 30000ms... >> [main] TRACE com.atomikos.datasource.xa.session.SessionHandleState - a >> SessionHandleState with 0 context(s): notifySessionBorrowed >> [main] TRACE com.atomikos.datasource.xa.session.TransactionContext - a >> TransactionContext: changing to state com.atomikos.datasource.xa.session. >> NotInBranchStateHandler@a826ff8 >> [main] DEBUG com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa >> session proxy for resource xamq: calling toString on JMS driver session... >> [main] TRACE com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa >> session proxy for resource xamq: toString returning ActiveMQSession >> {id=ID:garyhodgson-PC-57091-1511821093820-1:1:2,started=false} >> java.lang.Object@63187d63 >> [main] TRACE com.atomikos.jms.AtomikosJmsConnectionProxy - atomikos >> connection proxy for resource xamq: returning ActiveMQSession >> {id=ID:garyhodgson-PC-57091-1511821093820-1:1:2,started=false} >> java.lang.Object@63187d63 >> [main] DEBUG com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa >> session proxy for resource xamq: calling createQueue on JMS driver >> session... >> [main] TRACE com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa >> session proxy for resource xamq: createQueue returning queue://start >> [main] DEBUG com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa >> session proxy for resource xamq: calling createProducer on JMS driver >> session ActiveMQSession {id=ID:garyhodgson-PC-57091- >> 1511821093820-1:1:2,started=false} java.lang.Object@63187d63 >> [main] TRACE com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa >> session proxy for resource xamq: createProducer returning atomikos >> MessageProducer proxy for ActiveMQMessageProducer { >> value=ID:garyhodgson-PC-57091-1511821093820-1:1:2:1 } >> [main] DEBUG com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa >> session proxy for resource xamq: calling createTextMessage on JMS driver >> session... >> [main] TRACE com.atomikos.jms.AtomikosJmsXaSessionProxy - atomikos xa >> session proxy for resource xamq: createTextMessage returning >> ActiveMQTextMessage {commandId = 0, responseRequired = false, messageId = >> null, originalDestination = null, originalTransactionId = null, producerId >> = null, destination = null, transactionId = null, expiration = 0, timestamp >> = 0, arrival = 0, brokerInTime = 0, brokerOutTime = 0, correlationId = >> null, replyTo = null, persistent = false, type = null, priority = 0, >> groupID = null, groupSequence = 0, targetConsumerId = null, compressed = >> false, userID = null, content = null, marshalledProperties = null, >> dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, >> readOnlyProperties = false, readOnlyBody = false, droppable = false, >> jmsXGroupFirstForConsumer = false, text = null} >> [main] DEBUG com.atomikos.jms.AtomikosJmsMessageProducerProxy - >> atomikos MessageProducer proxy for ActiveMQMessageProducer { >> value=ID:garyhodgson-PC-57091-1511821093820-1:1:2:1 }: send ( message )... >> >> Attempt to get transaction here... >> >> [main] TRACE com.atomikos.icatch.imp.CompositeTransactionManagerImp - >> getCompositeTransaction() returning NULL! >> [main] WARN com.atomikos.jms.ConsumerProducerSupport - atomikos >> MessageProducer proxy for ActiveMQMessageProducer { >> value=ID:garyhodgson-PC-57091-1511821093820-1:1:2:1 }: The JMS session >> you are using requires a JTA transaction context for the calling thread and >> none was found. >> Please correct your code to do one of the following: >> 1. start a JTA transaction if you want your JMS operations to be subject >> to JTA commit/rollback, or >> 2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to >> avoid transaction timeout while waiting for a connection, or >> 3. create a non-transacted session and do session acknowledgment >> yourself, or >> 4. set localTransactionMode to true so connection-level commit/rollback >> are enabled. >> >> >> Cheers, >> Gary >> >> >> On 6 November 2017 at 18:16, Gary Hodgson <gary.s.hodg...@gmail.com> >> wrote: >> >>> Hi Antonin. >>> >>> Thanks for the response. >>> >>> I attempted a naive implementation of TransactionServices and it appears >>> to load via the serviceloader correctly, and produce UserTransactions: >>> https://github.com/garyhodgson/camel-example-cdi-standalone- >>> jta/blob/TransactionServices/src/main/java/org/apache/ >>> camel/example/cdi/util/TransactionServices.java >>> >>> Sadly the AtomikosTransactionRequiredJMSException is still thrown. >>> >>> >>> On 6 November 2017 at 11:52, Antonin Stefanutti <anto...@stefanutti.fr> >>> wrote: >>> >>>> Hi Gary, >>>> >>>> Your CDI producers for the ActiveMQ component and the transaction >>>> manager look OK (aside that you would have to destroy the connection >>>> factory in a dispose method). >>>> >>>> However The way you produce the UserTransaction may be problematic. With >>>> Weld SE, you would typically implement >>>> org.jboss.weld.transaction.spi.TransactionServices >>>> and add it as a Weld service before starting the CDI container. >>>> >>>> Let me know if that helps. >>>> >>>> Antonin >>>> >>>>> On 5 Nov 2017, at 21:54, Gary Hodgson <gary.s.hodg...@gmail.com> >>>> wrote: >>>>> >>>>> Hi, >>>>> >>>>> I am trying to get camel-cdi to work with a standalone JTA provider in >>>> a >>>>> non-JEE environment. I've made some progress but have a couple of >>>> issues >>>>> which I am not sure is due to my understanding or the code. >>>>> >>>>> I created a standalone demo project here to show the issues: >>>>> https://github.com/garyhodgson/camel-example-cdi-standalone-jta >>>>> >>>>> The demo uses Atomikos as the JTA provider and embedded ActiveMQ for >>>> JMS. >>>>> Running the project with camel:run results in three messages being >>>> sent to >>>>> the route. The first two are called explicitly in a userTransaction and >>>>> behave as expected: the first is processed normally, the second >>>> triggers a >>>>> rollback (as expected). >>>>> >>>>> The third message is outside a userTransaction and throws the following >>>>> exception from Atomikos: >>>>> >>>>> Caused by: com.atomikos.jms.AtomikosTrans >>>> actionRequiredJMSException: >>>>> The JMS session you are using requires a JTA transaction context for >>>> the >>>>> calling thread and none was found. >>>>> Please correct your code to do one of the following: >>>>> 1. start a JTA transaction if you want your JMS operations to be >>>>> subject to JTA commit/rollback, or >>>>> 2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to >>>>> avoid transaction timeout while waiting for a connection, or >>>>> 3. create a non-transacted session and do session acknowledgment >>>>> yourself, or >>>>> 4. set localTransactionMode to true so connection-level >>>> commit/rollback >>>>> are enabled. >>>>> at >>>>> com.atomikos.jms.AtomikosTransactionRequiredJMSException.thr >>>> owAtomikosTransactionRequiredJMSException(AtomikosTransactio >>>> nRequiredJMSException.java:23) >>>>> ~[transactions-jms-4.0.4.jar:?] >>>>> at >>>>> com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProd >>>> ucerSupport.java:90) >>>>> ~[transactions-jms-4.0.4.jar:?] >>>>> at >>>>> com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(Atomik >>>> osJmsMessageProducerProxy.java:34) >>>>> ~[transactions-jms-4.0.4.jar:?] >>>>> at >>>>> org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:626) >>>>> ~[spring-jms-4.3.11.RELEASE.jar:4.3.11.RELEASE] >>>>> at >>>>> org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemp >>>> late.doSend(JmsConfiguration.java:624) >>>>> ~[camel-jms-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemp >>>> late.doSendToDestination(JmsConfiguration.java:563) >>>>> ~[camel-jms-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemp >>>> late.access$100(JmsConfiguration.java:505) >>>>> ~[camel-jms-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemp >>>> late$1.doInJms(JmsConfiguration.java:519) >>>>> ~[camel-jms-2.20.0.jar:2.20.0] >>>>> at >>>>> org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:484) >>>>> ~[spring-jms-4.3.11.RELEASE.jar:4.3.11.RELEASE] >>>>> at >>>>> org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemp >>>> late.send(JmsConfiguration.java:516) >>>>> ~[camel-jms-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.component.jms.JmsProducer.doSend(JmsProduce >>>> r.java:440) >>>>> ~[camel-jms-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.component.jms.JmsProducer.processInOnly(Jms >>>> Producer.java:394) >>>>> ~[camel-jms-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.component.jms.JmsProducer.process(JmsProduc >>>> er.java:157) >>>>> ~[camel-jms-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.processor.SharedCamelInternalProcessor.proc >>>> ess(SharedCamelInternalProcessor.java:186) >>>>> ~[camel-core-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.processor.SharedCamelInternalProcessor.proc >>>> ess(SharedCamelInternalProcessor.java:86) >>>>> ~[camel-core-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerC >>>> ache.java:541) >>>>> ~[camel-core-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerC >>>> ache.java:506) >>>>> ~[camel-core-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.impl.ProducerCache.doInProducer(ProducerCac >>>> he.java:369) >>>>> ~[camel-core-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.impl.ProducerCache.sendExchange(ProducerCac >>>> he.java:506) >>>>> ~[camel-core-2.20.0.jar:2.20.0] >>>>> at org.apache.camel.impl.ProducerCache.send(ProducerCache.java: >>>> 229) >>>>> ~[camel-core-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.impl.DefaultProducerTemplate.send(DefaultPr >>>> oducerTemplate.java:144) >>>>> ~[camel-core-2.20.0.jar:2.20.0] >>>>> at >>>>> org.apache.camel.impl.DefaultProducerTemplate.sendBody(Defau >>>> ltProducerTemplate.java:161) >>>>> ~[camel-core-2.20.0.jar:2.20.0] >>>>> ... 56 more >>>>> >>>>> >>>>> I expected that "transacted()" on the route to have caused a >>>> transaction to >>>>> be created, and I am not sure why it has not been - other than it >>>> having >>>>> something to do with this example running outside of a JEE Application >>>>> Server. Is my expectation here incorrect? >>>>> >>>>> I believe the various required beans have been correctly configured as >>>>> Producer methods under org.apache.camel.example.cdi.util.CdiProducers >>>>> >>>>> As an aside: in order to get this working in a Weld SE environment I >>>> use a >>>>> CDI extension >>>>> (org.apache.camel.example.cdi.util.ResourceInjectReplacementExtension) >>>> to >>>>> add an @Inject annotation to the transactionManager attribute in >>>>> org.apache.camel.cdi.transaction.JtaTransactionPolicy. Perhaps it >>>> would be >>>>> worth considering adding the annotation in camel-cdi to enable it to be >>>>> used in a SE environment? (though I don't know if this would adversely >>>>> affect the JEE world.) >>>>> >>>>> >>>>> Any insights would be appreciated. >>>>> >>>>> Cheers, >>>>> Gary >>>> >>>> >>> >>