You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2014/12/24 12:20:27 UTC

tomee git commit: more scope events

Repository: tomee
Updated Branches:
  refs/heads/develop 1554b1054 -> 97b720ed1


more scope events


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/97b720ed
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/97b720ed
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/97b720ed

Branch: refs/heads/develop
Commit: 97b720ed1f95667bc4b48b22efea36b03b93a6e2
Parents: 1554b10
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Wed Dec 24 12:20:06 2014 +0100
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Wed Dec 24 12:20:06 2014 +0100

----------------------------------------------------------------------
 .../openejb/assembler/classic/Assembler.java    |   5 +-
 .../openejb/cdi/CdiAppContextsService.java      | 133 ++++++++++++++-----
 .../apache/openejb/cdi/OpenEJBLifecycle.java    |  10 +-
 .../cdi/UpdatableSessionContextManager.java     |   4 +
 .../org/apache/openejb/core/WebContext.java     |  10 ++
 .../openejb/web/LightweightWebAppBuilder.java   |   1 +
 .../openejb/server/httpd/HttpResponseImpl.java  |  29 ++--
 .../server/httpd/OpenEJBHttpRegistry.java       |  26 +++-
 .../openejb/server/httpd/OpenEJBHttpServer.java |  10 +-
 tck/cdi-embedded/src/test/resources/failing.xml |   7 +-
 .../tomee/catalina/TomcatWebAppBuilder.java     |   1 +
 .../cdi/SessionContextBackedByHttpSession.java  |  12 +-
 12 files changed, 179 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
index 82533c7..5750ec0 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
@@ -180,6 +180,7 @@ import javax.resource.spi.ResourceAdapter;
 import javax.resource.spi.ResourceAdapterInternalException;
 import javax.resource.spi.XATerminator;
 import javax.resource.spi.work.WorkManager;
+import javax.servlet.ServletContext;
 import javax.sql.DataSource;
 import javax.transaction.TransactionManager;
 import javax.transaction.TransactionSynchronizationRegistry;
@@ -1739,7 +1740,9 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A
                     final ClassLoader old = Thread.currentThread().getContextClassLoader();
                     Thread.currentThread().setContextClassLoader(classLoader);
                     try {
-                        webBeansContext.getService(ContainerLifecycle.class).stopApplication(null);
+                        final ServletContext context = appContext.isStandaloneModule() && appContext.getWebContexts().iterator().hasNext() ?
+                                appContext.getWebContexts().iterator().next().getServletContext() : null;
+                        webBeansContext.getService(ContainerLifecycle.class).stopApplication(context);
                     } finally {
                         Thread.currentThread().setContextClassLoader(old);
                     }

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java
index e80306f..0f57231 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java
@@ -56,12 +56,13 @@ import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Map;
 
 public class CdiAppContextsService extends AbstractContextsService implements ContextsService {
 
     private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB.createChild("cdi"), CdiAppContextsService.class);
 
-    private final ThreadLocal<RequestContext> requestContext = new ThreadLocal<RequestContext>();
+    private final ThreadLocal<ServletRequestContext> requestContext = new ThreadLocal<ServletRequestContext>();
 
     private final ThreadLocal<SessionContext> sessionContext = new ThreadLocal<SessionContext>();
     private final UpdatableSessionContextManager sessionCtxManager = new UpdatableSessionContextManager();
@@ -79,6 +80,8 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
 
     private final WebBeansContext webBeansContext;
 
