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
>>>
>>>
>>
>

Reply via email to