4 Replies Latest reply on Nov 11, 2009 12:18 AM by Arbi Sookazian

    How does Seam start?

    Arbi Sookazian Master

      Developing Seam applications requires thorough understanding of the JSF life cycle, the Seam life cycle and what extensions it has in the JSF life cycle via phase listeners.  Section 3.1.1 of SiA covers flipping Seam's switch.  I was going to write a knowledge base article about this topic in more detail but there was no appropriate category so I'm posting it here.



      In web applications, start-up code can be written with a ServletContextListener.  These are event listeners that are executed after the web application is first initialized (before it processes requests), and right before it is destroyed.

      source: JSF in Action, pg. 483


      The class of interest is org.jboss.seam.servlet.SeamListener defined as follows in Seam 2.1.2 codebase:


      import javax.servlet.ServletContextEvent;
      import javax.servlet.ServletContextListener;
      import javax.servlet.http.HttpSessionEvent;
      import javax.servlet.http.HttpSessionListener;
      
      import org.jboss.seam.Seam;
      import org.jboss.seam.contexts.ServletLifecycle;
      import org.jboss.seam.init.Initialization;
      import org.jboss.seam.jmx.JBossClusterMonitor;
      import org.jboss.seam.log.LogProvider;
      import org.jboss.seam.log.Logging;
      
      /**
       * Drives certain Seam functionality such as initialization and cleanup
       * of application and session contexts from the web application lifecycle.
       * 
       * @author Gavin King
       */
      public class SeamListener implements ServletContextListener, HttpSessionListener
      {
         private static final LogProvider log = Logging.getLogProvider(ServletContextListener.class);
         
         public void contextInitialized(ServletContextEvent event) 
         {
            log.info( "Welcome to Seam " + Seam.getVersion() );
            event.getServletContext().setAttribute( Seam.VERSION, Seam.getVersion() );
            ServletLifecycle.beginApplication( event.getServletContext() );
            new Initialization( event.getServletContext() ).create().init();
         }
         
         public void contextDestroyed(ServletContextEvent event) 
         {
            ServletLifecycle.endApplication();
         }
         
         public void sessionCreated(HttpSessionEvent event) 
         {
            ServletLifecycle.beginSession( event.getSession() );
         }
         
         public void sessionDestroyed(HttpSessionEvent event) 
         {
            JBossClusterMonitor monitor = JBossClusterMonitor.getInstance(event.getSession().getServletContext());
            if (monitor != null && monitor.failover())
            {
               // If application is unfarmed or all nodes shutdown simultaneously, cluster cache may still fail to retrieve SFSBs to destroy
               log.debug("Detected fail-over, not destroying session context");
            }
            else
            {
               ServletLifecycle.endSession( event.getSession() );
            }
         }
         
      }
      



      Notice that SeamListener implements ServletContextListener.



      Implementations of this interface receive notifications about changes to the servlet context of the web application they are part of. To receive notification events, the implementation class must be configured in the deployment descriptor for the web application.

      http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletContextListener.html


      So you simply implement ServletContextListener and add the following to web.xml:


      <listener>
              <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
          </listener>



      and the contextInitialized() method is invoked by the servlet container when the application is initialized.  This is how Seam starts everytime you deploy your Seam app in your servlet container and/or JEE server...