+    private final ConversationService conversationService;
+
     private static final ThreadLocal<Collection<Runnable>> endRequestRunnables = new ThreadLocal<Collection<Runnable>>() {
         @Override
         protected Collection<Runnable> initialValue() {
@@ -87,8 +90,8 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
     };
 
 
-    public CdiAppContextsService() {
-        this(WebBeansContext.currentInstance(), WebBeansContext.currentInstance().getOpenWebBeansConfiguration().supportsConversation());
+    public CdiAppContextsService(final WebBeansContext wbc) {
+        this(wbc, wbc.getOpenWebBeansConfiguration().supportsConversation());
     }
 
     public CdiAppContextsService(final WebBeansContext wbc, final boolean supportsConversation) {
@@ -100,8 +103,14 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
 
         dependentContext.setActive(true);
         if (supportsConversation) {
-            conversationContext = new ThreadLocal<ConversationContext>();
+            conversationService = webBeansContext.getService(ConversationService.class);
+            if (conversationService == null) {
+                conversationContext = null;
+            } else {
+                conversationContext = new ThreadLocal<ConversationContext>();
+            }
         } else {
+            conversationService = null;
             conversationContext = null;
         }
         applicationContext.setActive(true);
@@ -132,6 +141,28 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
         startContext(Singleton.class, initializeObject);
     }
 
+    public void beforeStop(final Object destroyObject) {
+        {   // trigger @PreDestroy mainly but keep it active until destroy(xxx)
+            applicationContext.destroy();
+            webBeansContext.getBeanManagerImpl().fireEvent(destroyObject != null ? destroyObject : applicationContext, DestroyedLiteral.APP);
+            applicationContext.setActive(true);
+
+            singletonContext.destroy();
+            singletonContext.setActive(true);
+        }
+
+        for (final Map.Entry<Conversation, ConversationContext> conversation : webBeansContext.getConversationManager().getAllConversationContexts().entrySet()) {
+            conversation.getValue().destroy();
+            webBeansContext.getBeanManagerImpl().fireEvent(conversation.getKey().getId(), DestroyedLiteral.CONVERSATION);
+        }
+        for (final SessionContext sc : sessionCtxManager.getContextById().values()) {
+            sc.destroy();
+            final Object event = HttpSessionContextSessionAware.class.isInstance(sc) ? HttpSessionContextSessionAware.class.cast(sc).getSession() : sc;
+            webBeansContext.getBeanManagerImpl().fireEvent(event, DestroyedLiteral.SESSION);
+        }
+        sessionCtxManager.getContextById().clear();
+    }
+
     public void destroy(final Object destroyObject) {
         //Destroy application context
         endContext(ApplicationScoped.class, destroyObject);
@@ -158,7 +189,6 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
 
     @Override
     public void endContext(final Class<? extends Annotation> scopeType, final Object endParameters) {
-
         if (supportsContext(scopeType)) {
             if (scopeType.equals(RequestScoped.class)) {
                 destroyRequestContext();
@@ -171,7 +201,7 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
             } else if (scopeType.equals(Singleton.class)) {
                 destroySingletonContext();
             } else if (supportsConversation() && scopeType.equals(ConversationScoped.class)) {
-                destroyConversationContext();
+                destroyConversationContext(endParameters);
             } else {
                 if (logger.isWarningEnabled()) {
                     logger.warning("CDI-OpenWebBeans container in OpenEJB does not support context scope "
@@ -186,13 +216,13 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
     @Override
     public Context getCurrentContext(final Class<? extends Annotation> scopeType) {
         if (scopeType.equals(RequestScoped.class)) {
-            return getRequestContext();
+            return getRequestContext(true);
         } else if (scopeType.equals(SessionScoped.class)) {
-            return getSessionContext();
+            return getSessionContext(true);
         } else if (scopeType.equals(ApplicationScoped.class)) {
             return getApplicationContext();
         } else if (supportsConversation() && scopeType.equals(ConversationScoped.class)) {
-            return getConversationContext();
+            return getConversationContext(true);
         } else if (scopeType.equals(Dependent.class)) {
             return dependentContext;
         } else if (scopeType.equals(Singleton.class)) {
@@ -210,7 +240,7 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
             } else if (scopeType.equals(SessionScoped.class)) {
                 initSessionContext((HttpSession) startParameter);
             } else if (scopeType.equals(ApplicationScoped.class)) {
-                initApplicationContext();
+                initApplicationContext(startParameter);
             } else if (scopeType.equals(Dependent.class)) {
                 initSingletonContext();
             } else if (scopeType.equals(Singleton.class)) { //NOPMD
@@ -231,8 +261,12 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
         singletonContext.setActive(true);
     }
 
-    private void initApplicationContext() { // in case contexts are stop/start
-        applicationContext.setActive(true);
+    private void initApplicationContext(final Object init) { // in case contexts are stop/start
+        final boolean alreadyStarted = applicationContext.isActive();
+        if (!alreadyStarted) {
+            applicationContext.setActive(true);
+            webBeansContext.getBeanManagerImpl().fireEvent(init != null ? init : applicationContext, InitializedLiteral.APP);
+        }
     }
 
     @Override
@@ -247,7 +281,7 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
     }
 
     private void initRequestContext(final ServletRequestEvent event) {
-        final RequestContext rq = new ServletRequestContext();
+        final ServletRequestContext rq = new ServletRequestContext();
         rq.setActive(true);
 
         requestContext.set(rq);// set thread local
@@ -279,7 +313,7 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
         }
 
         //Get context
-        final RequestContext context = getRequestContext();
+        final RequestContext context = getRequestContext(false);
 
         //Destroy context
         if (context != null) {
@@ -303,11 +337,11 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
     }
 
     private void cleanupConversation() {
-        if (webBeansContext.getService(ConversationService.class) == null) {
+        if (conversationService == null) {
             return;
         }
 
-        final ConversationContext conversationContext = getConversationContext();
+        final ConversationContext conversationContext = getConversationContext(false);
         if (conversationContext == null) {
             return;
         }
@@ -371,7 +405,7 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
                 logger.error("Can't instantiate " + classname + ", using default session context", e);
             }
         }
-        return new SessionContext();
+        return new HttpSessionContextSessionAware(session);
     }
 
     /**
@@ -382,11 +416,9 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
      */
     private void destroySessionContext(final HttpSession session) {
         if (session != null) {
-            //Get current session context
             final SessionContext context = sessionContext.get();
 
-            //Destroy context
-            if (context != null) {
+            if (context != null && context.isActive()) {
                 context.destroy();
                 pushRequestReleasable(new Runnable() { // call it at the end of the request
                     @Override
@@ -421,7 +453,7 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
      * @param context context
      */
     private void initConversationContext(final ConversationContext context) {
-        if (webBeansContext.getService(ConversationService.class) == null) {
+        if (conversationService == null) {
             return;
         }
 
@@ -431,6 +463,10 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
                 newContext.setActive(true);
 
                 conversationContext.set(newContext);
+                final ServletRequestContext servletRequestContext = getRequestContext(true);
+                webBeansContext.getBeanManagerImpl().fireEvent(
+                        servletRequestContext != null && servletRequestContext.getServletRequest() != null ?
+                                servletRequestContext.getServletRequest() : context, InitializedLiteral.CONVERSATION);
             } else {
                 conversationContext.get().setActive(true);
             }
@@ -444,36 +480,39 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
     /**
      * Destroy conversation context.
      */
-    private void destroyConversationContext() {
-        if (webBeansContext.getService(ConversationService.class) == null) {
+    private void destroyConversationContext(final Object destroy) {
+        if (conversationService == null) {
             return;
         }
 
-        final ConversationContext context = getConversationContext();
+        final ConversationContext context = getConversationContext(false);
 
         if (context != null) {
             context.destroy();
+            final ServletRequestContext servletRequestContext = getRequestContext(false);
+            final Object destroyObject = servletRequestContext != null && servletRequestContext.getServletRequest() != null ?
+                    servletRequestContext.getServletRequest() : destroy;
+            webBeansContext.getBeanManagerImpl().fireEvent(
+                    destroyObject == null ? context : destroyObject, DestroyedLiteral.CONVERSATION);
         }
 
         if (null != conversationContext) {
-            conversationContext.set(null);
             conversationContext.remove();
         }
     }
 
 
-    private RequestContext getRequestContext() {
-        RequestContext context = requestContext.get();
-        if (context == null) {
-            context = new RequestContext();
-            context.setActive(true);
+    private ServletRequestContext getRequestContext(final boolean create) {
+        ServletRequestContext context = requestContext.get();
+        if (context == null && create) {
+            initRequestContext(null);
         }
         return context;
     }
 
-    private Context getSessionContext() {
+    private Context getSessionContext(final boolean create) {
         SessionContext context = sessionContext.get();
-        if (context == null || !context.isActive()) {
+        if ((context == null || !context.isActive()) && create) {
             lazyStartSessionContext();
             context = sessionContext.get();
             if (context == null) {
@@ -508,8 +547,14 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
      *
      * @return conversation context
      */
-    private ConversationContext getConversationContext() {
-        return conversationContext.get();
+    private ConversationContext getConversationContext(final boolean createIfMissing) {
+        ConversationContext context = conversationContext.get();
+        if (context == null && createIfMissing) {
+            getRequestContext(true); // needs to exist for Conversation scope
+            initConversationContext(null);
+            return getConversationContext(false);
+        }
+        return context;
     }
 
     private Context lazyStartSessionContext() {
@@ -576,11 +621,11 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
     }
 
     public static class State {
-        private final RequestContext request;
+        private final ServletRequestContext request;
         private final SessionContext session;
         private final ConversationContext conversation;
 
-        public State(final RequestContext request, final SessionContext session, final ConversationContext conversation) {
+        public State(final ServletRequestContext request, final SessionContext session, final ConversationContext conversation) {
             this.request = request;
             this.session = session;
             this.conversation = conversation;
@@ -588,6 +633,8 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
     }
 
     public static class InitializedLiteral extends AnnotationLiteral<Initialized> implements Initialized {
+        private static final InitializedLiteral APP = new InitializedLiteral(ApplicationScoped.class);
+        private static final InitializedLiteral CONVERSATION = new InitializedLiteral(ConversationScoped.class);
         private static final InitializedLiteral REQUEST = new InitializedLiteral(RequestScoped.class);
         private static final InitializedLiteral SESSION = new InitializedLiteral(SessionScoped.class);
 
@@ -603,6 +650,8 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
     }
 
     public static class DestroyedLiteral extends AnnotationLiteral<Destroyed> implements Destroyed {
+        private static final DestroyedLiteral APP = new DestroyedLiteral(ApplicationScoped.class);
+        private static final DestroyedLiteral CONVERSATION = new DestroyedLiteral(ConversationScoped.class);
         private static final DestroyedLiteral REQUEST = new DestroyedLiteral(RequestScoped.class);
         private static final DestroyedLiteral SESSION = new DestroyedLiteral(SessionScoped.class);
 
@@ -616,4 +665,16 @@ public class CdiAppContextsService extends AbstractContextsService implements Co
             return value;
         }
     }
+
+    public static class HttpSessionContextSessionAware extends SessionContext {
+        private final HttpSession session;
+
+        public HttpSessionContextSessionAware(final HttpSession session) {
+            this.session = session;
+        }
+
+        public HttpSession getSession() {
+            return session;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java
index 6e59360..6d0766a 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/OpenEJBLifecycle.java
@@ -284,14 +284,18 @@ public class OpenEJBLifecycle implements ContainerLifecycle {
                 service.shutdownNow();
             }
 
-            //Fire shut down
+            // Fire shut down
             if (WebappBeanManager.class.isInstance(beanManager)) {
                 WebappBeanManager.class.cast(beanManager).beforeStop();
             }
+
+            if (CdiAppContextsService.class.isInstance(contextsService)) {
+                CdiAppContextsService.class.cast(contextsService).beforeStop(endObject);
+            }
             this.beanManager.fireEvent(new BeforeShutdownImpl(), true);
 
-            //Destroys context
-            this.contextsService.destroy(null);
+            // Destroys context before BeforeShutdown event
+            this.contextsService.destroy(endObject);
 
             //Unbind BeanManager
             if (jndiService != null) {

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/container/openejb-core/src/main/java/org/apache/openejb/cdi/UpdatableSessionContextManager.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/cdi/UpdatableSessionContextManager.java b/container/openejb-core/src/main/java/org/apache/openejb/cdi/UpdatableSessionContextManager.java
index b5279b0..fe97ef1 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/cdi/UpdatableSessionContextManager.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/cdi/UpdatableSessionContextManager.java
@@ -46,6 +46,10 @@ public class UpdatableSessionContextManager extends SessionContextManager {
         }
     }
 
+    public Map<String, SessionContext> getContextById() {
+        return contextById;
+    }
+
     public void updateSessionIdMapping(final String oldId, final String newId) {
         if (oldId == null) {
             return;

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/container/openejb-core/src/main/java/org/apache/openejb/core/WebContext.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/WebContext.java b/container/openejb-core/src/main/java/org/apache/openejb/core/WebContext.java
index 6654556..4811751 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/WebContext.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/WebContext.java
@@ -33,6 +33,7 @@ import javax.naming.InitialContext;
 import javax.naming.NamingException;
 import javax.servlet.Filter;
 import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
 import javax.servlet.ServletContextAttributeListener;
 import javax.servlet.ServletContextListener;
 import javax.servlet.ServletRequestAttributeListener;
@@ -56,6 +57,7 @@ public class WebContext {
     private String contextRoot;
     private String host;
     private Context initialContext;
+    private ServletContext servletContext;
     private final Map<Class<?>, ConstructorInjectionBean<Object>> constructorInjectionBeanCache = new ConcurrentHashMap<Class<?>, ConstructorInjectionBean<Object>>();
 
     public Context getInitialContext() {
@@ -70,6 +72,14 @@ public class WebContext {
         return initialContext;
     }
 
+    public ServletContext getServletContext() {
+        return servletContext;
+    }
+
+    public void setServletContext(final ServletContext servletContext) {
+        this.servletContext = servletContext;
+    }
+
     public void setHost(final String host) {
         this.host = host;
     }

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java b/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java
index d255337..7a9176b 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java
@@ -140,6 +140,7 @@ public class LightweightWebAppBuilder implements WebAppBuilder {
             webContext.setHost(webAppInfo.host);
             webContext.getInjections().addAll(injections);
             webContext.setInitialContext(new EmbeddedInitialContext(webContext.getJndiEnc(), webContext.getBindings()));
+            webContext.setServletContext(SystemInstance.get().getComponent(ServletContext.class));
 
             appContext.getWebContexts().add(webContext);
             cs.addWebContext(webContext);

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java
----------------------------------------------------------------------
diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java
index c9cce62..c875f7b 100644
--- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java
+++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpResponseImpl.java
@@ -16,6 +16,8 @@
  */
 package org.apache.openejb.server.httpd;
 
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
 import org.apache.openejb.util.OpenEjbVersion;
 
 import javax.servlet.ServletOutputStream;
@@ -42,6 +44,7 @@ import java.util.StringTokenizer;
  * This class takes care of HTTP Responses.  It sends data back to the browser.
  */
 public class HttpResponseImpl implements HttpResponse {
+    private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_SERVER, HttpResponseImpl.class.getName());
 
     /**
      * Response string
@@ -95,10 +98,21 @@ public class HttpResponseImpl implements HttpResponse {
     private String encoding = "UTF-8";
     private Locale locale = Locale.getDefault();
 
+    private boolean eagerFlush = false;
+
     protected void setRequest(HttpRequestImpl request) {
         this.request = request;
     }
 
+    public boolean isEagerlyFlushed() {
+        return eagerFlush;
+    }
+
+    public void eagerFlush(final OutputStream out) throws IOException {
+        eagerFlush = true;
+        writeMessage(out, false);
+    }
+
     /**
      * sets a header to be sent back to the browser
      *
@@ -409,14 +423,9 @@ public class HttpResponseImpl implements HttpResponse {
      * @throws java.io.IOException if an exception is thrown
      */
     protected void writeMessage(OutputStream output, boolean indent) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        DataOutputStream out = new DataOutputStream(baos);
-        //DataOutput log = new DataOutputStream(System.out);
-        //System.out.println("\nRESPONSE");
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final DataOutputStream out = new DataOutputStream(baos);
         closeMessage();
-//        writeResponseLine(log);
-//        writeHeaders(log);
-//        writeBody(log);
         writeResponseLine(out);
         writeHeaders(out);
         writeBody(out, indent);
@@ -584,7 +593,11 @@ public class HttpResponseImpl implements HttpResponse {
         body.println("<body>");
         body.println("<h3>Internal Server Error</h3>");
         body.println("<br><br>");
-        System.out.println("ERROR");
+
+        if (LOGGER.isDebugEnabled()) { // this is not an error, don't log it by default
+            LOGGER.error(String.valueOf(t), t);
+        }
+
         if (message != null) {
             StringTokenizer msg = new StringTokenizer(message, "\n\r");
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
----------------------------------------------------------------------
diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
index b2dc7a4..9b3385c 100644
--- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
+++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java
@@ -26,6 +26,7 @@ import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
 import org.apache.webbeans.config.WebBeansContext;
 
+import java.io.OutputStream;
 import java.net.InetAddress;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -111,31 +112,42 @@ public class OpenEJBHttpRegistry {
             try {
                 if (request instanceof HttpRequestImpl) {
                     wbc = findWebContext(request.getURI().getPath());
-                    initCdi(wbc, (HttpRequestImpl) request).init();
+                    initCdi(wbc, HttpRequestImpl.class.cast(request)).init();
                 }
 
                 delegate.onMessage(request, response);
             } finally {
+                final OutputStream out = OutputStream.class.cast(request.getAttribute("openejb_http_output"));
                 if (wbc != null) {
-                    ((HttpRequestImpl) request).destroy();
+                    HttpRequestImpl.class.cast(request).destroy();
+                }
+                if (out != null && HttpResponseImpl.class.isInstance(response)) { // otherwise it got flushed after which means we can lock if @Observes @Destroyed(RequestScoped.class) rely on local http
+                    HttpResponseImpl.class.cast(response).eagerFlush(out);
                 }
 
                 thread.setContextClassLoader(oldCl);
             }
         }
 
-        private static WebBeansContext findWebContext(final String path) { // poor impl, would need registration of app etc to be better
+        private static WebBeansContext findWebContext(final String path) { // TODO: this is a poor impl, would need registration of app etc to be better and have a rooter
             for (final AppContext app : SystemInstance.get().getComponent(ContainerSystem.class).getAppContexts()) {
                 for (final WebContext web : app.getWebContexts()) {
                     if (path.startsWith(web.getContextRoot()) || path.startsWith('/' + web.getContextRoot())) {
-                        if (web.getWebBeansContext() != null) {
-                            return web.getWebBeansContext();
+                        // classloader will be correctly resetted anyway to fine o set it here
+                        if (web.getClassLoader() != null) {
+                            Thread.currentThread().setContextClassLoader(web.getClassLoader());
+                        } else if (app.getClassLoader() != null) {
+                            Thread.currentThread().setContextClassLoader(app.getClassLoader()); // will be resetted anyway to fine o set it here
                         }
-                        return app.getWebBeansContext();
+                        return web.getWebBeansContext(); // if null returns app one
                     }
                 }
             }
-            return WebBeansContext.currentInstance();
+            try { // surely an issue or something just tolerated for fake webapps
+                return WebBeansContext.currentInstance();
+            } catch (final IllegalStateException ise) {
+                return null;
+            }
         }
 
         private static HttpRequestImpl initCdi(final WebBeansContext context, final HttpRequestImpl request) {

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java
----------------------------------------------------------------------
diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java
index ea7384a..aec41d7 100644
--- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java
+++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpServer.java
@@ -192,15 +192,16 @@ public class OpenEJBHttpServer implements HttpServer {
     private void processRequest(final URI socketURI, final InputStream in, final OutputStream out) {
         HttpResponseImpl response = null;
         try {
-            response = process(socketURI, in);
+            response = process(socketURI, in, out);
 
         } catch (Throwable t) {
             response = HttpResponseImpl.createError(t.getMessage(), t);
         } finally {
             try {
                 if (response != null) {
-                    response.writeMessage(out, false);
-
+                    if (!response.isEagerlyFlushed()) {
+                        response.writeMessage(out, false);
+                    }
                     if (print.size() > 0 && print.contains(Output.RESPONSE)) {
                         response.writeMessage(new LoggerOutputStream(log, "debug"), indent);
                     }
@@ -220,7 +221,7 @@ public class OpenEJBHttpServer implements HttpServer {
         }
     }
 
-    private HttpResponseImpl process(final URI socketURI, final InputStream in) throws OpenEJBException {
+    private HttpResponseImpl process(final URI socketURI, final InputStream in, final OutputStream out) throws OpenEJBException {
         final HttpRequestImpl req = new HttpRequestImpl(socketURI);
         final HttpResponseImpl res = new HttpResponseImpl();
 
@@ -259,6 +260,7 @@ public class OpenEJBHttpServer implements HttpServer {
         }
 
         try {
+            req.setAttribute("openejb_http_output", out);
             listener.onMessage(req, res);
         } catch (Throwable t) {
             throw new OpenEJBException("Error occurred while executing the module " + location + "\n" + t.getClass().getName() + ":\n" + t.getMessage(), t);

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/tck/cdi-embedded/src/test/resources/failing.xml
----------------------------------------------------------------------
diff --git a/tck/cdi-embedded/src/test/resources/failing.xml b/tck/cdi-embedded/src/test/resources/failing.xml
index 40f6f29..954932d 100644
--- a/tck/cdi-embedded/src/test/resources/failing.xml
+++ b/tck/cdi-embedded/src/test/resources/failing.xml
@@ -17,9 +17,12 @@
   -->
 <suite name="CDI TCK" verbose="0">
   <test name="CDI TCK">
-    <!-- -Dopenejb.cdi.filter.classloader=false -Dorg.apache.openejb.assembler.classic.WebAppBuilder=org.apache.openejb.web.LightweightWebAppBuilder -Dopenejb.cdi.debug=true -Dopenejb.http.mock-request=true  -->
+    <!-- runner helping properties
+    -Dopenejb.cdi.filter.classloader=false -Dorg.apache.openejb.assembler.classic.WebAppBuilder=org.apache.openejb.web.LightweightWebAppBuilder -Dopenejb.cdi.debug=true -Dopenejb.http.mock-request=true
+    -->
     <classes><!-- org.jboss.cdi.tck.tests.context.conversation.ClientConversationContextTest, org.jboss.cdi.tck.tests.context.application.ApplicationContextTest, org.jboss.cdi.tck.tests.extensions.beanManager.beanAttributes.CreateBeanAttributesTest, org.jboss.cdi.tck.tests.event.fires.FireEventTest, org.jboss.cdi.tck.tests.extensions.lifecycle.processInjectionPoint.ProcessInjectionPointFiredTest -->
-      <class name="org.jboss.cdi.tck.tests.context.application.async.ApplicationContextAsyncListenerTest" />
+      <!--<class name="org.jboss.cdi.tck.tests.context.application.async.ApplicationContextAsyncListenerTest" />-->
+      <class name="org.jboss.cdi.tck.tests.deployment.shutdown.ApplicationShutdownLifecycleTest" />
     </classes>
   </test>
 </suite>

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
index 2ef5e92..bb6b5e5 100644
--- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
+++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
@@ -1276,6 +1276,7 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
 
                 // add WebDeploymentInfo to ContainerSystem
                 final WebContext webContext = new WebContext(appContext);
+                webContext.setServletContext(standardContext.getServletContext());
                 webContext.setJndiEnc(new InitialContext());
                 webContext.setClassLoader(classLoader);
                 webContext.setId(webAppInfo.moduleId);

http://git-wip-us.apache.org/repos/asf/tomee/blob/97b720ed/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cdi/SessionContextBackedByHttpSession.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cdi/SessionContextBackedByHttpSession.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cdi/SessionContextBackedByHttpSession.java
index 7b68988..94c6f02 100644
--- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cdi/SessionContextBackedByHttpSession.java
+++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cdi/SessionContextBackedByHttpSession.java
@@ -18,6 +18,7 @@ package org.apache.tomee.catalina.cdi;
 
 import org.apache.catalina.session.StandardSession;
 import org.apache.catalina.session.StandardSessionFacade;
+import org.apache.openejb.cdi.CdiAppContextsService;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.util.reflection.Reflections;
 import org.apache.webbeans.context.SessionContext;
@@ -34,18 +35,17 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
-public class SessionContextBackedByHttpSession extends SessionContext {
+public class SessionContextBackedByHttpSession extends CdiAppContextsService.HttpSessionContextSessionAware {
     private static final String WRAPPER = SystemInstance.get().getProperty("tomee.session-context.wrapper", "direct");
 
-    private HttpSession session;
-
     public SessionContextBackedByHttpSession(final HttpSession session) {
-        this.session = session;
+        super(session);
         setComponentSessionInstanceMap(); // override default map (set in super())
     }
 
     @SuppressWarnings("unchecked")
     public void setComponentSessionInstanceMap() {
+        HttpSession session = getSession();
         if (session == null) {
             super.setComponentInstanceMap();
             return;
@@ -87,10 +87,6 @@ public class SessionContextBackedByHttpSession extends SessionContext {
         return key.toString(); // shouldn't occur
     }
 
-    public HttpSession getSession() {
-        return session;
-    }
-
     private static class DirectSessionMap implements ConcurrentMap<Contextual<?>, BeanInstanceBag<?>> {
         private final ConcurrentHashMap<String, Object> delegate;