Spring Integration - MQTT subscription issue - spring

I am trying to implement Spring integration with MQTT. I am using Mosquitto as MQTT broker. with the reference to docs provided in the following link. I have created a project and added all the required jar files. when i execute MQTTJavaApplication.
public class MqttJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(MqttJavaApplication.class)
.web(false)
.run(args);
}
#Bean
public MessageChannel mqttInputChannel() {
return new DirectChannel();
}
#Bean
public MqttPahoMessageDrivenChannelAdapter inbound() {
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter("tcp://localhost:1883", "test",
"sample");
adapter.setCompletionTimeout(5000);
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(1);
adapter.setOutputChannel(mqttInputChannel());
return adapter;
}
#Bean
#ServiceActivator(inputChannel = "mqttInputChannel")
public MessageHandler handler() {
return new MessageHandler() {
#Override
public void handleMessage(Message<?> message) {
System.out.println("Test##########"+message.getPayload());
}
};
}
}
I am getting following error when i publish a message via MQTT broker.
[2015-11-23 10:08:19.545] boot - 8100 INFO [main] --- AnnotationConfigApplicationContext: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#2d0e1c: startup date [Mon Nov 23 10:08:19 IST 2015]; root of context hierarchy
[2015-11-23 10:08:19.831] boot - 8100 INFO [main] --- PropertiesFactoryBean: Loading properties file from URL [jar:file:/D:/IoTWorkspace/MQTTTest/WebContent/WEB-INF/lib/spring-integration-core-4.2.1.RELEASE.jar!/META-INF/spring.integration.default.properties]
[2015-11-23 10:08:20.001] boot - 8100 INFO [main] --- DefaultLifecycleProcessor: Starting beans in phase 1073741823
[2015-11-23 10:08:20.104] boot - 8100 INFO [main] --- MqttPahoMessageDrivenChannelAdapter: started inbound
[2015-11-23 10:08:20.112] boot - 8100 INFO [main] --- MqttJavaApplication: Started MqttJavaApplication in 1.602 seconds (JVM running for 2.155)
[2015-11-23 10:13:04.564] boot - 8100 ERROR [MQTT Call: test] --- MqttPahoMessageDrivenChannelAdapter: Unhandled exception for GenericMessage [payload=Testing Subscription, headers={timestamp=1448253784563, id=cd5be974-3b19-8317-47eb-1c139725be24, mqtt_qos=0, mqtt_topic=sample, mqtt_retained=false, mqtt_duplicate=false}]
org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'unknown.channel.name'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:81)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:105)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.messageArrived(MqttPahoMessageDrivenChannelAdapter.java:262)
at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:336)
at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:148)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:153)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
... 10 more
[2015-11-23 10:13:04.613] boot - 8100 ERROR [MQTT Call: test] --- MqttPahoMessageDrivenChannelAdapter: Lost connection:MqttException; retrying...
[2015-11-23 10:13:04.614] boot - 8100 ERROR [MQTT Call: test] --- MqttPahoMessageDrivenChannelAdapter: Failed to schedule reconnect
java.lang.NullPointerException
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.scheduleReconnect(MqttPahoMessageDrivenChannelAdapter.java:228)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.connectionLost(MqttPahoMessageDrivenChannelAdapter.java:255)
at org.eclipse.paho.client.mqttv3.internal.CommsCallback.connectionLost(CommsCallback.java:229)
at org.eclipse.paho.client.mqttv3.internal.ClientComms.shutdownConnection(ClientComms.java:339)
at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:171)
at java.lang.Thread.run(Thread.java:722)
[2015-11-23 10:13:04.617] boot - 8100 INFO [Thread-0] --- AnnotationConfigApplicationContext: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#2d0e1c: startup date [Mon Nov 23 10:08:19 IST 2015]; root of context hierarchy
[2015-11-23 10:13:04.619] boot - 8100 INFO [Thread-0] --- DefaultLifecycleProcessor: Stopping beans in phase 1073741823
[2015-11-23 10:13:04.622] boot - 8100 ERROR [Thread-0] --- MqttPahoMessageDrivenChannelAdapter: Exception while unsubscribing
Client is not connected (32104)
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:27)
at org.eclipse.paho.client.mqttv3.internal.ClientComms.sendNoWait(ClientComms.java:132)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.unsubscribe(MqttAsyncClient.java:707)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.unsubscribe(MqttAsyncClient.java:682)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.doStop(MqttPahoMessageDrivenChannelAdapter.java:124)
at org.springframework.integration.endpoint.AbstractEndpoint.doStop(AbstractEndpoint.java:145)
at org.springframework.integration.endpoint.AbstractEndpoint.stop(AbstractEndpoint.java:128)
at org.springframework.context.support.DefaultLifecycleProcessor.doStop(DefaultLifecycleProcessor.java:229)
at org.springframework.context.support.DefaultLifecycleProcessor.access$300(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.stop(DefaultLifecycleProcessor.java:363)
at org.springframework.context.support.DefaultLifecycleProcessor.stopBeans(DefaultLifecycleProcessor.java:202)
at org.springframework.context.support.DefaultLifecycleProcessor.onClose(DefaultLifecycleProcessor.java:118)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:966)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:893)
[2015-11-23 10:13:04.623] boot - 8100 ERROR [Thread-0] --- MqttPahoMessageDrivenChannelAdapter: Exception while disconnecting
Client is disconnected (32101)
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:27)
at org.eclipse.paho.client.mqttv3.internal.ClientComms.disconnect(ClientComms.java:405)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.disconnect(MqttAsyncClient.java:524)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.disconnect(MqttAsyncClient.java:493)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.disconnect(MqttAsyncClient.java:500)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.doStop(MqttPahoMessageDrivenChannelAdapter.java:131)
at org.springframework.integration.endpoint.AbstractEndpoint.doStop(AbstractEndpoint.java:145)
at org.springframework.integration.endpoint.AbstractEndpoint.stop(AbstractEndpoint.java:128)
at org.springframework.context.support.DefaultLifecycleProcessor.doStop(DefaultLifecycleProcessor.java:229)
at org.springframework.context.support.DefaultLifecycleProcessor.access$300(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.stop(DefaultLifecycleProcessor.java:363)
at org.springframework.context.support.DefaultLifecycleProcessor.stopBeans(DefaultLifecycleProcessor.java:202)
at org.springframework.context.support.DefaultLifecycleProcessor.onClose(DefaultLifecycleProcessor.java:118)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:966)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:893)
[2015-11-23 10:13:04.624] boot - 8100 INFO [Thread-0] --- MqttPahoMessageDrivenChannelAdapter: stopped inbound
Please find below stack trace after adding #SpringBootApplication Annotation
[2015-11-26 10:55:46.571] boot - 5524 INFO [main] --- AnnotationConfigApplicationContext: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#562d4b: startup date [Thu Nov 26 10:55:46 IST 2015]; root of context hierarchy
[2015-11-26 10:55:46.572] boot - 5524 WARN [main] --- AnnotationConfigApplicationContext: Exception thrown from ApplicationListener handling ContextClosedEvent
java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.context.annotation.AnnotationConfigApplicationContext#562d4b: startup date [Thu Nov 26 10:55:46 IST 2015]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:337)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:324)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1025)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:988)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:329)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
at com.igate.MqttJavaApplication.main(MqttJavaApplication.java:32)
[2015-11-26 10:55:46.594] boot - 5524 WARN [main] --- AnnotationConfigApplicationContext: Exception thrown from LifecycleProcessor on context close
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: org.springframework.context.annotation.AnnotationConfigApplicationContext#562d4b: startup date [Thu Nov 26 10:55:46 IST 2015]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:350)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1033)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:988)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:329)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
at com.igate.MqttJavaApplication.main(MqttJavaApplication.java:32)
Exception in thread "main" java.lang.IllegalStateException: At least one base package must be specified
at org.springframework.context.annotation.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:121)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:214)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:149)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:135)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:260)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:203)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:617)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:446)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
at com.igate.MqttJavaApplication.main(MqttJavaApplication.java:32)

