Skip to content

SimpAnnotationMethodMessageHandler fails when no applicationDestinationPrefixes configured or Rabbit endpoint present [SPR-13704] #18279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Nov 19, 2015 · 11 comments
Assignees
Labels
in: messaging Issues in messaging modules (jms, messaging) in: web Issues in web modules (web, webmvc, webflux, websocket) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

Juliusz Piwoński opened SPR-13704 and commented

There is unguarded access to first iterator element at: SimpAnnotationMethodMessageHandler.handleMatch
which causes NoSuchElementException in case no org.springframework.messaging.simp.config.MessageBrokerRegistry#setApplicationDestinationPrefixes is set.

Caused by: java.util.NoSuchElementException
	at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:713)
	at java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:734)
	at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1042)
	at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:471)
	at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:86)
	at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:426)
	at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:364)
	at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:135)
	... 3 more

Affects: 4.1.8, 4.2.3

Referenced from: commits 5549436, 4b27a6d, f119962, e8417ea

Backported to: 4.1.9

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Juliusz Piwoński, could you please give a recent 4.2.4.BUILD-SNAPSHOT and/or 4.1.9.BUILD-SNAPSHOT a try and let us know whether it works for you? The release is still two weeks away but I'd be great to verify upfront.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juliusz Piwoński commented

sure, just give me a while

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

No hurries - it'd just be great to verify ahead of the releases on Dec 15...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juliusz Piwoński commented

Hi Juergen,
sorry for delay. I've just checked the same scenario with version:

'org.springframework:spring-messaging:4.2.4.BUILD-SNAPSHOT',
'org.springframework:spring-context:4.2.4.BUILD-SNAPSHOT',

and it seems that NoSuchElementException is fixed.

But now I was hit by another exception (also while creating STOMP subscription):

2015-12-09 16:21:28.324 DEBUG [clientInboundChannel-4] .WebSocketAnnotationMethodMessageHandler : Searching methods to handle MethodArgumentNotValidException
2015-12-09 16:21:28.332 ERROR [clientInboundChannel-4] .WebSocketAnnotationMethodMessageHandler : Unhandled exception
org.springframework.messaging.handler.annotation.support.MethodArgumentNotValidException: Could not resolve method parameter at index 0 in method: public void com.example.SomeClass.processDeviceUpdate(org.springframework.amqp.core.Message) , with 1 error(s): [Error in object 'message': codes []; arguments []; default message [@Payload param is required]] 
	at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:101) ~[spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77) ~[spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:139) ~[spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:108) ~[spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMatch(AbstractMethodMessageHandler.java:490) [spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:484) [spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler.handleMatch(SimpAnnotationMethodMessageHandler.java:86) [spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessageInternal(AbstractMethodMessageHandler.java:451) [spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler.handleMessage(AbstractMethodMessageHandler.java:389) [spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at org.springframework.messaging.support.ExecutorSubscribableChannel$SendTask.run(ExecutorSubscribableChannel.java:135) [spring-messaging-4.2.4.BUILD-SNAPSHOT.jar:4.2.4.BUILD-SNAPSHOT]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_60]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_60]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]

What is important both exceptions (this one and the previous) don't break stomp functionality. Subscription message passed is handled by rabbit broker and works later on.
Another observation is when I remove RabbitListener code from my app (just for tests), the exception doesn't occur.

    @RabbitListener(queues = "someNotImportantQueueName")
    void processDeviceUpdate(Message message) {
...
}

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Thanks for the follow-up, I'll have a look at what happens there in PayloadArgumentResolver tonight...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

The error message is a bit misleading there: It indicates that the payload value was empty, which we do not accept by default. You may add @Payload(required=false) to accept an empty payload as well. However, I'm wondering which payload it is actually failing for in your case?

In any case, I'll make that error message clearer.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Hmm, aside from the misleading exception message, it looks like our STOMP endpoint dispatcher is getting confused with your Rabbit endpoint there... possibly due to @RabbitListener being meta-annotated with @MessageMapping itself. I'll see what we can do there.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

I've added an explicit check to ignore @MessageMapping annotations without any destinations specified, which is in particular the case when used as a meta-annotation on @RabbitListener or @JmsListener. This should avoid such mismatched dispatch attempts as the one you were seeing there, properly identifying actual STOMP endpoints.

The next 4.2.4.BUILD-SNAPSHOT will include those changes. Let me know whether you get proper results without any exceptions now...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Just to confirm my assumption: You have @RabbitListener methods and @MessageMapping methods mixed on a class that's marked as @Controller at the type level, right? In this case, the latest fix should hopefully sort it out now. If your scenario differs, please let me know...

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juliusz Piwoński commented

Just to confirm my assumption: You have @RabbitListener methods and @MessageMapping methods mixed on a class that's marked as @Controller
not exactly; there are no @MessageMapping at this Controller
just for tests I put the @RabbitListener into totally clean @Controller and exceptions were thrown; but changing @Controller into @Service helped.
\
\

The next 4.2.4.BUILD-SNAPSHOT will include those changes. Let me know whether you get proper results without any exceptions now...
yes, it works without any exceptions now :) thanks

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Ah ok, makes sense that way as well. When @RabbitListener / @JmsListener are declared on a @Controller bean, they would be accidentally found as STOMP endpoints along the same lines.

Good to hear that it works for you now :-)

Juergen

@spring-projects-issues spring-projects-issues added type: bug A general bug in: messaging Issues in messaging modules (jms, messaging) status: backported An issue that has been backported to maintenance branches in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 4.2.4 milestone Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: messaging Issues in messaging modules (jms, messaging) in: web Issues in web modules (web, webmvc, webflux, websocket) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants