Skip to content
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

EventListenerMethodProcessor unconditionally instantiates certain beans, leading to BeanCreationException during deployment [SPR-13526] #18103

Closed
spring-projects-issues opened this issue Oct 1, 2015 · 5 comments
Assignees
Labels
in: core type: bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Oct 1, 2015

Piotr Findeisen opened SPR-13526 and commented

steps to reproduce
  1. Use <context:annotation-config />
    • this loads EventListenerMethodProcessor
  2. have a prototype bean "A" which uses @Transactional and expects constructor arguments to be provided using org.springframework.beans.factory.BeanFactory.getBean(String, Object...)
    • the bean doesn't need to use @EventListener
  3. start the context
expected
  • context starts
  • if "A" is the only bean (or if nothing uses "A"), the bean is not instantiated at all
observed
  1. EventListenerMethodProcessor wants to know whether "A" is annotated with @EventListener
    1. it calls applicationContext.getType("A")
      1. applicationContext (or rather InfrastructureAdvisorAutoProxyCreator) sees @Transactional ...
      2. ... so sth like A$$EnhancerBySpringCGLIB$$8e7e447 is returned
    2. EventListenerMethodProcessor.getTargetClass sees the bean class is kind of SpringProxy, so...
    3. it instantiates the bean, but obviously not providing required arguments to constructor

Affects: 4.2.1

Issue Links:

  • #18256 EventListener in a Request scoped bean fails context initialization
  • #18114 Spring incorrectly interprets a bean to be a spring eventlistener
  • #17619 EventListenerMethodProcessor resolves classes of lazy beans causing NoClassDefFoundError

Referenced from: commits dbec212

1 votes, 5 watchers

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 1, 2015

Piotr Findeisen commented

Even if the bean was possible to instantiate at this point, it just does not seem right to instantiate a bean just to check its type. The instantiation can read some configuration data form database and thus be expensive, etc.

Or, when world is not perfect and not everything is a bean, it may fail.

Or, if the bean is a singleton supposed to be exposed to non-Spring-world on a static field, the bean may check it's exposed at most once.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 2, 2015

Piotr Findeisen commented

Hi Juergen,

thanks for prioritizing this and scheduling for next release.

In the meantime, I found a workaround:

<bean id="org.springframework.context.event.internalEventListenerProcessor" class="java.lang.String">
	<constructor-arg value="Disable EventListenerMethodProcessor / @EventListener support
		due to #18103; TODO: remove once we're on Spring 4.2.2" />
</bean>

<!-- Now context:annotation-config won't register the EventListenerMethodProcessor -->
<context:annotation-config />

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 2, 2015

Stéphane Nicoll commented

You can register your own EventListenerMethodProcessor bean with name org.springframework.context.event.internalEventListenerProcessor that overrides afterSingletonInstantiated to do nothing and you should be fine.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 2, 2015

Piotr Findeisen commented

Thanks Stéphane,
that sounds ever better than my approach.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 6, 2015

Juergen Hoeller commented

It turns out that, overall, we don't really benefit from introspecting target classes behind proxies: We're only doing it for validation purposes, trying to find out whether the target class has an @EventListener annotation that gets suppressed through a non-annotated proxy interface. Since this is arguably something an IDE should be doing instead, we're simply not bothering anymore as of 4.2.2, always just looking at the proxy signature now (like in other places within the framework).

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core type: bug
Projects
None yet
Development

No branches or pull requests

2 participants