Uploaded image for project: 'Seam 2'
  1. Seam 2
  2. JBSEAM-4094

SeamComponentPostProcessor.postProcessAfterInitialization returns null when Seam component name differs from Spring bean name

    Details

    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 2.1.1.GA
    • Fix Version/s: None
    • Component/s: Spring
    • Labels:
      None

      Description

      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.

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                ravan Ravan Naidoo
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated: