You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by st...@apache.org on 2015/05/17 13:21:17 UTC
[31/37] tomee git commit: TOMEE-1572 add a ThreadBindingListener to
prevent mem leaks in async servlet requests
TOMEE-1572 add a ThreadBindingListener to prevent mem leaks in async servlet requests
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/c8c7f5c9
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/c8c7f5c9
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/c8c7f5c9
Branch: refs/heads/master
Commit: c8c7f5c91a94ed3c40f42b8e635cb0e6bb9aaae5
Parents: ac291b9
Author: Mark Struberg <st...@apache.org>
Authored: Thu May 14 18:50:14 2015 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Thu May 14 18:50:14 2015 +0200
----------------------------------------------------------------------
.../tomee/catalina/TomcatWebAppBuilder.java | 8 +++
.../cdi/WebBeansThreadBindingListener.java | 56 ++++++++++++++++++++
2 files changed, 64 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tomee/blob/c8c7f5c9/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 8137673..a64dab3 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
@@ -79,6 +79,7 @@ import org.apache.openejb.assembler.classic.WebAppBuilder;
import org.apache.openejb.assembler.classic.WebAppInfo;
import org.apache.openejb.assembler.classic.event.NewEjbAvailableAfterApplicationCreated;
import org.apache.openejb.cdi.CdiBuilder;
+import org.apache.openejb.cdi.OWBContextThreadListener;
import org.apache.openejb.cdi.OpenEJBLifecycle;
import org.apache.openejb.cdi.Proxys;
import org.apache.openejb.config.AppModule;
@@ -118,6 +119,7 @@ import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.apache.tomcat.util.descriptor.web.ResourceBase;
import org.apache.tomcat.util.scan.StandardJarScanFilter;
import org.apache.tomee.catalina.cdi.ServletContextHandler;
+import org.apache.tomee.catalina.cdi.WebBeansThreadBindingListener;
import org.apache.tomee.catalina.cluster.ClusterObserver;
import org.apache.tomee.catalina.cluster.TomEEClusterListener;
import org.apache.tomee.catalina.environment.Hosts;
@@ -1678,6 +1680,12 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare
newLifecycleListeners[newLifecycleListeners.length - 1] = endWebBeansListener;
standardContext.setApplicationLifecycleListeners(newLifecycleListeners);
}
+
+ // also add the ThreadBindingListener to clean up async thread executions
+ {
+ WebBeansThreadBindingListener webBeansThreadBindingListener = new WebBeansThreadBindingListener(webBeansContext, standardContext.getThreadBindingListener());
+ standardContext.setThreadBindingListener(webBeansThreadBindingListener);
+ }
} else {
// just add the end listener to be able to stack tasks to execute at the request end
final EndWebBeansListener endWebBeansListener = new EndWebBeansListener(webBeansContext);
http://git-wip-us.apache.org/repos/asf/tomee/blob/c8c7f5c9/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cdi/WebBeansThreadBindingListener.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cdi/WebBeansThreadBindingListener.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cdi/WebBeansThreadBindingListener.java
new file mode 100644
index 0000000..10bb76a
--- /dev/null
+++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cdi/WebBeansThreadBindingListener.java
@@ -0,0 +1,56 @@
+/**
+ * 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.cdi;
+
+import javax.enterprise.context.RequestScoped;
+
+import org.apache.catalina.ThreadBindingListener;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.spi.ContextsService;
+
+/**
+ * For Tomcat we need to implement a ThreadBindingListener to
+ * release the ServletRequest in case of Async requests.
+ * Tomcat only sends the requestDestroyed event only when the 'final'
+ * detached response gets rendered. But this happens on a totally
+ * different Thread.
+ * Thus in order to release e.g. locks on Conversations and prevent mem leaks
+ * we need to end the request on unbind() as well.
+ * Note that the ContextsService will do nothing if the Request was already
+ * properly destroyed in standard synchronous Servlet Requests.
+ */
+public class WebBeansThreadBindingListener implements ThreadBindingListener {
+
+ private final ContextsService contextsService;
+ private final ThreadBindingListener delegate;
+
+ public WebBeansThreadBindingListener(WebBeansContext webBeansContext, ThreadBindingListener delegate) {
+ this.contextsService = webBeansContext.getContextsService();
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void bind() {
+ delegate.bind();
+ }
+
+ @Override
+ public void unbind() {
+ contextsService.endContext(RequestScoped.class, null);
+ delegate.unbind();
+ }
+}