Yep! That's true. Without #SpringBootApplication I have the same StackTrace.
The Spring Boot stuff includes IntegrationAutoConfiguration who is responsible for subscribers and TaskScheduler bean population.

Probably too late to answer but hope it might help some beginner.
Few Things:-
Declare #SpringBootApplication in your main class to let the project know its a spring boot application
For the 2nd Error, Define base package of the project where spring boot will refer for configuration files etc. To do so, add #ComponentScan({"package-name"}) at class level.
Sample Example:-
#SpringBootApplication
#ComponentScan({"package-name"})
public class Main {
...
}

Related

Should Scheduled Task start a Spring application each time it is executed?

I'm running a spring boot application with a scheduled task. It is divided into two maven projects, lets call them 'lib' and 'app'.
The class whose method is annotated with #Scheduled is located in 'lib' project. It does not contain any classes annotated with #SpringBootApplication, or any classes that start a spring application. Here's what Scheduled bean looks like:
#Component
public class Refresher {
#Scheduled(fixedRate = 30000)
public void refresh() {
...
}
The 'lib' project also has a simple SchedulingConfigurer implementation that tells Spring to use ThreadPoolTaskScheduler with its Scheduled tasks.
The 'app' project, on the other hand, has a dependency on 'lib' and has a class annotated with #SpringBootApplication, and starts it as usual:
#SpringBootApplication(scanBasePackages = {"x.y", "x.y.z"})
#EnableScheduling
public class ExampleService {
public static void main(String[] args) {
SpringApplication.run(ExampleService.class, args);
}
}
Both maven projects have this:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/>
</parent>
So, when ExampleService starts I see it finds Refresher and executes its refresh method once every 30 sec alright, but something strange appears in the logs. When Example service starts, it prints:
2019-01-11 18:18:27.647 INFO 6428 --- [ main] x.y.z.ExampleService : Started ExampleService in 32.613 seconds (JVM running for 40.37)
This is great, it tells me that main application has started. But then I get the following lines every 30 seconds, every time Refresher gets executed:
2019-01-11 18:18:58.596 INFO 6428 --- [nio-8080-exec-3] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#66e31414: startup date [Fri Jan 11 18:18:58 MSK 2019]; root of context hierarchy
2019-01-11 18:18:58.637 INFO 6428 --- [nio-8080-exec-3] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$7c355e31] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
... some logging from the refresh() method
2019-01-11 18:19:01.020 INFO 6428 --- [nio-8080-exec-3] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#1262db58: startup date [Fri Jan 11 18:19:01 MSK 2019]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext#66e31414
2019-01-11 18:19:01.035 INFO 6428 --- [nio-8080-exec-3] o.s.boot.SpringApplication : Started application in 3.585 seconds (JVM running for 73.771)
2019-01-11 18:19:01.035 INFO 6428 --- [nio-8080-exec-3] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#1262db58: startup date [Fri Jan 11 18:19:01 MSK 2019]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext#66e31414
2019-01-11 18:19:01.035 INFO 6428 --- [nio-8080-exec-3] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#66e31414: startup date [Fri Jan 11 18:18:58 MSK 2019]; root of context hierarchy
Notice 'Started application in 3.585 seconds (JVM running for 73.771)'. This happens every 30 seconds. It looks like in order to run the Scheduled bean Spring runs a new separate Spring application every time. Why would it do that, and can this be avoided? Can Scheduled bean run as part of currently started Spring Boot app?

