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) {