Author: rmannibucau
Date: Tue Dec 11 09:16:54 2012
New Revision: 1420046

URL: http://svn.apache.org/viewvc?rev=1420046&view=rev
Log:
TOMEE-645 ensuring the cdi contexts are availables when needed and released 
after all potential needs

Added:
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/BeginWebBeansListener.java
      - copied, changed from r1420027, 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/WebBeansListener.java
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/EndWebBeansListener.java
Removed:
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/WebBeansListener.java
Modified:
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java

Copied: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/BeginWebBeansListener.java
 (from r1420027, 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/WebBeansListener.java)
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/BeginWebBeansListener.java?p2=openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/BeginWebBeansListener.java&p1=openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/WebBeansListener.java&r1=1420027&r2=1420046&rev=1420046&view=diff
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/WebBeansListener.java
 (original)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/BeginWebBeansListener.java
 Tue Dec 11 09:16:54 2012
@@ -21,23 +21,17 @@ import org.apache.openejb.cdi.ThreadSing
 import org.apache.openejb.cdi.WebappWebBeansContext;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
-import org.apache.webbeans.component.InjectionPointBean;
 import org.apache.webbeans.config.OWBLogConst;
 import org.apache.webbeans.config.WebBeansContext;
-import org.apache.webbeans.conversation.ConversationManager;
-import org.apache.webbeans.el.ELContextStore;
 import org.apache.webbeans.spi.FailOverService;
 import org.apache.webbeans.util.WebBeansUtil;
-import org.apache.webbeans.web.context.WebContextsService;
 
-import javax.enterprise.context.ApplicationScoped;
 import javax.enterprise.context.RequestScoped;
 import javax.enterprise.context.SessionScoped;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 import javax.servlet.ServletRequestEvent;
 import javax.servlet.ServletRequestListener;
-import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 import javax.servlet.http.HttpSessionActivationListener;
 import javax.servlet.http.HttpSessionEvent;
@@ -46,14 +40,14 @@ import javax.servlet.http.HttpSessionLis
 /**
  * @version $Rev$ $Date$
  */