Not able to shutdown the jms listener which posts message to kafka spring boot application with Runtime.exit, context.close, System.exit()

I am developing a spring boot application which will listen to ibm mq with
#JmsListener(id="abc", destination="${queueName}", containerFactory="defaultJmsListenerContainerFactory")
I have a JmsListenerEndpointRegistry which starts the listenerContainer.
On message will try to push the same message with some business logic to kafka. The poster code is
kafkaTemplate.send(kafkaProp.getTopic(), uniqueId, message)
Now in case a kafka producer fails, I want my boot application to get terminated. So I have added a custom
setErrorHandler.
So I have tried
`System.exit(1)`, `configurableApplicationContextObject.close()`, `Runtime.getRuntime.exit(1)`.
But none of them work. Below is the log that gets generated after
System.exit(0) or above others.
2018-05-24 12:12:47.981 INFO 18904 --- [ Thread-4] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#1d08376: startup date [Thu May 24 12:10:35 IST 2018]; root of context hierarchy
2018-05-24 12:12:48.027 INFO 18904 --- [ Thread-4] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 2147483647
2018-05-24 12:12:48.028 INFO 18904 --- [ Thread-4] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 0
2018-05-24 12:12:48.028 INFO 18904 --- [ Thread-4] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
2018-05-24 12:12:48.028 INFO 18904 --- [ Thread-4] o.a.k.clients.producer.KafkaProducer : Closing the Kafka producer with timeoutMillis = 9223372036854775807 ms.
2018-05-24 12:12:48.044 INFO 18904 --- [ Thread-4] o.a.k.clients.producer.KafkaProducer : Closing the Kafka producer with timeoutMillis = 30000 ms.
But the application is still running and below are the running threads
Daemon Thread [Tomcat JDBC Pool Cleaner[14341596:1527144039908]] (Running)
Thread [DefaultMessageListenerContainer-1] (Running)
Thread [DestroyJavaVM] (Running)
Daemon Thread [JMSCCThreadPoolMaster] (Running)
Daemon Thread [RcvThread: com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection#12474910[qmid=*******,fap=**,channel=****,ccsid=***,sharecnv=***,hbint=*****,peer=*******,localport=****,ssl=****]] (Running)
Thread [Thread-4] (Running)
The help is much appreciated. Thanks in advance. I simply want the application should exit.
Below is the thread dump before I call System.exit(1)
"DefaultMessageListenerContainer-1"
java.lang.Thread.State: RUNNABLE
at sun.management.ThreadImpl.getThreadInfo1(Native Method)
at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:174)
at com.QueueErrorHandler.handleError(QueueErrorHandler.java:42)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeErrorHandler(AbstractMessageListenerContainer.java:931)
at org.springframework.jms.listener.AbstractMessageListenerContainer.handleListenerException(AbstractMessageListenerContainer.java:902)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:326)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:235)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1166)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1158)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1055)
at java.lang.Thread.run(Thread.java:745)
You should take a thread dump to see what Thread [DefaultMessageListenerContainer-1] (Running) is doing.
Now in case a kafka producer fails
What kind of failure? If the broker is down, the thread will block in the producer library for up to 60 seconds by default.
You can reduce that time by setting the max.block.ms producer property.
Couple of solutions which worked for me to solve above.
Solutions 1.
Get all threads in error handler and interrupt them all and then exist the system.
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds(), 100);
for (ThreadInfo threadInfo : threadInfos) {
Thread.currentThread().interrupt();
}
System.exit(1);
Solution 2. Define a application context manager. Like
public class AppContextManager implements ApplicationContextAware {
private static ApplicationContext _appCtx;
#Override
public void setApplicationContext(ApplicationContext ctx){
_appCtx = ctx;
}
public static ApplicationContext getAppContext(){
return _appCtx;
}
public static void exit(Integer exitCode) {
System.exit(SpringApplication.exit(_appCtx,() -> exitCode));
}
}
Then use same manager to exit in error handler
Executors.newSingleThreadExecutor().execute(new Runnable() {
public void run() {
jmsListenerEndpointRegistry.stop();
AppContextManager.exit(-1);
}
});

