Camel CDI with standalone JTA in Weld SE

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Camel CDI with standalone JTA in Weld SE

Gary Hodgson
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.AtomikosTransactionRequiredJMSException:
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.throwAtomikosTransactionRequiredJMSException(AtomikosTransactionRequiredJMSException.java:23)
~[transactions-jms-4.0.4.jar:?]
      at
com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProducerSupport.java:90)
~[transactions-jms-4.0.4.jar:?]
      at
com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(AtomikosJmsMessageProducerProxy.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$CamelJmsTemplate.doSend(JmsConfiguration.java:624)
~[camel-jms-2.20.0.jar:2.20.0]
      at
org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.doSendToDestination(JmsConfiguration.java:563)
~[camel-jms-2.20.0.jar:2.20.0]
      at
org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.access$100(JmsConfiguration.java:505)
~[camel-jms-2.20.0.jar:2.20.0]
      at
org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate$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$CamelJmsTemplate.send(JmsConfiguration.java:516)
~[camel-jms-2.20.0.jar:2.20.0]
      at
org.apache.camel.component.jms.JmsProducer.doSend(JmsProducer.java:440)
~[camel-jms-2.20.0.jar:2.20.0]
      at
org.apache.camel.component.jms.JmsProducer.processInOnly(JmsProducer.java:394)
~[camel-jms-2.20.0.jar:2.20.0]
      at
org.apache.camel.component.jms.JmsProducer.process(JmsProducer.java:157)
~[camel-jms-2.20.0.jar:2.20.0]
      at
org.apache.camel.processor.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:186)
~[camel-core-2.20.0.jar:2.20.0]
      at
org.apache.camel.processor.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:86)
~[camel-core-2.20.0.jar:2.20.0]
      at
org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:541)
~[camel-core-2.20.0.jar:2.20.0]
      at
org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:506)
~[camel-core-2.20.0.jar:2.20.0]
      at
org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:369)
~[camel-core-2.20.0.jar:2.20.0]
      at
org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.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(DefaultProducerTemplate.java:144)
~[camel-core-2.20.0.jar:2.20.0]
      at
org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.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 | Threaded
Open this post in threaded view
|

Re: Camel CDI with standalone JTA in Weld SE

