10 Replies Latest reply on Feb 26, 2014 4:00 PM by Bechara Hitti

    LifecycleListener equivalent

    Bechara Hitti Newbie

      Hello,

      I am contemplating a cross-over from glassfish v4 (reasons beyond the scope of this question).

       

      The application I am porting is mostly standard compliant except for the initialization part which relies on com.sun.appserv.server.LifecycleListener

       

       

      public class Init implements com.sun.appserv.server.LifecycleListener {
      
          @Override
          public void handleEvent(LifecycleEvent le) throws ServerLifecycleException {
                whatever initialization code I need goes here....
           }
      }
      
      

       

      While wildfly is getting downloaded, I have been trying to research a way to accomplish the same.

       

      Basically, what I need is a way to make sure the code initialization sequence is performed once and only once in the event of a server startup (even when following a crash or ungraceful reboot).

       

      I am not a fan of using server specific code but with glassfish, I had previously tried a Singleton with a @PostConstruct... which resulted with the code getting initiated twice... afaik java ee 7 specifications do not guarantee that the @PostContruct method is only called once.

       

       

      Any suggestions would be appreciated.

       

      Thanks,

        • 1. Re: LifecycleListener equivalent
          Tomaz Cerar Master

          You need servlet events?

           

          As you can achieve what you want in completely standard way.

          by having @Singleton @Startup ejb bean with @PostConstruct method.

          • 2. Re: LifecycleListener equivalent
            Bechara Hitti Newbie

            Thank you for your reply!

             

            Unfortunately, as stated above, last time I tried this approach the method got called twice during startup.

             

            Afaik, there is no guarantee that the @PostConstruct gets called only once. It is absurd I know, but it seems that's the way things are designed.

             

            See EJB 3.2 spec section "3.4.4Session Bean's No-Interface View":

            The developer of an enterprise bean that exposes a no-interface view must not make any assumptions about the number of times the bean class no-arg constructor will be called. For example, it is possible that the acquisition of a client reference to the no-interface view will result in the invocation of the beanclass constructor.


            (Got my information from https://java.net/jira/browse/GLASSFISH-20863)

            • 3. Re: Re: LifecycleListener equivalent
              Stephen Coy Master

              This:

              The developer of an enterprise bean that exposes a no-interface view must not make any assumptions about the number of times the bean class no-arg constructor will be called

               

              does not imply that @PostConstruct will be called multiple times. In fact the JIRA that you referenced says this as well.

               

              Therefore, if this is indeed happening to you then we would need to see more details.

              • 4. Re: LifecycleListener equivalent
                Bechara Hitti Newbie

                Thank you for the feedback.

                So you mean that the multiple calls apply to the no-arg constructor rather than the @PostContruct method

                 

                My experience with Glassfish tells me otherwise. I had the @PostConstructor called twice during startup which after a lot of research prompted me to switch to the LicecycleListener.

                 

                Since I am trying to migrate to wildfly, I do not feel that elaborating on the glassfish issue is relevant to this forum. Perhaps it would be best if I made a test implementation using wildfly an shared my findings here.

                 

                It will probably do so and report success of failure.

                 

                Thanks again!

                • 5. Re: LifecycleListener equivalent
                  Rich DiCroce Novice

                  If you're okay with using CDI, there's a new feature in CDI 1.1 that may do what you want. Basically, the CDI container now fires a CDI event whenever any scope is initialized or destroyed. So you can effectively get "run on startup" behavior by creating an observer method like so:

                   

                  void myStartupMethod(@Observes @Initialized(ApplicationScoped.class) Object event) {

                  ...your init code here...

                  }

                   

                  I'm using this in a new project right now, and I'm happy with it so far.

                   

                  For you, I do see one caveat. Technically, this is not tied to the lifecycle of the application server but rather the lifecycle of the deployment. So if you deployed the application, then undeployed it (without stopping WildFly), and then redeployed it, the method would get invoked again.

                  1 of 1 people found this helpful
                  • 6. Re: LifecycleListener equivalent
                    Bechara Hitti Newbie

                    That sounds like a delightful solution and standard compliant too! Thank you!

                     

                    I am currently running into the much expected migration trouble.. netbeans 7.4 refusing to connect to wildfly etc ... and still have not been able to find the time needed to get a test environment running.

                     

                    Will get back to you with my findings asap!

                    • 7. Re: Re: LifecycleListener equivalent
                      Bechara Hitti Newbie
                      @ApplicationScoped
                      public class Init {
                          private static final Logger LOG = Logger.getLogger(Init.class.getName());
                      
                          public Init() {
                              LOG.info("###In init");
                          }
                      
                      public void start(@Observes @Initialized(ApplicationScoped.class) Object o)  {
                           LOG.info("## Startup");  
                      }
                      
                      
                      public void stop(@Observes @Destroyed(ApplicationScoped.class) Object o) {
                              LOG.info("Goodbye cruel World!");
                          }
                      
                      }
                      
                      
                      

                       

                      I tested the code above in glassfish while setting up WildFly, the code above worked like a charm but only when the class was decorated with @ApplicationScoped are you observing the same behavior?

                       

                      Thanks!

                      • 8. Re: LifecycleListener equivalent
                        Tomaz Cerar Master

                        Bechara Hitti wrote:

                         

                        I am currently running into the much expected migration trouble.. netbeans 7.4 refusing to connect to wildfly etc ... and still have not been able to find the time needed to get a test environment running.

                        You should try NetBeans 8 see: https://blogs.oracle.com/geertjan/entry/wildfly_simply_works_in_netbeans

                        1 of 1 people found this helpful
                        • 9. Re: Re: LifecycleListener equivalent
                          Rich DiCroce Novice

                          Yes, I've observed that behavior as well. The reason is because of another change in CDI 1.1. In CDI 1.0, any archive containing a beans.xml file was CDI-enabled, and any class in such an archive that didn't have a scope annotation was implicitly @Dependent scoped. That caused headaches for a variety of reasons, so in CDI 1.1, a new bean discovery mode was introduced (and is also the default, if memory serves) that only looks at classes with an explicit scope annotation. You can change the bean discovery mode in beans.xml like so:

                           

                          <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                            xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"

                            version="1.1" bean-discovery-mode="annotated"/>

                           

                          bean-discovery-mode can be annotated, all (equivalent to CDI 1.0), or none. @Dependent is a scope annotation, so you can still have dependent-scoped beans when using annotated bean-discovery-mode.

                          • 10. Re: Re: LifecycleListener equivalent
                            Bechara Hitti Newbie

                            Thanks for the thorough explanation!