Skip to content

Wrong detection of event type on ApplicationListener<> when using lambdas (ClassCast Exception) [SPR-14109] #18681

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 Apr 4, 2016 · 7 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) in: messaging Issues in messaging modules (jms, messaging) in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Apr 4, 2016

Michael Simons opened SPR-14109 and commented

Hello there,

i hope this is indeed a Spring Framework and not a Spring Boot bug. If not, please excuse and move it to the right place.

In my application i have a WebSocketMessageBroker (enabled through @EnableWebSocketMessageBroker) as well as a HttpSessionEventPublisher (enabled via @Bean) and a ApplicationListener<HttpSessionCreatedEvent>.

If i use an anonymous inner class for the ApplicationListener, everything works fine.

If i use a lambda like so

public ApplicationListener<HttpSessionCreatedEvent> httpSessionCreatedEventListener() {
  return (HttpSessionCreatedEvent event) -> {
    LoggerFactory.getLogger(ClasscastApplication.class).info("Session created...");
  };
}

the generic type of my listener is incorrectly identified and a BrokerAvailabilityEvent is passed to it leading to:

Caused by: java.lang.ClassCastException: org.springframework.messaging.simp.broker.BrokerAvailabilityEvent cannot be cast to org.springframework.security.web.session.HttpSessionCreatedEvent
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:163) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:136) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:381) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:335) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler.publishBrokerAvailableEvent(AbstractBrokerMessageHandler.java:262) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler.startInternal(SimpleBrokerMessageHandler.java:178) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler.start(AbstractBrokerMessageHandler.java:164) ~[spring-messaging-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
	... 14 common frames omitted

I guess that might happen with other events, too, but i noticed it in context of messaging.

I have attached a demo application that reproduces that bug.


Affects: 4.2.5

Attachments:

Issue Links:

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

This is unfortunately a known limitation with lambda-defined callbacks: We cannot reliably introspect generic type declarations there upfront. That said, we should at least make our event processing defensive enough: catching ClassCastException and simply skipping the listener if the event doesn't match... I'll try that right away.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Apr 4, 2016

Michael Simons commented

Hello Juergen,
thanks for looking into it so quickly.

Sorry, didn't find the other ticket.

If you skip the listener, a big warning is need, i think.
Or: Throw a custom exception with the reason and explanation.

Just for your interest: We've been using TypeTools which are linked in the SO question in #17130 for detecting generic types of Lambdas successfully.

Thanks again,
Michael.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Skipping the listener in case of a ClassCastException should actually be reasonably safe: It just means that we were trying to invoke it with a non-matching event type which, if known upfront, would have to led to the listener getting skipped in any case...

@spring-projects-issues
Copy link
Collaborator Author

Michael Simons commented

Thanks for clarifying, now i understand, i thought you meant skipping that listener from being registered at all.

@spring-projects-issues
Copy link
Collaborator Author

Hans-Peter Werner commented

Hello Juergen,

I try to catch and log exceptions at the site where an event is fired. When a listener is throwing a ClassCastException, this happens without being noticed (provided the log-level is not debug) because of that exception being catched within the SimpleApplicationEventMulticaster. I don't know a perfect solution for that problem, but I would rather have too much exceptions than too few :)

Cheers
hp

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

As of 4.3.4 / 4.2.9, we're now just swallowing a ClassCastException if it affects the passed-in event class directly (as in the case of a lambda-defined listener for a specific event type).

@spring-projects-issues
Copy link
Collaborator Author

Michael Simons commented

Thanks Jürgen for the update. Good to know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) in: messaging Issues in messaging modules (jms, messaging) in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants