0

I'm getting JTA exception while running an example from the Pro Spring 5 book (12. Using Spring Remote, boot-jms project). Here is the entirety of the code (exclude the imports). It only has one file Application.java:

@SpringBootApplication
public class Application {

    private static Logger logger = LoggerFactory.getLogger(Application.class);

    @Bean
    public JmsListenerContainerFactory<DefaultMessageListenerContainer> connectionFactory(ConnectionFactory connectionFactory,
            DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        // This provides all boot's default to this factory, including the message converter
        configurer.configure(factory, connectionFactory);
        // You could still override some of Boot's default if necessary.
        return factory;
    }

    public static void main(String... args) throws Exception {
        ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
        JmsTemplate jmsTemplate = ctx.getBean(JmsTemplate.class);
        jmsTemplate.setDeliveryDelay(5000L);
        for (int i = 0; i < 10; ++i) {
            logger.info(">>> Sending: Test message: " + i);
            jmsTemplate.convertAndSend("prospring5", "Test message: " + i);
        }

        System.in.read();
        ctx.close();
    }

    @JmsListener(destination = "prospring5", containerFactory = "connectionFactory")
    public void onMessage(Message message) {
        TextMessage textMessage = (TextMessage) message;

        try {
            logger.info(">>> Received: " + textMessage.getText());
        } catch (JMSException ex) {
            logger.error("JMS error", ex);
        }
    }
}

First, I got the following error:

Exception in thread "main" java.lang.AbstractMethodError: com.atomikos.jms.AtomikosJmsMessageProducerProxy.setDeliveryDelay(J)V at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:628) at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:608) at org.springframework.jms.core.JmsTemplate.lambda$send$3(JmsTemplate.java:586) at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:504) at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:584) at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:661) at com.apress.prospring5.ch12.Application.main(Application.java:54)

Then I commented out "jmsTemplate.setDeliveryDelay(5000L);". So I was able to get pass this error but only end up with the JTA exception.

Exception in thread "main" org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is 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 org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:311) at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:185) at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:507) at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:584) at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:661) at com.apress.prospring5.ch12.Application.main(Application.java:54) 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:
  5. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or
  6. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or
  7. create a non-transacted session and do session acknowledgment yourself, or
  8. set localTransactionMode to true so connection-level commit/rollback are enabled. at com.atomikos.jms.AtomikosTransactionRequiredJMSException.throwAtomikosTransactionRequiredJMSException(AtomikosTransactionRequiredJMSException.java:23) at com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProducerSupport.java:90) at com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(AtomikosJmsMessageProducerProxy.java:34) at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:634) at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:608) at org.springframework.jms.core.JmsTemplate.lambda$send$3(JmsTemplate.java:586) at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:504) ... 3 more

My project includes the dependency of spring-boot-starter-artemis and spring-boot-starter-jta-atomikos:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-artemis</artifactId>
    <version>2.0.6.RELEASE</version>            
</dependency>
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>artemis-jms-server</artifactId>
    <version>2.4.0</version>            
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jta-atomikos</artifactId>
    <version>2.0.6.RELEASE</version>            
</dependency>
<dependency>
    <groupId>com.atomikos</groupId>
    <artifactId>transactions-hibernate4</artifactId>
    <version>4.0.4</version>            
</dependency>

The error message seems suggesting the Transaction is missing, so I had added @Transactional annotation at the listener and jmsTemplate, but the same problem still persists.

João Dias
  • 16,277
  • 6
  • 33
  • 45
  • Are you using an XA connection factory? See this [question/answer](https://stackoverflow.com/questions/51290771/spring-boot-jta-with-artemis-issue). – Gary Russell Sep 07 '21 at 15:34

1 Answers1

0

The problem seems is that I had included spring-boot-starter-jta-atomikos and transactions-hibernate4 in the dependencies. Once I removed these 2 dependencies, the code works. The intention of this example is not to do transaction but demonstrate spring-boot doing JMS over artemis. But since I have these 2 transaction related files in classpath, spring-boot automatically asks for transaction.