astefanutti
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 <[hidden email]> 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.AtomikosTransactionRequiredJMSException:
> 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.throwAtomikosTransactionRequiredJMSException(AtomikosTransactionRequiredJMSException.java:23)
> ~[transactions-jms-4.0.4.jar:?]
>      at
> com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProducerSupport.java:90)
> ~[transactions-jms-4.0.4.jar:?]
>      at
> com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(AtomikosJmsMessageProducerProxy.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$CamelJmsTemplate.doSend(JmsConfiguration.java:624)
> ~[camel-jms-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.doSendToDestination(JmsConfiguration.java:563)
> ~[camel-jms-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.access$100(JmsConfiguration.java:505)
> ~[camel-jms-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate$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$CamelJmsTemplate.send(JmsConfiguration.java:516)
> ~[camel-jms-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.component.jms.JmsProducer.doSend(JmsProducer.java:440)
> ~[camel-jms-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.component.jms.JmsProducer.processInOnly(JmsProducer.java:394)
> ~[camel-jms-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.component.jms.JmsProducer.process(JmsProducer.java:157)
> ~[camel-jms-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.processor.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:186)
> ~[camel-core-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.processor.SharedCamelInternalProcessor.process(SharedCamelInternalProcessor.java:86)
> ~[camel-core-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:541)
> ~[camel-core-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.impl.ProducerCache$1.doInProducer(ProducerCache.java:506)
> ~[camel-core-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:369)
> ~[camel-core-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.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(DefaultProducerTemplate.java:144)
> ~[camel-core-2.20.0.jar:2.20.0]
>      at
> org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.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 | Threaded
Open this post in threaded view
|

Re: Camel CDI with standalone JTA in Weld SE

Gary Hodgson
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 <[hidden email]>
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 <[hidden email]> 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.AtomikosTransactionRequiredJMSException:
> > 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.
> throwAtomikosTransactionRequiredJMSException(
> AtomikosTransactionRequiredJMSException.java:23)
> > ~[transactions-jms-4.0.4.jar:?]
> >      at
> > com.atomikos.jms.ConsumerProducerSupport.enlist(
> ConsumerProducerSupport.java:90)
> > ~[transactions-jms-4.0.4.jar:?]
> >      at
> > com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(
> AtomikosJmsMessageProducerProxy.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$CamelJmsTemplate.doSend(
> JmsConfiguration.java:624)
> > ~[camel-jms-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.
> doSendToDestination(JmsConfiguration.java:563)
> > ~[camel-jms-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.component.jms.JmsConfiguration$
> CamelJmsTemplate.access$100(JmsConfiguration.java:505)
> > ~[camel-jms-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.component.jms.JmsConfiguration$
> CamelJmsTemplate$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$CamelJmsTemplate.send(
> JmsConfiguration.java:516)
> > ~[camel-jms-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.component.jms.JmsProducer.doSend(JmsProducer.java:440)
> > ~[camel-jms-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.component.jms.JmsProducer.processInOnly(
> JmsProducer.java:394)
> > ~[camel-jms-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.component.jms.JmsProducer.process(JmsProducer.java:157)
> > ~[camel-jms-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.processor.SharedCamelInternalProcessor.process(
> SharedCamelInternalProcessor.java:186)
> > ~[camel-core-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.processor.SharedCamelInternalProcessor.process(
> SharedCamelInternalProcessor.java:86)
> > ~[camel-core-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.impl.ProducerCache$1.doInProducer(
> ProducerCache.java:541)
> > ~[camel-core-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.impl.ProducerCache$1.doInProducer(
> ProducerCache.java:506)
> > ~[camel-core-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:369)
> > ~[camel-core-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.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(
> DefaultProducerTemplate.java:144)
> > ~[camel-core-2.20.0.jar:2.20.0]
> >      at
> > org.apache.camel.impl.DefaultProducerTemplate.sendBody(
> DefaultProducerTemplate.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 | Threaded
Open this post in threaded view
|

Re: Camel CDI with standalone JTA in Weld SE

Gary Hodgson
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 <[hidden email]> 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 <[hidden email]>
> 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 <[hidden email]> 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.AtomikosTransactionRequiredJMSException:
>> > 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(JmsProducer.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 | Threaded
Open this post in threaded view
|

Re: Camel CDI with standalone JTA in Weld SE

Gary Hodgson
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 <[hidden email]> 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 <[hidden email]>
> 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 <[hidden email]>
>> 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 <[hidden email]>
>>> 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 | Threaded
Open this post in threaded view
|

Re: Camel CDI with standalone JTA in Weld SE

astefanutti
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]>
>> 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 <[hidden email]>
>>> 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 <[hidden email]>
>>>> 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 | Threaded
Open this post in threaded view
|

Re: Camel CDI with standalone JTA in Weld SE

Gary Hodgson
Hi Antonin

So I created a branch which attempts to use Narayana.
https://github.com/garyhodgson/camel-example-cdi-standalone-jta/tree/narayana

I see the arjuna transaction manager starts up but the logs seem to
indicate too little interaction with the activemq connection factory I
think, and the results are not as I expect (the logs end with "middle
QueueSize = 2" where it should only be one).  I've posted the output of the
camel:run command in the off-chance anyone wants to take a look:
https://gist.github.com/garyhodgson/c96bc6c90656c5f1a2af21f95caacf9f

I'll look forward to any examples you get around to makeing - hopefully
they will help show me where I'm going wrong.

Cheers,
Gary

On 28 November 2017 at 18:00, Antonin Stefanutti <[hidden email]>
wrote:

> 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 <[hidden email]> 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 <[hidden email]>
> 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 <[hidden email]>
> >> 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 <[hidden email]
> >
> >>> 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 <[hidden email]>
> >>>> 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.ResourceInjectReplacementExten
> sion)
> >>>> 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
> >>>>
> >>>>
> >>>
> >>
>
>