Occasional NullPointerException when publishing STOMP message using SpringFramework - spring-boot

I am running into some occasional NPE when publishing STOMP messages using Spring (5.2.0).
Unfortunately I cannot precisely provide the steps to reproduce but I was hoping to get some insight into how this could happen.
I looked into the source and the only thing I can think of is that the channel is null. I'm hoping to get a confirmation and possible reason for this, or an alternate explanation.
The client did not disconnect but it seems like this error causes the client to disconnect as it receives a 1002 code.
Attached is the stacktrace. Any help or insight would be greatly appreciated. Thanks!
org.springframework.messaging.MessageDeliveryException: Failed to send message to ExecutorSubscribableChannel[clientInboundChannel]; nested exception is java.lang.NullPointerException
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:146)
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:122)
at org.springframework.web.socket.messaging.StompSubProtocolHandler.handleMessageFromClient(StompSubProtocolHandler.java:302)
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.handleMessage(SubProtocolWebSocketHandler.java:335)
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75)
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.handleMessage(LoggingWebSocketHandlerDecorator.java:56)
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.handleMessage(ExceptionWebSocketHandlerDecorator.java:58)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleTextMessage(StandardWebSocketHandlerAdapter.java:114)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access$000(StandardWebSocketHandlerAdapter.java:43)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:85)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:82)
at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:395)
at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:119)
at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:495)
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:294)
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133)
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:82)
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171)
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148)
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: null
at org.springframework.messaging.support.AbstractMessageChannel$ChannelInterceptorChain.applyPreSend(AbstractMessageChannel.java:178)
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:132)
... 28 common frames omitted```

Not related to this problem; but you should try to keep up with maintenance releases; the current 5.2.x version is 5.2.6.
That NPE implies you have somehow ended up with a null in the interceptor list.
Line 178 in the abstract channel is invoking each interceptor in the list.
https://github.com/spring-projects/spring-framework/blob/927b8c15ef20eaaa4002d4b2170cc536a6d6aa35/spring-messaging/src/main/java/org/springframework/messaging/support/AbstractMessageChannel.java#L178
I think the only way you can get an NPE there is if you have (or something has) added null to the list.
for (ChannelInterceptor interceptor : interceptors) {
Message<?> resolvedMessage = interceptor.preSend(messageToUse, channel); // line 178
if (resolvedMessage == null) {
...

Related

SpringBoot Camel (3.14.0) and ElasticSearch Integration

I'm trying to integrate Spring Boot (2.6.3) with Camel (3.14.0) to send a simple query to ElasticSearch.
The project is located at https://github.com/saavedrah/springboot-camel-elastic
I have a timer that sends a ElasticSearch query every 60 sec.
However, the following exception is generated:
2022-01-26 11:08:48.036 WARN 23668 --- [1 - timer://foo] o.a.camel.component.timer.TimerConsumer : Error processing exchange. Exchange[2578AAA06ED30CB-0000000000000000]. Caused by: [org.apache.camel.CamelExecutionException - Exception occurred during execution on the exchange: Exchange[]]
org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[]
at org.apache.camel.CamelExecutionException.wrapCamelExecutionException(CamelExecutionException.java:45) ~[camel-api-3.14.0.jar:3.14.0]
at org.apache.camel.support.AbstractExchange.setException(AbstractExchange.java:589) ~[camel-support-3.14.0.jar:3.14.0]
at org.apache.camel.support.DefaultExchange.setException(DefaultExchange.java:27) ~[camel-support-3.14.0.jar:3.14.0]
at org.apache.camel.support.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:69) ~[camel-support-3.14.0.jar:3.14.0]
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:172) ~[camel-core-processor-3.14.0.jar:3.14.0]
at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:469) ~[camel-core-processor-3.14.0.jar:3.14.0]
at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:187) ~[camel-base-engine-3.14.0.jar:3.14.0]
at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:64) ~[camel-base-engine-3.14.0.jar:3.14.0]
at org.apache.camel.processor.Pipeline.process(Pipeline.java:184) ~[camel-core-processor-3.14.0.jar:3.14.0]
at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:398) ~[camel-base-engine-3.14.0.jar:3.14.0]
at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:210) ~[camel-timer-3.14.0.jar:3.14.0]
at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:76) ~[camel-timer-3.14.0.jar:3.14.0]
at java.base/java.util.TimerThread.mainLoop(Timer.java:556) ~[na:na]
at java.base/java.util.TimerThread.run(Timer.java:506) ~[na:na]
Caused by: java.lang.NoClassDefFoundError: org/elasticsearch/common/CheckedConsumer
at org.apache.camel.component.elasticsearch.ElasticsearchProducer$HighLevelClient.<init>(ElasticsearchProducer.java:347) ~[camel-elasticsearch-rest-3.14.0.jar:3.14.0]
at org.apache.camel.component.elasticsearch.ElasticsearchProducer$HighLevelClient.<init>(ElasticsearchProducer.java:345) ~[camel-elasticsearch-rest-3.14.0.jar:3.14.0]
at org.apache.camel.component.elasticsearch.ElasticsearchProducer.process(ElasticsearchProducer.java:124) ~[camel-elasticsearch-rest-3.14.0.jar:3.14.0]
at org.apache.camel.support.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:66) ~[camel-support-3.14.0.jar:3.14.0]
... 10 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.common.CheckedConsumer
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
... 14 common frames omitted
UPDATE 1
Accordingly with this site CAMEL-17183 the downloaded version of ElasticSearch (7.15.2) does not have the [org.elasticsearch.common.CheckedConsumer] class.
So, how should I update the gradle.properties to get the supported version of ElasticSearch(7.8.0) ?
UPDATE 2
Gradle properties was updated to force the version of ElasticSearch.
configurations.all {
resolutionStrategy {
dependencySubstitution {
substitute module('org.elasticsearch.client:elasticsearch-rest-high-level-client') with module('org.elasticsearch.client:elasticsearch-rest-high-level-client:7.8.0')
substitute module('org.elasticsearch.client:elasticsearch-rest-client') with module('org.elasticsearch.client:elasticsearch-rest-client:7.8.0')
substitute module('org.elasticsearch:elasticsearch') with module('org.elasticsearch:elasticsearch:7.8.0')
}
}
}
And now I'm getting the following exception, I guess it is related with the lack of parameters passed to the query...
java.lang.IllegalArgumentException: Wrong body type. Only Map, String or SearchRequest is allowed as a type
at org.apache.camel.component.elasticsearch.ElasticsearchProducer.process(ElasticsearchProducer.java:232)
at org.apache.camel.support.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:66)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:172)
at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:469)
at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:187)
at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:64)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:184)
at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:398)
at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:210)
at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:76)
at java.base/java.util.TimerThread.mainLoop(Timer.java:556)
at java.base/java.util.TimerThread.run(Timer.java:506)
13:13:25.219 [Camel (camel-1) thread #1 - timer://foo] WARN o.a.c.component.timer.TimerConsumer - Error processing exchange. Exchange[DB28E010007B18C-0000000000000006]. Caused by: [java.lang.IllegalArgumentException - Wrong body type. Only Map, String or SearchRequest is allowed as a type]
java.lang.IllegalArgumentException: Wrong body type. Only Map, String or SearchRequest is allowed as a type
at org.apache.camel.component.elasticsearch.ElasticsearchProducer.process(ElasticsearchProducer.java:232)
at org.apache.camel.support.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:66)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:172)
at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:469)
at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:187)
at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:64)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:184)
at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:398)
at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:210)
at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:76)
at java.base/java.util.TimerThread.mainLoop(Timer.java:556)
at java.base/java.util.TimerThread.run(Timer.java:506)
Any help is appreciated.
What Huang was telling me was that I should put some query in my timer component body to pass it to the Search operation, something like:
from("timer://foo?fixedRate=true&period=60000")
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
exchange.getIn().setBody("{\"query\":{\"match_all\":{}}}");
}
})
.to("direct:search");
from("direct:search")
.to("elasticsearch-rest://elasticsearch?operation=Search&indexName=twitter");
Thank you.

Kotlin based Spring RabbitListener produces endlessloop trying to send back `kotlin.Unit`

We have a RabbitListener implemented in Kotlin. The method returns Unit, so I dont expect Spring to send a result but we are getting the following error message. It looks like Spring tries to iterprete Unit as the result and send a rabbit message back:
2021-04-16 16:39:21
msg="Execution of Rabbit message listener failed." thread="org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-2" level=WARN logger="org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler" exception="org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Listener threw exception
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:1746)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1636)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1551)
at jdk.internal.reflect.GeneratedMethodAccessor64.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at brave.spring.rabbit.TracingRabbitListenerAdvice.invoke(TracingRabbitListenerAdvice.java:108)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at org.springframework.amqp.rabbit.listener.$Proxy146.invokeListener(Unknown Source)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1539)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1530)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1474)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:967)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1288)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1194)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.amqp.rabbit.listener.adapter.ReplyFailureException: Failed to send reply with payload 'InvocationResult [returnValue=kotlin.Unit, returnType=class java.lang.Object, bean=com.xxx.EventHandler#4aaf6902, method=public java.lang.Object com.xxx.EventHandler.receiveMessage(org.springframework.amqp.core.Message)]'
at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.doHandleResult(AbstractAdaptableMessageListener.java:476)
at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.handleResult(AbstractAdaptableMessageListener.java:400)
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandlerAndProcessResult(MessagingMessageListenerAdapter.java:152)
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:135)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1632)
... 20 common frames omitted
Caused by: java.lang.IllegalArgumentException: SimpleMessageConverter only supports String, byte[] and Serializable payloads, received: kotlin.Unit
at org.springframework.amqp.support.converter.SimpleMessageConverter.createMessage(SimpleMessageConverter.java:164)
at org.springframework.amqp.support.converter.AbstractMessageConverter.createMessage(AbstractMessageConverter.java:88)
at org.springframework.amqp.support.converter.AbstractMessageConverter.toMessage(AbstractMessageConverter.java:70)
at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.convert(AbstractAdaptableMessageListener.java:519)
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.buildMessage(MessagingMessageListenerAdapter.java:257)
at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.doHandleResult(AbstractAdaptableMessageListener.java:464)
... 24 common frames omitted
" time="2021-04-16 14:39:21,726"
here a simplified version of the RabbitLister:
#Component
class EventHandler {
#RabbitListener(queues = ["someQueue"])
fun receiveMessage(message: Message): Unit {
log.debug("Received message")
}
}
We use Spring Boot 2.4.4, Spring Rabbit 2.3.6 and Spring Framework 5.3.6
debugging the issue, I got the following result:
What version are you using?
This works fine for me (with and without the Unit return type)...
#RabbitListener(queues = ["foo"])
open fun listen(data: String?): Unit {
println(data)
}
Even with : Unit, I see void as the return type and null:

grcp failure while posting in etcd via spring boot

I'm running a simple etcd connection with springbok example. I keep getting an error w.r.t grcp in both my spring boot logs and server logs. How can I fix this?
#Scheduled(fixedRate = 5000)
public void test() throws EtcdException, ExecutionException, InterruptedException {
// create client
Client client = Client.builder().endpoints("http://localhost:2379").build();
KV kvClient = client.getKVClient();
ByteSequence key = ByteSequence.fromBytes("test_key".getBytes());
ByteSequence val = ByteSequence.fromBytes("test_val".getBytes());
// put the key-value
kvClient.put(key, val);
// get the CompletableFuture
CompletableFuture<GetResponse> getFuture = kvClient.get(key);
// get the value from CompletableFuture
GetResponse response = getFuture.get();
System.out.println(response.toString());
}
Error
.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]
Caused by: java.util.concurrent.ExecutionException: io.grpc.StatusRuntimeException: INTERNAL: Connection closed with unknown cause
at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:476) ~[guava-19.0.jar:na]
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:455) ~[guava-19.0.jar:na]
at com.coreos.jetcd.internal.impl.Util.lambda$toCompletableFutureWithRetry$1(Util.java:125) ~[jetcd-core-0.0.1.jar:na]
... 3 common frames omitted
Caused by: io.grpc.StatusRuntimeException: INTERNAL: Connection closed with unknown cause
at io.grpc.Status.asRuntimeException(Status.java:526) ~[grpc-core-1.5.0.jar:1.5.0]
at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:427) ~[grpc-stub-1.5.0.jar:1.5.0]
at io.grpc.ForwardingClientCallListener.onClose(ForwardingClientCallListener.java:41) ~[grpc-core-1.5.0.jar:1.5.0]
at com.coreos.jetcd.internal.impl.ClientConnectionManager$AuthTokenInterceptor$1$1.onClose(ClientConnectionManager.java:267) ~[jetcd-core-0.0.1.jar:na]
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:419) ~[grpc-core-1.5.0.jar:1.5.0]
at io.grpc.internal.ClientCallImpl.access$100(ClientCallImpl.java:60) ~[grpc-core-1.5.0.jar:1.5.0]
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:493) ~[grpc-core-1.5.0.jar:1.5.0]
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$500(ClientCallImpl.java:422) ~[grpc-core-1.5.0.jar:1.5.0]
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:525) ~[grpc-core-1.5.0.jar:1.5.0]
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) ~[grpc-core-1.5.0.jar:1.5.0]
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:102) ~[grpc-core-1.5.0.jar:1.5.0]
... 3 common frames omitted
At ETCD server
WARNING: 2020/04/16 00:23:15 grpc: Server.processUnaryRPC failed to write status: connection error: desc = "transport is closing"
Tried setting the keep alive property but didn't work
grpc.client.GLOBAL.keep-alive-time=5000
So it turns out that the grcp version was the reason, I was using verion 1.5.0 but when I moved to version 1.9.0, the issue was resolved for me.

No converter found to convert to interface javax.jms.TextMessage

I am running a spring boot application that connects to activeMQ as a consumer from my Spring STS environment. I then run my camel blueprint from my JBoss Developer Studio app.
Here's the code from my listener:
#JmsListener(destination = '${tripRequest.updateStatus.destination}')
void handle(TextMessage message) {
When the message hits the consumer, I get the following exception:
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method could not be invoked with incoming message
Endpoint handler details:
Method [public void com.xxx.trip.request.messaging.status.TripRequestUpdateStatusListener.handle(javax.jms.TextMessage)]
Bean [com.xxx.trip.request.messaging.status.TripRequestUpdateStatusListener#1a99744a]
; nested exception is org.springframework.messaging.converter.MessageConversionException: No converter found to convert to interface javax.jms.TextMessage, message=GenericMessage [payload=byte[197], headers={CamelFileLastModified=1466448102155, CamelFileParent=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data, CamelFilePath=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data\one.json, CamelFileLength=22, jms_destination=queue://tripRequest.updateStatus.v1.0, jms_priority=4, CamelFileAbsolute=true, jms_timestamp=1466631945834, CamelFileName=one.json, jms_redelivered=false, jms_deliveryMode=2, CamelFileNameConsumed=one.json, breadcrumbId=ID-ThomasLaptop-55017-1466631942306-0-1, jms_replyTo=temp-queue://ID:ThomasLaptop-55022-1466631945608-1:1:1, CamelFileRelativePath=one.json, jms_correlationId=Camel-ID-ThomasLaptop-55017-1466631942306-0-3, id=3c38a185-44c7-4df2-fefb-1f3320e0262f, CamelFileAbsolutePath=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data\one.json, jms_expiration=1466631965834, jms_messageId=ID:ThomasLaptop-55022-1466631945608-1:1:2:1:1, CamelFileNameOnly=one.json, timestamp=1466631945924}]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:94) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:66) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:721) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:681) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:315) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1158) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1150) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1047) [spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_91]
Caused by: org.springframework.messaging.converter.MessageConversionException: No converter found to convert to interface javax.jms.TextMessage, message=GenericMessage [payload=byte[197], headers={CamelFileLastModified=1466448102155, CamelFileParent=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data, CamelFilePath=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data\one.json, CamelFileLength=22, jms_destination=queue://tripRequest.updateStatus.v1.0, jms_priority=4, CamelFileAbsolute=true, jms_timestamp=1466631945834, CamelFileName=one.json, jms_redelivered=false, jms_deliveryMode=2, CamelFileNameConsumed=one.json, breadcrumbId=ID-ThomasLaptop-55017-1466631942306-0-1, jms_replyTo=temp-queue://ID:ThomasLaptop-55022-1466631945608-1:1:1, CamelFileRelativePath=one.json, jms_correlationId=Camel-ID-ThomasLaptop-55017-1466631942306-0-3, id=3c38a185-44c7-4df2-fefb-1f3320e0262f, CamelFileAbsolutePath=C:\Users\Thom\git\brms-poc-esb\rule-cancel\data\one.json, jms_expiration=1466631965834, jms_messageId=ID:ThomasLaptop-55022-1466631945608-1:1:2:1:1, CamelFileNameOnly=one.json, timestamp=1466631945924}]
at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:118) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:98) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:138) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:107) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:90) ~[spring-jms-4.2.5.RELEASE.jar:4.2.5.RELEASE]
... 10 common frames omitted
I know for a fact that we have tested this with text messages sent from another application and this message works fine. I don't understand why it fails from my camel route. When I look at the message, it appears to be well-formed XML. Here it is:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tripRequestUpdateStatus>
<id>1</id>
<status>Approved</status>
<updatedBy source="lgtc">1</updatedBy>
</tripRequestUpdateStatus>
Why does it need converted in the first place when I'm sending text? Why is conversion failing?
I guess you created a new question after you found out something, but forgot to mention this in this question: How to send text message instead of byte message
You send the messages as byte payload so the JMS consumer receives the message payload as a javax.jms.BytesMessage which Spring Integration is not able to convert to a javax.jms.TextMessage. So you can change your code to use a javax.jms.BytesMessage instead. Or have the sender send the JMS messages as Text based instead of Bytes.

Spring Integration: HTTP Inbound Gateway - using JSON to Object transformer for HashMap

I am trying to setup a Spring Integration based Restful service. I am trying to avoid creating individual objects for request and response but instead use a HashMap for simple functions such as isUserAvailableForRegistration at service.
e.g
HashMap<String, String> isUserAvailableForRegistration(HashMap<String,String> request)
The following is the integration related context information:
<bean class="org.springframework.integration.http.inbound.UriPathHandlerMapping"/>
<int-http:inbound-gateway id="inboundGateway"
request-channel="incoming" reply-channel="outgoing"
supported-methods="POST" reply-timeout="5000"
path="/customer/isUserAvailable" />
<int:channel id="incoming" />
<int:channel id="outgoing" />
<int:service-activator id="activator" input-channel="incoming" ref="customerManagementGateway"
method="isUserAvailableForRegistration" output-channel="outgoing" requires-reply="true" />
<int:object-to-json-transformer id="outgoingJsonConverter"
input-channel="outgoing" />
<int:json-to-object-transformer id="incomingJsonConverter" input-channel="incoming" type="java.util.HashMap" />
While I can successfully test that I could marshall HashMap to JSON successfully, I am missing the configuration to unmarshall JSON data into HashMap.
I get the following exception:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.integration.dispatcher.AggregateMessageDeliveryException: All attempts to deliver Message to MessageHandlers failed. Multiple causes:
failed to transform message
org.springframework.expression.AccessException: Problem invoking method: public java.util.Map com.testapp.customer.CustomerManagementServiceActivator.isUserAvailableForRegistration(java.util.Map)
See below for the stacktrace of the first cause.
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
root cause
org.springframework.integration.dispatcher.AggregateMessageDeliveryException: All attempts to deliver Message to MessageHandlers failed. Multiple causes:
failed to transform message
org.springframework.expression.AccessException: Problem invoking method: public java.util.Map com.testapp.customer.CustomerManagementServiceActivator.isUserAvailableForRegistration(java.util.Map)
See below for the stacktrace of the first cause.
org.springframework.integration.dispatcher.UnicastingDispatcher.handleExceptions(UnicastingDispatcher.java:164)
org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:127)
org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:101)
org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:61)
org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
org.springframework.integration.core.MessagingTemplate.doSendAndReceive(MessagingTemplate.java:318)
org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:239)
org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:233)
org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:207)
org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:378)
org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:95)
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
root cause
org.springframework.integration.transformer.MessageTransformationException: failed to transform message
org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:44)
org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:67)
org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:97)
org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:114)
org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:101)
org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:61)
org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
org.springframework.integration.core.MessagingTemplate.doSendAndReceive(MessagingTemplate.java:318)
org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:239)
org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:233)
org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:207)
org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:378)
org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:95)
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
root cause
java.lang.ClassCastException: [B cannot be cast to java.lang.String
org.springframework.integration.json.JsonToObjectTransformer.transformPayload(JsonToObjectTransformer.java:30)
org.springframework.integration.transformer.AbstractPayloadTransformer.doTransform(AbstractPayloadTransformer.java:33)
org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:33)
org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:67)
org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:97)
org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:114)
org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:101)
org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:61)
org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
org.springframework.integration.core.MessagingTemplate.doSendAndReceive(MessagingTemplate.java:318)
org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:239)
org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:233)
org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:207)
org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:378)
org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:95)
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Can anybody help me with figuring out what could possible be wrong ?
I have double checked the headers, hence i am sure that I it's something with the configuration or Jackson's support for unmarshalling to HashMap. Thanks for your time.
As Biju mentioned the integration graph wasnt correct, but the error was thrown even before the message reached json-to-object-transformer. After fixing the integration graph correctly i still was getting this error. after searching in spring integration forum, i found that mentioning request-payload-type in the int-http:inbound-gateway gateway solved the problem.
So the correct configuration is
<int-http:inbound-gateway id="inboundGateway"
request-channel="incoming" reply-channel="outgoing"
supported-methods="POST" reply-timeout="5000"
path="/customer/isUserAvailable" request-payload-type="String" />
Doesn't look like you have connected the different endpoints and channels correctly -
This is the flow that you have:
httpgateway->incoming(c)->customerManagementGateway->outgoing(c)->outgoingJsonConverter
->incomingJsonConverter
Both incomingJsonConverter and customerManagementGateway seem to be consuming off incoming channel
This may not be the main reason for the error message though, I think you need to convert the byte array to a String payload for the json transformer: try introducing this transformer also between your inputchannel and jsonconverter:
JsonToObjectTransformer:
<int:object-to-string-transformer input-channel="in" output-channel="out"/>

Resources