4 Replies Latest reply on Jul 15, 2008 4:35 PM by alesj

    Bean destroy methods when undeploying

    tkyung

      Hi:

      I am using jboss 4.2. I just started using the jboss spring deployer to deploy my spring application. Some of the spring beans my application are configured with destroy-method callback as described here (http://static.springframework.org/spring/docs/2.0.x/reference/beans.html#beans-factory-lifecycle-disposablebean).

      When I shutdown jboss, I see in the log that there is a line about destroying the singleton beans:
      2008-07-14 11:28:19,418 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@17c7988: defining beans [<my app beans>]

      But I don't think the destroy methods of the beans are invoked (added some log messages but they didn't show up in the log).

      How should I configure my app for the spring deployer to call the lifecycle methods like init and destroy?

      Thanks,

      Ken

        • 1. Re: Bean destroy methods when undeploying
          alesj

          I think this should already be taken care by Spring.
          JBossSpringDeployer doesn't have anything to do with beans lifecycle, except from instantiating/destroying AppContext/BeanFactory.

          The only reason I could think of is that you're using SpringBeanFactoryDeployer which only creates BeanFactory instance, not ApplicationContext instance.
          AFAIK it's only AppContext impl that handles init/destroy, but I could be wrong.

          • 2. Re: Bean destroy methods when undeploying
            alesj

             

            "tkyung" wrote:

            But I don't think the destroy methods of the beans are invoked (added some log messages but they didn't show up in the log).

            Which log level did you use?
            Try throwing some exception just to make sure. :-)


            • 3. Re: Bean destroy methods when undeploying
              tkyung

              I checked the mbean defined in the spring deployer and it is using SpringApplicationContextDeployer. Then I threw an exception inside one of the bean's destroy method and it showed up, so after all the destroy method is being called, just that I didn't set up my log correctly. Thanks for the pointers!

              Then I noticed the deployed app is registered in JNDI, so I went further to deploy two spring apps (app1 and app2), where in app2 I refer to the app1's context using jndi, like this in app2's applicationContext.xml:

              <bean id="app1Context" class="org.springframework.jndi.JndiObjectFactoryBean">
               <property name="jndiName" value="app1"/>
               <property name="expectedType" value="org.springframework.context.support.AbstractApplicationContext"/>
               </bean>
              

              The issue is, when I shutdown jboss, I see the message "Failed to stop bean factory app2", and if I remove this bean, the app can be undeployed without failing. It also works if I make this bean prototype scope instead of a singleton. Is there a downside for making this a prototype bean?

              Thanks,

              Ken


              • 4. Re: Bean destroy methods when undeploying
                alesj

                 

                "tkyung" wrote:
                Is there a downside for making this a prototype bean?

                This is more of a Spring question, so you should really ask there.
                But I think this is what happens here is that if a bean is prototype, Spring doesn't track it anymore, so nothing happens on shutdown - since it's out of Spring's scope.

                What you should really use is, SpringDeployer's hierarchy notion:
                - http://java.sys-con.com/read/180386.htm

                Since we'd like to hot deploy many different Spring archives, each of them must be uniquely represented in our environment. For that purpose, JNDI will be used as a registry for these deployments. But where can we get our local JNDI name? By default, this JNDI name is obtained from the archive's file name: <name>.spring or <name>-spring.xml. But since it's also possible for each bean factory to have parent bean factory, there should be a way to define this parent's name too. This can be done in Spring's beans xml descriptor in description tag as shown in Listing 3.

                We are parsing this description tag and looking for a regular expression pattern of 'BeanFactory=(<name>)' and 'ParentBeanFactory=(<name>)' so see Listing 4.

                Every time a Spring component is undeployed, we get the corresponding Bean factory through the URL string key in our bean factory map. We remove the map entry, destroy the bean factory singletons, and unbind it from JNDI. When undeploying components be careful of the bean factory hierarchy; don't undeploy some other component's parent bean factory. When shutting down, JBossAS undeploys components in reverse order, which is the right behavior for our child-parent bean factory hierarchy.


                And then you can access other context's bean directly.