Affects: v5.3.15 (detected there)
Complete setup involved Apache Camel in conjunction with Narayana Transaction Manager and RedHat Quarkus.
Example project is here:
https://github.com/cquoss/camel-quarkus-xa-from-jms-to-db/tree/topic
Look into the topic branch.
When trying to consume from this durable subscription error 'client id has not been set' is raised:
2022-02-23 18:04:23,097 [Camel (camel-1) thread #1 - JmsConsumer[foo]] [{camel.contextId=camel-1}] DEBUG org.apache.camel.component.jms.DefaultJmsMessageListenerContainer Initiating transaction rollback on listener exception: javax.jms.IllegalStateException: Cannot create durable subscription - client ID has not been set
at org.apache.activemq.artemis.jms.client.ActiveMQSession.createConsumer(ActiveMQSession.java:876)
at org.apache.activemq.artemis.jms.client.ActiveMQSession.createDurableSubscriber(ActiveMQSession.java:596)
at org.springframework.jms.listener.AbstractMessageListenerContainer.createConsumer(AbstractMessageListenerContainer.java:863)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.createListenerConsumer(AbstractPollingMessageListenerContainer.java:224)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:300)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:245)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1237)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1227)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1120)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Problem lies before in establishing the (non-shared) connection:
2022-02-23 18:04:22,840 [Camel (camel-1) thread #1 - JmsConsumer[foo]] [{camel.contextId=camel-1}] TRACE org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl getConnectionWithRetry::1 with retryInterval = 2000 multiplier = 1.0: java.lang.Exception: trace
at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.getConnectionWithRetry(ClientSessionFactoryImpl.java:818)
at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.connect(ClientSessionFactoryImpl.java:252)
at org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl.connect(ClientSessionFactoryImpl.java:268)
at org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:688)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:884)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:299)
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:294)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:196)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.access$100(AbstractPollingMessageListenerContainer.java:77)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer$MessageListenerContainerResourceFactory.createConnection(AbstractPollingMessageListenerContainer.java:490)
at org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession(ConnectionFactoryUtils.java:325)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:281)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:245)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1237)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1227)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1120)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Code of setting the client id on connection has to be moved to a prepareConnection(...)
method as i provided here:
https://github.com/cquoss/spring-framework/blob/c42b73cf4bf4147e2b6190f98d5efa8038816534/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java#L424
I left prepareSharedConnection(...)
in place, but empty, for compatibility:
https://github.com/cquoss/spring-framework/blob/c42b73cf4bf4147e2b6190f98d5efa8038816534/spring-jms/src/main/java/org/springframework/jms/listener/AbstractJmsListeningContainer.java#L459
Please suggest, comment or complain.
Comment From: cquoss
I will try - not promise - to provide a test including embedded artemis broker (maybe difficult) and in-mem h2 database (easy) in the example project above. Makes it easier to re-produce as right now configuration is for standalone broker and server h2 database.
Comment From: cquoss
Reproducer project has been updated to include an integration test (MainRouteIT).
https://github.com/cquoss/camel-quarkus-xa-from-jms-to-db/tree/topic
Test is still green since it is still WIP, but when looking into target/quarkus.log after running 'mvn verify' one sees the problem:
2022-02-25 12:14:16,506 [Camel (camel-1) thread #1 - JmsConsumer[foo]] [{camel.contextId=camel-1}] WARN org.apache.camel.component.jms.DefaultJmsMessageListenerContainer Setup of JMS message listener invoker failed for destination 'foo' - trying to recover. Cause: Cannot create durable subscription - client ID has not been set
No external set up of artemis broker needed any more since this test makes use of quarkiverse artemis test resource.
Comment From: rstoyanchev
I've edited your comment to improve the formatting. You might want to check out this Mastering Markdown guide for future reference.
Comment From: cquoss
Well. Thanks. Looks much better now.
BTW, i finished on the reproducer project, see current commit:
https://github.com/cquoss/camel-quarkus-xa-from-jms-to-db/commit/042cb1044d6cc3495fa03c6ab948e769ef5a2d94
Only available integration test fails now because connection cannot be established.
Comment From: jyeary
I am facing the same issue. I see that this is still open and in a triage state. Can someone take a look at this and update the status?
Comment From: snicoll
@cquoss thanks for the reproducer but the only import on org.springframework
I could find is on JtaTransactionManager
that is created by hand with no visible handling of bean callbacks. This alone invalidates the reproducer as afterPropertiesSet
at the very least should be called.
If you can reproduce this behavior with a Spring app, please update the reproducer and we can take another look.
Comment From: cquoss
This was a Long Time ago.
From what i Recall from the reproducer the issue occurred in a Quarkus Environment using camel-jms.
So No Spring Context involved.
Regards
Clemens