-public class WebBeansListener implements ServletContextListener, 
ServletRequestListener, HttpSessionListener, HttpSessionActivationListener {
+public class BeginWebBeansListener implements ServletContextListener, 
ServletRequestListener, HttpSessionListener, HttpSessionActivationListener {
 
-    private final String contextKey = this.getClass().getName() + "@" + 
hashCode();
+    private final String contextKey;
 
     /**
      * Logger instance
      */
-    private static final Logger logger = 
Logger.getInstance(LogCategory.OPENEJB_CDI, WebBeansListener.class);
+    private static final Logger logger = 
Logger.getInstance(LogCategory.OPENEJB_CDI, BeginWebBeansListener.class);
 
     protected FailOverService failoverService;
 
@@ -65,67 +59,26 @@ public class WebBeansListener implements
     /**
      * Default constructor
      *
-     * @param webBeansContext
+     * @param webBeansContext the OWB context
      */
-    public WebBeansListener(WebBeansContext webBeansContext) {
+    public BeginWebBeansListener(WebBeansContext webBeansContext) {
         this.webBeansContext = webBeansContext;
         this.failoverService = 
this.webBeansContext.getService(FailOverService.class);
+        this.contextKey = "org.apache.tomee.catalina.WebBeansListener@" + 
webBeansContext.hashCode();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public void requestDestroyed(ServletRequestEvent event) {
-        if (logger.isDebugEnabled()) {
-            logger.debug("Destroying a request : [{0}]", 
event.getServletRequest().getRemoteAddr());
-        }
-
-        final Object oldContext = 
event.getServletRequest().getAttribute(contextKey);
-
-        try {
-            if (failoverService != null &&
-                    failoverService.isSupportFailOver()) {
-                Object request = event.getServletRequest();
-                if (request instanceof HttpServletRequest) {
-                    HttpServletRequest httpRequest = (HttpServletRequest) 
request;
-                    HttpSession session = httpRequest.getSession(false);
-                    if (session != null) {
-                        failoverService.sessionIsIdle(session);
-                    }
-                }
-            }
-
-            // clean up the EL caches after each request
-            ELContextStore elStore = ELContextStore.getInstance(false);
-            if (elStore != null) {
-                elStore.destroyELContextStore();
-            }
-
-
-            
webBeansContext.getContextsService().endContext(RequestScoped.class, event);
-            if (webBeansContext instanceof WebappWebBeansContext) {
-                ((WebappWebBeansContext) 
webBeansContext).getParent().getContextsService().endContext(RequestScoped.class,
 event);
-            }
-            cleanupRequestThreadLocals();
-        } finally {
-            ThreadSingletonServiceImpl.enter((WebBeansContext) oldContext);
-        }
-    }
-
-    /**
-     * Ensures that all ThreadLocals, which could have been set in this
-     * request's Thread, are removed in order to prevent memory leaks.
-     */
-    private void cleanupRequestThreadLocals() {
-        // TODO maybe there are more to cleanup
-
-        InjectionPointBean.removeThreadLocal();
-        WebContextsService.removeThreadLocals();
+        // no-op
     }
 
     /**
      * {@inheritDoc}
      */
+    @Override
     public void requestInitialized(ServletRequestEvent event) {
         final Object oldContext = 
ThreadSingletonServiceImpl.enter(this.webBeansContext);
         event.getServletRequest().setAttribute(contextKey, oldContext);
@@ -135,10 +88,10 @@ public class WebBeansListener implements
                 logger.debug("Starting a new request : [{0}]", 
event.getServletRequest().getRemoteAddr());
             }
 
-            
this.webBeansContext.getContextsService().startContext(RequestScoped.class, 
event);
-            if (webBeansContext instanceof WebappWebBeansContext) {
+            if (webBeansContext instanceof WebappWebBeansContext) { // start 
before child
                 ((WebappWebBeansContext) 
webBeansContext).getParent().getContextsService().startContext(RequestScoped.class,
 event);
             }
+            
this.webBeansContext.getContextsService().startContext(RequestScoped.class, 
event);
 
             // we don't initialise the Session here but do it lazily if it 
gets requested
             // the first time. See OWB-457
@@ -152,15 +105,16 @@ public class WebBeansListener implements
     /**
      * {@inheritDoc}
      */
+    @Override
     public void sessionCreated(HttpSessionEvent event) {
         try {
             if (logger.isDebugEnabled()) {
                 logger.debug("Starting a session with session id : [{0}]", 
event.getSession().getId());
             }
-            
this.webBeansContext.getContextsService().startContext(SessionScoped.class, 
event.getSession());
-            if (webBeansContext instanceof WebappWebBeansContext) {
+            if (webBeansContext instanceof WebappWebBeansContext) { // start 
before child
                 ((WebappWebBeansContext) 
webBeansContext).getParent().getContextsService().startContext(SessionScoped.class,
 event.getSession());
             }
+            
this.webBeansContext.getContextsService().startContext(SessionScoped.class, 
event.getSession());
         } catch (Exception e) {
             logger.error(OWBLogConst.ERROR_0020, event.getSession());
             WebBeansUtil.throwRuntimeExceptions(e);
@@ -170,29 +124,15 @@ public class WebBeansListener implements
     /**
      * {@inheritDoc}
      */
+    @Override
     public void sessionDestroyed(HttpSessionEvent event) {
-        if (logger.isDebugEnabled()) {
-            logger.debug("Destroying a session with session id : [{0}]", 
event.getSession().getId());
-        }
-
-        
this.webBeansContext.getContextsService().endContext(SessionScoped.class, 
event.getSession());
-        if (webBeansContext instanceof WebappWebBeansContext) {
-            ((WebappWebBeansContext) 
webBeansContext).getParent().getContextsService().endContext(SessionScoped.class,
 event.getSession());
-        }
-
-        ConversationManager conversationManager = 
webBeansContext.getConversationManager();
-        
conversationManager.destroyConversationContextWithSessionId(event.getSession().getId());
+        // no-op
     }
 
 
     @Override
     public void sessionWillPassivate(HttpSessionEvent event) {
-        if (failoverService != null &&
-                failoverService.isSupportPassivation()) {
-            HttpSession session = event.getSession();
-            failoverService.sessionWillPassivate(session);
-        }
-
+        // no-op
     }
 
     @Override

Added: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/EndWebBeansListener.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/EndWebBeansListener.java?rev=1420046&view=auto
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/EndWebBeansListener.java
 (added)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/EndWebBeansListener.java
 Tue Dec 11 09:16:54 2012
@@ -0,0 +1,170 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.tomee.catalina;
+
+import org.apache.openejb.cdi.ThreadSingletonServiceImpl;
+import org.apache.openejb.cdi.WebappWebBeansContext;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+import org.apache.webbeans.component.InjectionPointBean;
+import org.apache.webbeans.config.OWBLogConst;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.conversation.ConversationManager;
+import org.apache.webbeans.el.ELContextStore;
+import org.apache.webbeans.spi.FailOverService;
+import org.apache.webbeans.util.WebBeansUtil;
+import org.apache.webbeans.web.context.WebContextsService;
+
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.context.SessionScoped;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class EndWebBeansListener implements ServletRequestListener, 
HttpSessionListener, HttpSessionActivationListener {
+
+    private final String contextKey;
+
+    /**
+     * Logger instance
+     */
+    private static final Logger logger = 
Logger.getInstance(LogCategory.OPENEJB_CDI, EndWebBeansListener.class);
+
+    protected FailOverService failoverService;
+
+    /**
+     * Manages the container lifecycle
+     */
+    protected WebBeansContext webBeansContext;
+
+    /**
+     * Default constructor
+     *
+     * @param webBeansContext the OWB context
+     */
+    public EndWebBeansListener(WebBeansContext webBeansContext) {
+        this.webBeansContext = webBeansContext;
+        this.failoverService = 
this.webBeansContext.getService(FailOverService.class);
+        this.contextKey = "org.apache.tomee.catalina.WebBeansListener@" + 
webBeansContext.hashCode();
+    }
+
+    /**
+     * Ensures that all ThreadLocals, which could have been set in this
+     * request's Thread, are removed in order to prevent memory leaks.
+     */
+    private void cleanupRequestThreadLocals() {
+        // TODO maybe there are more to cleanup
+
+        InjectionPointBean.removeThreadLocal();
+        WebContextsService.removeThreadLocals();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void requestDestroyed(ServletRequestEvent event) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("Destroying a request : [{0}]", 
event.getServletRequest().getRemoteAddr());
+        }
+
+        final Object oldContext = 
event.getServletRequest().getAttribute(contextKey);
+
+        try {
+            if (failoverService != null &&
+                    failoverService.isSupportFailOver()) {
+                Object request = event.getServletRequest();
+                if (request instanceof HttpServletRequest) {
+                    HttpServletRequest httpRequest = (HttpServletRequest) 
request;
+                    HttpSession session = httpRequest.getSession(false);
+                    if (session != null) {
+                        failoverService.sessionIsIdle(session);
+                    }
+                }
+            }
+
+            // clean up the EL caches after each request
+            final ELContextStore elStore = ELContextStore.getInstance(false);
+            if (elStore != null) {
+                elStore.destroyELContextStore();
+            }
+
+
+            
webBeansContext.getContextsService().endContext(RequestScoped.class, event);
+            if (webBeansContext instanceof WebappWebBeansContext) { // end 
after child
+                ((WebappWebBeansContext) 
webBeansContext).getParent().getContextsService().endContext(RequestScoped.class,
 event);
+            }
+            cleanupRequestThreadLocals();
+        } finally {
+            ThreadSingletonServiceImpl.enter((WebBeansContext) oldContext);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void requestInitialized(ServletRequestEvent event) {
+        // no-op
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void sessionCreated(HttpSessionEvent event) {
+        // no-op
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void sessionDestroyed(HttpSessionEvent event) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("Destroying a session with session id : [{0}]", 
event.getSession().getId());
+        }
+
+        
this.webBeansContext.getContextsService().endContext(SessionScoped.class, 
event.getSession());
+        if (webBeansContext instanceof WebappWebBeansContext) { // end after 
child
+            ((WebappWebBeansContext) 
webBeansContext).getParent().getContextsService().endContext(SessionScoped.class,
 event.getSession());
+        }
+
+        ConversationManager conversationManager = 
webBeansContext.getConversationManager();
+        
conversationManager.destroyConversationContextWithSessionId(event.getSession().getId());
+    }
+
+
+    @Override
+    public void sessionWillPassivate(HttpSessionEvent event) {
+        if (failoverService != null && failoverService.isSupportPassivation()) 
{
+            failoverService.sessionWillPassivate(event.getSession());
+        }
+    }
+
+    @Override
+    public void sessionDidActivate(HttpSessionEvent event) {
+        // no-op
+    }
+}

Modified: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java?rev=1420046&r1=1420045&r2=1420046&view=diff
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
 (original)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
 Tue Dec 11 09:16:54 2012
@@ -1318,11 +1318,30 @@ public class TomcatWebAppBuilder impleme
         }
 
 
-        final WebBeansListener webBeansListener = 
getWebBeansContext(contextInfo);
-
-        if (webBeansListener != null) {
-            standardContext.addApplicationEventListener(webBeansListener);
-            standardContext.addApplicationLifecycleListener(webBeansListener);
+        final WebBeansContext webBeansContext = 
getWebBeansContext(contextInfo);
+        if (webBeansContext != null) {
+            // it is important to have a begin and a end listener
+            // to be sure to create contexts before other listeners
+            // and destroy contexts after other listeners
+
+            final Object[] appEventListeners = 
standardContext.getApplicationEventListeners();
+            final Object[] newEventListeners = new 
Object[appEventListeners.length + 2];
+
+            final Object[] lifecycleListeners = 
standardContext.getApplicationLifecycleListeners();
+            final Object[] newLifecycleListeners = new 
Object[lifecycleListeners.length + 2];
+
+            final BeginWebBeansListener beginWebBeansListener = new 
BeginWebBeansListener(webBeansContext);
+            final EndWebBeansListener endWebBeansListener = new 
EndWebBeansListener(webBeansContext);
+
+            newEventListeners[0] = beginWebBeansListener;
+            System.arraycopy(appEventListeners, 0, newEventListeners, 1, 
appEventListeners.length);
+            newEventListeners[newEventListeners.length - 1] = 
endWebBeansListener;
+            standardContext.setApplicationEventListeners(newEventListeners);
+
+            newLifecycleListeners[0] = beginWebBeansListener;
+            System.arraycopy(lifecycleListeners, 0, newLifecycleListeners, 1, 
lifecycleListeners.length);
+            newLifecycleListeners[newEventListeners.length - 1] = 
endWebBeansListener;
+            
standardContext.setApplicationLifecycleListeners(newLifecycleListeners);
         }
 
         LinkageErrorProtection.preload(standardContext);
@@ -1363,7 +1382,7 @@ public class TomcatWebAppBuilder impleme
         }
     }
 
-    private WebBeansListener getWebBeansContext(final ContextInfo contextInfo) 
{
+    private WebBeansContext getWebBeansContext(final ContextInfo contextInfo) {
         final AppContext appContext = 
getContainerSystem().getAppContext(contextInfo.appInfo.appId);
 
         if (appContext == null) return null;
@@ -1385,9 +1404,11 @@ public class TomcatWebAppBuilder impleme
             }
         }
 
-        if (webBeansContext == null) webBeansContext = 
appContext.getWebBeansContext();
+        if (webBeansContext == null) {
+            webBeansContext = appContext.getWebBeansContext();
+        }
 
-        return new WebBeansListener(webBeansContext);
+        return webBeansContext;
     }
 
     private static String removeFirstSlashAndWar(final String name) {


Reply via email to