You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2016/01/18 20:22:32 UTC

cxf git commit: [CXF-6749] When using a servlet, attempt to remove the temp dir hook when the servlet is destroyed to prevent a classloader leak. This is an attmempt only and not guaranteed to work.

Repository: cxf
Updated Branches:
  refs/heads/3.0.x-fixes f976a73c4 -> e90072c74


[CXF-6749] When using a servlet, attempt to remove the temp dir hook when the servlet is destroyed to prevent a classloader leak.   This is an attmempt only and not guaranteed to work.


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

Branch: refs/heads/3.0.x-fixes
Commit: e90072c7491745f8b76f6e759f660aeb3930a1e9
Parents: f976a73
Author: Daniel Kulp <dk...@apache.org>
Authored: Mon Jan 18 14:05:58 2016 -0500
Committer: Daniel Kulp <dk...@apache.org>
Committed: Mon Jan 18 14:22:04 2016 -0500

----------------------------------------------------------------------
 .../java/org/apache/cxf/helpers/FileUtils.java  | 63 ++++++++++++++++----
 .../transport/servlet/AbstractHTTPServlet.java  |  5 ++
 .../transport/servlet/CXFNonSpringServlet.java  |  1 +
 3 files changed, 59 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/e90072c7/core/src/main/java/org/apache/cxf/helpers/FileUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/cxf/helpers/FileUtils.java b/core/src/main/java/org/apache/cxf/helpers/FileUtils.java
index 82444d1..a8d3fa5 100644
--- a/core/src/main/java/org/apache/cxf/helpers/FileUtils.java
+++ b/core/src/main/java/org/apache/cxf/helpers/FileUtils.java
@@ -38,6 +38,7 @@ import org.apache.cxf.common.util.SystemPropertyAction;
 public final class FileUtils {
     private static final int RETRY_SLEEP_MILLIS = 10;
     private static File defaultTempDir;
+    private static Thread shutdownHook;
     private static final char[] ILLEGAL_CHARACTERS 
         = {'/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':'};    
     
@@ -84,13 +85,51 @@ public final class FileUtils {
             }
         }
         if (defaultTempDir == null) {
-            defaultTempDir = createTmpDir();         
+            defaultTempDir = createTmpDir(false);
+            if (shutdownHook != null) {
+                Runtime.getRuntime().removeShutdownHook(shutdownHook); 
+            }
+            shutdownHook = new Thread() {
+                @Override
+                public void run() {
+                    removeDir(defaultTempDir, true);
+                }
+            };
+            Runtime.getRuntime().addShutdownHook(shutdownHook); 
+
         }
         return defaultTempDir;
     }
     
+    public static synchronized void maybeDeleteDefaultTempDir() {
+        if (defaultTempDir != null) {
+            Runtime.getRuntime().gc(); // attempt a garbage collect to close any files
+            String files[] = defaultTempDir.list();
+            if (files != null && files.length > 0) {
+                //there are files in there, we need to attempt some more cleanup
+                
+                //HOWEVER, we don't want to just wipe out every file as something may be holding onto
+                //the files for a reason. We'll re-run the gc and run the finalizers to see if 
+                //anything gets cleaned up.
+                Runtime.getRuntime().gc(); // attempt a garbage collect to close any files
+                Runtime.getRuntime().runFinalization(); 
+                Runtime.getRuntime().gc();
+                files = defaultTempDir.list();
+            }
+            if (files == null || files.length == 0) {
+                //all the files are gone, we can remove the shutdownhook and reset
+                Runtime.getRuntime().removeShutdownHook(shutdownHook);
+                shutdownHook.run();
+                shutdownHook = null;
+                defaultTempDir = null;
+            }
+        }
+    }
+    
     public static File createTmpDir() {
-        int x = (int)(Math.random() * 1000000);
+        return createTmpDir(true);
+    }
+    public static File createTmpDir(boolean addHook) {
         String s = SystemPropertyAction.getProperty("java.io.tmpdir");
         File checkExists = new File(s);
         if (!checkExists.exists() || !checkExists.isDirectory()) {
@@ -110,6 +149,8 @@ public final class FileUtils {
                                                            + "little usable temporary space.  Operations"
                                                            + " requiring temporary files may fail.");
         }
+
+        int x = (int)(Math.random() * 1000000);
         File f = new File(checkExists, "cxf-tmp-" + x);
         int count = 0;
         while (!f.mkdir()) {
@@ -124,14 +165,16 @@ public final class FileUtils {
             count++;
         }
         File newTmpDir  = f;
-        final File f2 = f;
-        Thread hook = new Thread() {
-            @Override
-            public void run() {
-                removeDir(f2, true);
-            }
-        };
-        Runtime.getRuntime().addShutdownHook(hook); 
+        if (addHook) {
+            final File f2 = newTmpDir;
+            Thread hook = new Thread() {
+                @Override
+                public void run() {
+                    removeDir(f2, true);
+                }
+            };
+            Runtime.getRuntime().addShutdownHook(hook); 
+        }
         return newTmpDir;
     }
 

http://git-wip-us.apache.org/repos/asf/cxf/blob/e90072c7/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractHTTPServlet.java
----------------------------------------------------------------------
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractHTTPServlet.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractHTTPServlet.java
index e1f6af5..29b158d 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractHTTPServlet.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/AbstractHTTPServlet.java
@@ -52,6 +52,7 @@ import org.apache.cxf.common.i18n.BundleUtils;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.common.util.PropertyUtils;
 import org.apache.cxf.common.util.StringUtils;
+import org.apache.cxf.helpers.FileUtils;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.resource.ResourceManager;
 import org.apache.cxf.transport.http.AbstractHTTPDestination;
@@ -119,6 +120,10 @@ public abstract class AbstractHTTPServlet extends HttpServlet implements Filter
         useXForwardedHeaders = Boolean.valueOf(servletConfig.getInitParameter(USE_X_FORWARDED_HEADERS_PARAMETER));
     }
     
+    public void destroy() {
+        FileUtils.maybeDeleteDefaultTempDir();
+    }
+    
     protected void finalizeServletInit(ServletConfig servletConfig) {
         InputStream is = getResourceAsStream("/WEB-INF" + STATIC_RESOURCES_MAP_RESOURCE);
         if (is == null) {

http://git-wip-us.apache.org/repos/asf/cxf/blob/e90072c7/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java
----------------------------------------------------------------------
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java
index 86b0470..829bbf6 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java
@@ -202,6 +202,7 @@ public class CXFNonSpringServlet extends AbstractHTTPServlet {
             destinationRegistry = null;
         }
         destroyBus();
+        super.destroy();
     }
     
     public void destroyBus() {