Camel jms route to IBM MQ immediately shuts down after successful test connection

I have used Camel a few times now but this problem is over my head and I have no clue what I'm doing wrong. It is a new application that should fetch messages from IBM MQ and place files to disk. The route is very simple:
String fromString = "message-queue:XXX.FUNDORDER.YYY.OUT?testConnectionOnStartup=true";
from(fromString)
.autoStartup(true)
.routeId("RouteReceiver")
.log("Processing message ${exchangeId}")
.to("file:/in?fileName=${exchangeId}.txt");
Here's the code used when creating the Connection factory:
public JmsConnectionFactory websphereConnectionFactory() throws JMSException
{
Logger logger = Logger.getLogger(Config.class);
logger.info("ibmMqChannel = " + ibmMqChannel);
logger.info("ibmMqHost = " + ibmMqHost);
logger.info("ibmMqPort = " + ibmMqPort);
logger.info("ibmMqQueueManagerName = " + ibmMqQueueManagerName);
/*
* Create MQConnectionFactory
*/
final MQConnectionFactory connectionFactory = new MQConnectionFactory();
connectionFactory.setHostName(ibmMqHost);
connectionFactory.setPort(ibmMqPort);
connectionFactory.setChannel(ibmMqChannel);
connectionFactory.setQueueManager(ibmMqQueueManagerName);
connectionFactory.setIntProperty(CommonConstants.WMQ_CONNECTION_MODE, CommonConstants.WMQ_CM_CLIENT);
logger.debug("connectionFactory=" + connectionFactory.toString());
/*
* Add ConnectionFactory to JmsConfiguration
*/
final JmsConfiguration jmsConfiguration = new JmsConfiguration();
jmsConfiguration.setConnectionFactory(connectionFactory);
/*
* Add JmsConfiguration to JmsComponent
*/
final JmsComponent jmsComponent = new JmsComponent();
jmsComponent.setConfiguration(jmsConfiguration);
jmsComponent.setAcknowledgementModeName("AUTO_ACKNOWLEDGE");
/*
* Add JmsComponent to camelContext
*/
camelContext.addComponent("message-queue", jmsComponent);
return connectionFactory;
}
Right after the application is started and connection is tested it immediately starts shutting down. No exceptions are thrown.
When testing locally I'm using a different profile and connects to an ActiveMQ server instead. This runs fine and does what it is supposed to.
Any help would be greatly appreciated!
/Katarina
Here's an extract of the log right before the route is shut down:
2018-01-23 12:13:05:501 o.a.camel.component.jms.JmsConsumer DEBUG - Successfully tested JMS Connection on startup for destination: MY.QUEUE.NAME
2018-01-23 12:13:05:501 o.a.camel.component.jms.JmsConsumer TRACE - Starting listener container org.apache.camel.component.jms.DefaultJmsMessageListenerContainer#7b02881e on destination MY.QUEUE.NAME
2018-01-23 12:13:05:532 o.a.c.c.j.DefaultJmsMessageListenerContainer DEBUG - Established shared JMS Connection
2018-01-23 12:13:05:532 o.a.c.u.c.CamelThreadFactory TRACE - Created thread[Camel (Client Robur messaging service) thread #1 - JmsConsumer[MY.QUEUE.NAME]] -> Thread[Camel (Client Robur messaging service) thread #1 - JmsConsumer[MY.QUEUE.NAME],5,main]
2018-01-23 12:13:05:547 o.a.c.c.j.DefaultJmsMessageListenerContainer DEBUG - Resumed paused task: org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker#503d687a
2018-01-23 12:13:05:547 o.a.camel.component.jms.JmsConsumer DEBUG - Started listener container org.apache.camel.component.jms.DefaultJmsMessageListenerContainer#7b02881e on destination MY.QUEUE.NAME
2018-01-23 12:13:05:547 o.a.camel.spring.SpringCamelContext INFO - Route: RouteReceiver started and consuming from: message-queue://MY.QUEUE.NAME?errorHandlerLoggingLevel=TRACE&jmsMessageType=Text&testConnectionOnStartup=true
2018-01-23 12:13:05:547 o.a.camel.support.ServiceSupport TRACE - Starting service
2018-01-23 12:13:05:547 o.a.camel.spring.SpringCamelContext INFO - Total 1 routes, of which 1 are started
2018-01-23 12:13:05:547 o.a.camel.spring.SpringCamelContext INFO - Apache Camel 2.20.1 (CamelContext: Client Robur messaging service) started in 5.974 seconds
2018-01-23 12:13:05:547 o.a.camel.spring.SpringCamelContext DEBUG - start() took 5974 millis
2018-01-23 12:13:05:563 o.a.camel.spring.SpringCamelContext DEBUG - onApplicationEvent: org.springframework.boot.context.event.ApplicationReadyEvent[source=org.springframework.boot.SpringApplication#53976f5c]
2018-01-23 12:13:05:563 se.tradechannel.IbmMqApplication INFO - Started IbmMqApplication in 37.347 seconds (JVM running for 39.742)
2018-01-23 12:13:05:563 se.tradechannel.IbmMqApplication INFO - Message Queue application started.
2018-01-23 12:13:05:563 o.a.c.c.j.DefaultJmsMessageListenerContainer TRACE - runningAllowed() -> true
2018-01-23 12:13:05:766 o.a.camel.spring.SpringCamelContext DEBUG - onApplicationEvent: org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext#621be5d1: startup date [Tue Jan 23 12:12:29 CET 2018]; root of context hierarchy]
2018-01-23 12:13:05:766 o.a.camel.spring.SpringCamelContext INFO - Apache Camel 2.20.1 (CamelContext: Client Robur messaging service) is shutting down
2018-01-23 12:13:05:766 org.apache.camel.util.ServiceHelper TRACE - Stopping service org.apache.camel.impl.DefaultRouteController#35e2d654
2018-01-23 12:13:05:766 org.apache.camel.util.ServiceHelper TRACE - Shutting down service org.apache.camel.impl.DefaultRouteController#35e2d654
2018-01-23 12:13:05:766 o.a.camel.support.ServiceSupport TRACE - Service already stopped
2018-01-23 12:13:05:766 o.a.c.impl.DefaultShutdownStrategy INFO - Starting to graceful shutdown 1 routes (timeout 300 seconds)
2018-01-23 12:13:05:766 o.a.c.m.DefaultManagementLifecycleStrategy TRACE - Checking whether to register org.apache.camel.util.concurrent.RejectableThreadPoolExecutor#279ccd56[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0][ShutdownTask] from route: null
2018-01-23 12:13:05:766 o.a.c.i.DefaultExecutorServiceManager DEBUG - Created new ThreadPool for source: org.apache.camel.impl.DefaultShutdownStrategy#1e800aaa with name: ShutdownTask. -> org.apache.camel.util.concurrent.RejectableThreadPoolExecutor#279ccd56[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0][ShutdownTask]
2018-01-23 12:13:05:766 o.a.c.u.c.CamelThreadFactory TRACE - Created thread[Camel (Client Robur messaging service) thread #2 - ShutdownTask] -> Thread[Camel (Client Robur messaging service) thread #2 - ShutdownTask,5,main]
2018-01-23 12:13:05:766 o.a.c.impl.DefaultShutdownStrategy DEBUG - There are 1 routes to shutdown
2018-01-23 12:13:05:766 o.a.c.impl.DefaultShutdownStrategy TRACE - Shutting down route: RouteReceiver with options [Default,CompleteCurrentTaskOnly]
2018-01-23 12:13:05:766 o.a.c.impl.DefaultShutdownStrategy TRACE - Suspending: Consumer[message-queue://MY.QUEUE.NAME?errorHandlerLoggingLevel=TRACE&jmsMessageType=Text&testConnectionOnStartup=true]
2018-01-23 12:13:05:766 org.apache.camel.util.ServiceHelper TRACE - Suspending service Consumer[message-queue://MY.QUEUE.NAME?errorHandlerLoggingLevel=TRACE&jmsMessageType=Text&testConnectionOnStartup=true]
2018-01-23 12:13:05:766 o.a.c.c.j.DefaultJmsMessageListenerContainer DEBUG - Stopping listenerContainer: org.apache.camel.component.jms.DefaultJmsMessageListenerContainer#7b02881e with cacheLevel: 3 and sharedConnectionEnabled: true
Are you using SpringBoot? If yes, is it possible that your application does not block and therefore simply shuts down after startup because the main method is done?
According to http://camel.apache.org/spring-boot.html there are many ways to block the main thread in a SpringBoot application (see Link for further details):
Your route class extends the org.apache.camel.spring.boot.FatJarRouter class
Use CamelSpringBootApplicationController.blockMainThread()
include the spring-boot-starter-web dependency in pom.xml
Set the property camel.springboot.main-run-controller to true in property or YAML file

resteasy ContainerRequestFilter didn't work in springboot

resteasy 3.1.3.Final and springboot 1.5.7
I want do somthing before the request go ino the restful method,but it never worked.
here is the restful method interface.
#Path("/demo")
#Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
#Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
public interface DemoService {
#POST
#Path("/query")
List<EntityDemoInfo> queryByType(QueryRequest requst);
}
Here is the filter.
#Provider
#PreMatching
public class RequestFilter implements HttpRequestPreprocessor,ContainerRequestFilter{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
System.out.println("-----------------");
}
#Override
public void preProcess(HttpRequest request) {
System.out.println("================");
}
}
It never go in the filter and print the log,even if i tried the annotations #Provider/#PreMatching/#Configuration in any combination.
Later i think maybe something registry problem,and tried to add #Bean in #SpringBootApplication class.This can print what I register,however when debugging request the registry/factory din't have my RequestFilter, thus it didn't work. What's wrong with it? thanks !
#Bean
public SynchronousDispatcher synchronousDispatcher() {
ResteasyProviderFactory providerFactory = ResteasyProviderFactory.getInstance();
RequestFilter requestFilter = new RequestFilter();
providerFactory.getContainerRequestFilterRegistry().registerSingleton(requestFilter);
SynchronousDispatcher dispatcher = new SynchronousDispatcher(providerFactory);
dispatcher.addHttpPreprocessor(requestFilter);
System.out.println("*****************");
System.out.println(providerFactory.getContainerRequestFilterRegistry().preMatch());
return dispatcher;
}
As 'paypal' codes do in https://github.com/paypal/resteasy-spring-boot , I added RequestFilter like Hantsy mentioned below, it didn't work!
Here is the log.
14:44:01.537 [main] INFO org.apache.tomcat.util.net.NioSelectorPool Using a shared selector for servlet write/read
14:44:01.548 [main] INFO org.jboss.resteasy.resteasy_jaxrs.i18n RESTEASY002225: Deploying javax.ws.rs.core.Application: class com.sample.app.JaxrsApplication
#################
################# ------This is what I add in JaxrsApplication
14:44:01.548 [main] INFO org.jboss.resteasy.resteasy_jaxrs.i18n RESTEASY002215: Adding singleton provider java.lang.Class from Application class com.sample.app.JaxrsApplication
14:44:01.554 [main] INFO org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer Tomcat started on port(s): 8080 (http)
14:44:01.559 [main] INFO com.sample.app.Application Started Application in 2.478 seconds (JVM running for 2.978)
//There is when i post a request as it say what happened,nothing,but got the response.Thus it didn't work!
14:45:58.657 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar$SpringApplicationAdmin Application shutdown requested.
14:45:58.657 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#34f22f9d: startup date [Fri Oct 20 14:43:59 CST 2017]; root of context hierarchy
14:45:58.659 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.context.support.DefaultLifecycleProcessor Stopping beans in phase 0
14:45:58.660 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter Unregistering JMX-exposed beans on shutdown
14:45:58.660 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter Unregistering JMX-exposed beans
14:45:58.660 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.jmx.export.annotation.AnnotationMBeanExporter Unregistering JMX-exposed beans on shutdown
The resteasy documentation provides simple guide for intgrating resteasy with Spring and Spring Boot. Hope these links are helpful.
Resteasy and Spring Integration
Spring Boot starter, described in the 43.4. Spring Boot starter section of the Resteasy doc.
If you are using Spring Boot as described in the doc, just register you custom Filter in your Application class.
#Component
#ApplicationPath("/sample-app/")
public class JaxrsApplication extends Application {
#Override
public Set<Object> getSingletons() {
Set<Object> singletons = new HashSet<>();
singletons.add(yourFilter);
return singletons;
}
}
Updated: I forked the paypal/resteasy-spring-boot, and modified the sample-app, added a EchoFitler for demo purpose.
Check the source codes from my Github account.
Run the sample-app via mvn spring-boot:run.
Use curl to test the apis.
# curl -v -X POST -H "Content-Type:text/plain" -H "Accept:application/json" http://localhost:8080/sample-app/echo -d "test"
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /sample-app/echo HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.56.0
> Content-Type:text/plain
> Accept:application/json
> Content-Length: 4
>
* upload completely sent off: 4 out of 4 bytes
< HTTP/1.1 200
< X-Application-Context: application
< Content-Type: application/json
< Content-Length: 45
< Date: Fri, 20 Oct 2017 07:19:43 GMT
<
{"timestamp":1508483983603,"echoText":"test"}* Connection #0 to host localhost left intact
And you will see the filtering info in the spring-boot console.
filtering request context:org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext#1ca8d1e4
filtering request/response context:org.jboss.resteasy.core.interception.jaxrs.ResponseContainerRequestContext#1787a18c
org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl#4aad828e
Hope this is helpful.

Why doesn't Wildfly give my application access to org.Hornetq (HornetQ's API)?

I really need help.
I have a simple Java Client (run by Eclipse, outside a container).
I have Wildfly 9 running on localhost.
And I have a simple MDB deployed as an ear package on Wildfly.
The Client does a JNDI lookup for "jms/RemoteConnectionFactory "
It get's and uses a HornetQJMSConnectionFactory.
It sends an ObjectMessage to the Queue that my MDB listens to.
The MDB's onMessage(Message msg) shows it receives the message.
And that msg is an instance of HornetQObjectMessage.
But when I try to cast msg to a HornetQObjectMessage, so I can retrieve the Object, it fails.
The core error seems to be NoClassDefFoundError for HornetQObjectMessage, so my application has no access to the HornetQ API (org.hornetq module I think).
Note: The Cast is in a try catch block, but there is no output to the Wildfly log from the my catch block?
I've pasted the MDB code below.
My module.xml
And and extract of the relevant lines from the Wildfly log.
Clearly the message arrives. See lines with "XXXXXXXXXX" prefix.
Then failure!
The ear has no war module.
Note: I added #ApplicationScoped only because it was suggested to solve an earlier problem I posted. Is that my problem now?
Please help.
MDB CODE:
#MessageDriven(
activationConfig ={
#ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
#ActivationConfigProperty(propertyName="maxSession",propertyValue="1"),
#ActivationConfigProperty(propertyName="destination", propertyValue="jms/goSendToServerQueue")
})
public class GoMsgBean implements MessageListener {
#ApplicationScoped
#Inject
#JMSConnectionFactory ("java:jboss/DefaultJMSConnectionFactory")
private JMSContext jmsCtx;
#Resource(name = "java:jboss/exported/jms/goSendToClientQueue")
private Queue sendToClientQueue;
public GoMsgBean () {
}
#PostConstruct
public void myInit () {
System.out.println("XXXXXXXXXX Post Construct - GoMsgBean");
}
#PreDestroy
public void myDestroy () {
System.out.println("XXXXXXXXXX Post Destroy - GoMsgBean");
}
public void onMessage(Message msg) {
System.out.println("XXXXXXXXXX Greetings From GoMsgBean.onMessage()");
System.out.println("XXXXXXXXXX Message Type is " + msg.getClass().getSimpleName());
try {
HornetQObjectMessage oMsg = (HornetQObjectMessage) msg;
System.out.println("XXXXXXXXXX Successfully Cast msg to HornetQObjectMessage");
System.out.println("XXXXXXXXXX Object Type is " + oMsg.getObject().getClass().getSimpleName());
} catch (ClassCastException e) {
System.out.println("XXXXXXXXXX ClassCastException");
} catch (JMSException e) {
System.out.println("XXXXXXXXXX JMSException ");
} catch (Exception e) {
System.out.println("XXXXXXXXXX " + e.getClass().getSimpleName()");
}
}
}
MODULE.XML
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.acmemq">
<dependencies>
<!-- we depend on org.hornetq module since we will send messages to -->
<!-- the HornetQ server embedded in the local WildFly instance -->
<module name="org.hornetq" />
</dependencies>
</module>
WILDFLY LOG (Extract of WARN and ERROR)
Calling "D:\Bulletproof\bpWildFly\bin\standalone.conf.bat"
Setting JAVA property to "C:\Program Files\Java\jdk1.8.0_05\bin\java"
===============================================================================
JBoss Bootstrap Environment
JBOSS_HOME: "D:\Bulletproof\bpWildFly"
JAVA: "C:\Program Files\Java\jdk1.8.0_05\bin\java"
JAVA_OPTS: "-Dprogram.name=standalone.bat -Xms64M -Xmx512M -XX:MaxPermSize=256M -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jbos
s.byteman"
===============================================================================
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256M; support was removed in 8.0
...
13:59:09,204 WARN [org.jboss.as.txn] (ServerService Thread Pool -- 60) WFLYTX0013: Node identifier property is set to the default value. Please make
sure it is unique.
13:59:09,880 INFO [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-6) WFLYJCA0001: Bound data source [java:jboss/datasources/ExampleDS]
13:59:09,994 WARN [org.jboss.as.messaging] (MSC service thread 1-6) WFLYMSG0001: AIO wasn't located on this platform, it will fall back to using pure
Java NIO.
13:59:10,010 INFO [org.jboss.as.server.deployment.scanner] (MSC service thread 1-1) WFLYDS0013: Started FileSystemDeploymentService for directory D:\
Bulletproof\bpWildFly\standalone\deployments
...
13:59:13,067 WARN [org.jboss.weld.Validator] (MSC service thread 1-8) WELD-001440: Scope type #javax.enterprise.context.ApplicationScoped() used on i
njection point [BackedAnnotatedField] #ApplicationScoped #Inject #JMSConnectionFactory private org.america3.gotest.server.messaging.GoMsgBean.jmsCtx
13:59:13,076 WARN [org.jboss.weld.Validator] (MSC service thread 1-8) WELD-001440: Scope type #javax.enterprise.context.ApplicationScoped() used on i
njection point [BackedAnnotatedField] #ApplicationScoped #Inject #JMSConnectionFactory private org.america3.gotest.server.messaging.GoMsgBean.jmsCtx
13:59:13,316 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 9.0.2.Final (WildFly Core 1.0.2.Final) started in 6207ms - Starte
d 480 of 676 services (264 services are lazy, passive or on-demand)
#START UP COMPLETED#
#MESSAGE RECEIVED#
14:01:04,983 INFO [stdout] (Thread-3 (HornetQ-client-global-threads-1527152166)) XXXXXXXXXX Post Construct - GoMsgBean
14:01:04,985 INFO [stdout] (Thread-3 (HornetQ-client-global-threads-1527152166)) XXXXXXXXXX Greetings From GoMsgBean.onMessage()
14:01:04,986 INFO [stdout] (Thread-3 (HornetQ-client-global-threads-1527152166)) XXXXXXXXXX Message Type is HornetQObjectMessage
14:01:04,987 INFO [stdout] (Thread-3 (HornetQ-client-global-threads-1527152166)) XXXXXXXXXX Post Destroy - GoMsgBean
14:01:04,989 ERROR [org.jboss.as.ejb3.invocation] (Thread-3 (HornetQ-client-global-threads-1527152166)) WFLYEJB0034: EJB Invocation failed on component GoMsgBean for method public void org.america3.gotest.server.messaging.GoMsgBean.onMessage(javax.jms.Message):javax.ejb.EJBTransactionRolledbackException: WFLYEJB0457: Unexpected Error
...
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: org/hornetq/jms/client/HornetQObjectMessage
...
... 52 more
Caused by: java.lang.ClassNotFoundException: org.hornetq.jms.client.HornetQObjectMessage from [Module "deployment.GoTest.ear.GoTest.jar:main" from Service Module Loader]
...
... 80 more
14:01:05,002 ERROR [org.hornetq.ra] (Thread-3 (HornetQ-client-global-threads-1527152166)) HQ154004: Failed to deliver message: javax.ejb.EJBTransactio
nRolledbackException: WFLYEJB0457: Unexpected Error
at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleInCallerTx(CMTTxInterceptor.java:153)
...
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: org/hornetq/jms/client/HornetQObjectMessage
...
... 52 more
Caused by: java.lang.ClassNotFoundException: org.hornetq.jms.client.HornetQObjectMessage from [Module "deployment.GoTest.ear.GoTest.jar:main" from Service Module Loader]
...
... 80 more

Resources