Issue
I wanted to schedule a message delay using JMS. For that I'm using JMS 2.0 with Artemis MQ and the message is scheduled successfully in compile time but when I deploy it in Tomcat and try to send the message with a delay it says:
java.lang.IllegalStateException: setDeliveryDelay requires JMS 2.0
I'm guessing that the Tomcat isn't able to communicate properly with the Artemis server I have setup. So I have two servers setup in my system: Tomcat and Artemis. Is it because Tomcat can't communicate with Artemis? If so, then why does my spring boot in-built Tomcat server detects Artemis but my standalone Tomcat doesn't?
My source code for the JMS message sender is:
@Service
public class TransferServiceImpl implements TransferService {
@Autowired
private JmsTemplate jmsTemplate;
@Override
public void transfertoJMS(Transaction transaction) {
System.out.println("Sending a transaction.");
jmsTemplate.setDeliveryDelay(20000);
jmsTemplate.convertAndSend(destinationQueue, transaction);
}
}
My pom.xml
is:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stargate.transferfund</groupId>
<artifactId>TransferFund</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>TransferFund</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<startClass>org.springframework.boot.SpringApplication</startClass>
<maven.test.skip>true</maven.test.skip>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- for test case, in memory db -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<!-- marked the embedded servlet container as provided -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- JMS related dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-junit</artifactId>
<version>1.5.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- http://repo1.maven.org/maven2/commons-lang/commons-lang/2.6/commons-lang-2.6.jar -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
My application.properties
is:
server.port=${port:8085}
# database config
spring.datasource.url=jdbc:mysql://localhost:3306/ach_stargate
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=none
# jms config
jms.queue.destination=TransactionQueue
spring.artemis.mode=native
spring.artemis.host=localhost
spring.artemis.port=61616
spring.artemis.user=admin
spring.artemis.password=admin
Solution
You've got a conflict with two conflicting dependencies. The following dependency is for ActiveMQ 5.x(!):
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
</dependency>
Spring is probably finding the JMS 1.0 spec from that dependency which is overriding the JMS 2.0
spec on your classpath and giving you that java.lang.IllegalStateException
when spring looks for the necessary JMS interface to use when starting up the ConnectionFactory
.
If you want an embedded broker, the spring-boot-starter-artemis
already contains it, so you should be able to remove that activemq-broker
dependency without a problem.
Answered By - Dovmo
Answer Checked By - Candace Johnson (JavaFixing Volunteer)