SeamComponentPostProcessor.postProcessAfterInitialization returns null when Seam component
name differs from Spring bean name
-----------------------------------------------------------------------------------------------------------------------------
Key: JBSEAM-4094
URL:
https://jira.jboss.org/jira/browse/JBSEAM-4094
Project: Seam
Issue Type: Bug
Components: Spring
Affects Versions: 2.1.1.GA
Reporter: Ravan Naidoo
Given the following Spring xml :
<bean id="fooBarBean" class="....">
<seam:component name="fooBarSeam" intercept="false"/>
</bean>
SeamComponentPostProcessor.postProcessAfterInitialization() returns null when the Seam
component name differs from the Spring bean name.
This results in a null reference in the Spring Context for bean name
"fooBarBean" and indirectly a null Seam Component.
SeamComponentPostProcessor.postProcessAfterInitialization() uses the
SpringComponent.forSpringBeanName() to identify if a Spring bean (fooBarBean) is a Seam
Component.
When true, it proceeds to instruct the Component.getInstance() to wrap the bean so that it
can be managed by Seam.
At this point the SeamComponentPostProcessor passes the Spring bean name (fooBarBean) to
the getInstance method instead of the Seam component name (fooBarSeam). The method cannot
find the Seam component and returns a null.
Unfortunately, my unit test did not pick up this problem due to the fact that the
SeamComponentPostProcessor sets a threadlocal ObjectFactory with a direct reference to the
bean as instantiated by Spring. So during the execution of the test, the
SpringComponent.instanciateIoCBean() used the threadlocal ObjectFactory to get a reference
to the bean. In my deployed application, initialization and requests occur in different
threads.
In that case, the ObjectFactory is null and the Spring BeanFactory is asked for the
reference. Which is now null due to the SeamComponentPostProcessor.
Another interesting side affect of the above naming problem in combination with the
threadlocal ObjectFactory mechanism, was that when I defined 2 Spring beans as Seam
components :
<bean id="fooBarBean" class="....">
<seam:component/>
</bean>
<bean id="someOtherBean" class="....">
<seam:component name="someOtherBeanSeam"
intercept="false"/>
</bean>
Then tried Component.getInstance("fooBarBean"), I got the following exception :
"java.lang.AssertionError: javax.el.ELException: java.lang.IllegalArgumentException:
value of context variable is not an instance of the component bound to the context
variable: fooBarBean. If you are using hot deploy, you may have attempted to hot deploy a
session or application-scoped component definition while using an old instance in the
session."
Swapping the order in the xml resolve eliminates the exception.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira