cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dk...@apache.org
Subject 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. Also use java7 nio2 methods for temp files
Date Mon, 18 Jan 2016 19:07:44 GMT
Repository: cxf
Updated Branches:
  refs/heads/master 6cc93fb07 -> 1247e04ec


[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.
Also use java7 nio2 methods for temp files


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

Branch: refs/heads/master
Commit: 1247e04ec9c7472b136b4c5b58ea99324585984e
Parents: 6cc93fb
Author: Daniel Kulp <dkulp@apache.org>
Authored: Mon Jan 18 14:05:58 2016 -0500
Committer: Daniel Kulp <dkulp@apache.org>
Committed: Mon Jan 18 14:07:34 2016 -0500

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


http://git-wip-us.apache.org/repos/asf/cxf/blob/1247e04e/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 773b821..59632e5 100644
--- a/core/src/main/java/org/apache/cxf/helpers/FileUtils.java
+++ b/core/src/main/java/org/apache/cxf/helpers/FileUtils.java
@@ -26,6 +26,8 @@ import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -38,6 +40,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 +87,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,28 +151,40 @@ public final class FileUtils {
                                                            + "little usable temporary space.
 Operations"
                                                            + " requiring temporary files
may fail.");
         }
-        File f = new File(checkExists, "cxf-tmp-" + x);
-        int count = 0;
-        while (!f.mkdir()) {
-            
-            if (count > 10000) {
-                throw new RuntimeException("Could not create a temporary directory in "
-                                           + s + ",  please set java.io.tempdir"
-                                           + " to a writable directory");
+
+        File newTmpDir;
+        try {
+            Path path = Files.createTempDirectory(checkExists.toPath(), "cxf-tmp-");
+            File f = path.toFile();
+            f.deleteOnExit();
+            newTmpDir = f;
+        } catch (IOException ex) {
+            int x = (int)(Math.random() * 1000000);
+            File f = new File(checkExists, "cxf-tmp-" + x);
+            int count = 0;
+            while (!f.mkdir()) {
+                
+                if (count > 10000) {
+                    throw new RuntimeException("Could not create a temporary directory in
"
+                                               + s + ",  please set java.io.tempdir"
+                                               + " to a writable directory");
+                }
+                x = (int)(Math.random() * 1000000);
+                f = new File(checkExists, "cxf-tmp-" + x);
+                count++;
             }
-            x = (int)(Math.random() * 1000000);
-            f = new File(checkExists, "cxf-tmp-" + x);
-            count++;
+            newTmpDir  = f;
+        }
+        if (addHook) {
+            final File f2 = newTmpDir;
+            Thread hook = new Thread() {
+                @Override
+                public void run() {
+                    removeDir(f2, true);
+                }
+            };
+            Runtime.getRuntime().addShutdownHook(hook); 
         }
-        File newTmpDir  = f;
-        final File f2 = f;
-        Thread hook = new Thread() {
-            @Override
-            public void run() {
-                removeDir(f2, true);
-            }
-        };
-        Runtime.getRuntime().addShutdownHook(hook); 
         return newTmpDir;
     }
 
@@ -235,7 +288,7 @@ public final class FileUtils {
         } else if (prefix.length() < 3) {
             prefix = prefix + "cxf";
         }
-        result = File.createTempFile(prefix, suffix, parent);
+        result = Files.createTempFile(parent.toPath(), prefix, suffix).toFile();
 
         //if parentDir is null, we're in our default dir
         //which will get completely wiped on exit from our exit

http://git-wip-us.apache.org/repos/asf/cxf/blob/1247e04e/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 777be3c..2b78fe6 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/1247e04e/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 d1220bc..fe46f4f 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() {


Mime
View raw message