I'm using spring-boot with camel and ActiveMQ.
I'm using activemq autoconfiguration via @EnableJms annotation. But creating my own ActiveMQComponent to enable "transacted(true)" on all queues.
@Bean(name = "activemq")
@ConditionalOnClass(ActiveMQComponent.class)
public ActiveMQComponent activeMQComponent(ConnectionFactory connectionFactory) {
ActiveMQComponent activeMQComponent = new ActiveMQComponent();
activeMQComponent.setConnectionFactory(connectionFactory);
activeMQComponent.setTransacted(true);
activeMQComponent.setTransactionManager(jmsTransactionManager(connectionFactory));
return activeMQComponent;
}
It works well but when I try to gracefully shutdown the application. The PooledConnectionFactory get destroyed before the camel graceful shutdown happens.
Leading to a tons of error and the route unable to correctly stops.
Like 20 times this error :
2017-05-04 18:21:59.748 WARN 12188 --- [er[test.queue]] o.a.activemq.jms.pool.PooledSession : Caught exception trying rollback() when putting session back into the pool, will invalidate. javax.jms.IllegalStateException: The Session is closed
Followed by:
2017-05-04 18:21:59.748 INFO 12188 --- [ Thread-18] o.a.camel.spring.SpringCamelContext : Apache Camel 2.18.3 (CamelContext: route) is shutting down
Then later :
2017-05-04 18:21:59.766 INFO 12188 --- [ - ShutdownTask] o.a.camel.impl.DefaultShutdownStrategy : Waiting as there are still 1 inflight and pending exchanges to complete, timeout in 300 seconds. Inflights per route: [test2 = 1]
Anyone can help me configuring spring-boot camel activemq all together with graceful shutdown ?
Thanks
Update : Here is a sample of my pom.xml:
<properties>
<!-- Spring -->
<spring-boot.version>1.4.3.RELEASE</spring-boot.version>
<!-- Camel -->
<camel-spring-boot.version>2.18.3</camel-spring-boot.version>
</properties>
....
<!-- Camel BOM -->
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-dependencies</artifactId>
<version>${camel-spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
...
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<!-- ActiveMQ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-camel</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
</dependency>
<!-- Camel -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
Update 2: After further investigation and the creation of a new project adding every modification one by one I have isolated the problem.
The shutdown works correcly until I add a specific endpoint :
@EndpointInject(uri = "direct:aaa")
private Endpoint errorHandling;
Using :
private String errorHandling = "direct:aaa";
Doesn't produce the bug.
It seems like using @EndpointInject is making the activemq close first
Update 3 :
Found that SpringCamelContext is not implementing ApplicationListener and thus its method "onApplicationEvent" its not called handling the "shutdownEager" of camel.
Apparently since https://issues.apache.org/jira/browse/CAMEL-2607 the SpringCamelContext doesn't implement ApplicationListener interface anymore.
Since I'm using spring-boot autoconfiguration, I am not using CamelContextFactoryBean which is adding the listener.
Has a temporary fix, I created a component which listen to ApplicationEvent and dispatch them to the SpringCamelContext method :
}
I had this same problem running unit/integration tests with Spring Boot, ActiveMQ or A-MQ, and Camel (version 2.18.1.redhat-000012). Apparently, when Spring Boot shuts down, the JMS thread pool is closed before the Camel context is shutdown, which is the wrong order. @John D provided a code fix in a Camel users mailing list thread which is similar to what he provided in this thread. Here is the version of John D's code that worked for me:
Important thing is to use Camel Spring Boot Starter.
http://camel.apache.org/spring-boot.html
How to enable Camel auto-configuration in my Spring Boot application?
Just drop camel-spring-boot jar into your classpath:
camel-spring-boot jar comes with the spring.factories file, so as soon as you add that dependency into your classpath, Spring Boot will automatically auto-configure the Camel for you. Yay! That was fast ;) .
Auto-configured Camel context
The most important piece of functionality provided by the Camel auto-configuration is the CamelContext instance.
Camel auto-configuration creates SpringCamelContext for your and take care of the proper initialization and shutdown of that context.
Created Camel context is also registered in the Spring application context (under camelContext bean name), so you can access it just as the any other Spring bean.