You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by gd...@apache.org on 2008/12/10 16:45:38 UTC

svn commit: r725315 - in /webservices/axis2/trunk/java/modules: kernel/src/org/apache/axis2/classloader/ kernel/src/org/apache/axis2/deployment/util/ osgi/

Author: gdaniels
Date: Wed Dec 10 07:45:38 2008
New Revision: 725315

URL: http://svn.apache.org/viewvc?rev=725315&view=rev
Log:
* Fix the build (hmm... looks like someone didn't test everything)

* Improve https://issues.apache.org/jira/browse/AXIS2-3883 by using a TempFileManager to a) clean up the structure of temp files (it's now one directory per instance/jvm), and b) get rid of stale files each time the system starts up.  This is a temporary solution to a larger problem but should help.

* Some code cleanup

Added:
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/TempFileManager.java
Modified:
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/classloader/JarFileClassLoader.java
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java
    webservices/axis2/trunk/java/modules/osgi/pom.xml

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/classloader/JarFileClassLoader.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/classloader/JarFileClassLoader.java?rev=725315&r1=725314&r2=725315&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/classloader/JarFileClassLoader.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/classloader/JarFileClassLoader.java Wed Dec 10 07:45:38 2008
@@ -218,8 +218,7 @@
             return null;
         }
 
-        String path = new File(URI.create(url.toString())).getPath();
-        return path;
+        return new File(URI.create(url.toString())).getPath();
     }
 
     /**
@@ -275,8 +274,7 @@
                     CodeSource codeSource = new CodeSource(codeSourceUrl, certificates);
 
                     // load the class into the vm
-                    Class clazz = defineClass(className, bytes, 0, bytes.length, codeSource);
-                    return clazz;
+                    return defineClass(className, bytes, 0, bytes.length, codeSource);
                 }
             }, acc);
         } catch (PrivilegedActionException e) {
@@ -342,9 +340,6 @@
 
     private boolean isSealed(Attributes packageAttributes, Attributes mainAttributes) {
         String sealed = getAttribute(Attributes.Name.SEALED, packageAttributes, mainAttributes);
-        if (sealed == null) {
-            return false;
-        }
-        return "true".equalsIgnoreCase(sealed);
+        return sealed != null && "true".equalsIgnoreCase(sealed);
     }
 }
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/TempFileManager.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/TempFileManager.java?rev=725315&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/TempFileManager.java (added)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/TempFileManager.java Wed Dec 10 07:45:38 2008
@@ -0,0 +1,223 @@
+/*
+ * 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.axis2.deployment.util;
+
+import java.io.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * Generates and properly cleans up temporary files. Similar to {@link
+ * File#createTempFile(java.lang.String, java.lang.String)}, this class provides a static method to
+ * create temporary files. The temporary files will be created in a special directory to be cleaned
+ * up the next time this class is loaded by the JVM. This functionality is required because Win32
+ * platforms will not allow the JVM to delete files that are open. This causes problems with items
+ * such as JARs that get opened by a URLClassLoader and can therefore not be deleted by the JVM
+ * (including deleteOnExit).
+ * <p/>
+ * The caller should not need to create an instance of this class, although it is possible. Simply
+ * use the static methods to perform the required operations. Note that all files created by this
+ * class should be considered as deleted at JVM exit (although the actual deletion may be delayed).
+ * If persistent temporary files are required, use {@link java.io.File} instead.
+ * <p/>
+ * Refer to Sun bugs 4171239 and 4950148 for more details.
+ * <p/>
+ * Thanks to Mike Pilone for this code, which was sourced from
+ * http://www.devx.com/Java/Article/22018/ and contributed to Apache.
+ */
+
+public class TempFileManager {
+
+    /**
+     * Creates a temporary file in the proper directory to allow for cleanup after execution. This
+     * method delegates to {@link File#createTempFile(java.lang.String, java.lang.String,
+     * java.io.File)} so refer to it for more documentation. Any file created using this method should
+     * be considered as deleted at JVM exit; therefore, do not use this method to create files that
+     * need to be persistent between application runs.
+     *
+     * @param prefix the prefix string used in generating the file name; must be at least three
+     *               characters long
+     * @param suffix the suffix string to be used in generating the file's name; may be null, in which
+     *               case the suffix ".tmp" will be used
+     * @return an abstract pathname denoting a newly created empty file
+     * @throws IOException if a file could not be created
+     */
+    @SuppressWarnings({"ResultOfMethodCallIgnored"})
+    public static File createTempFile(String prefix, String suffix)
+            throws IOException {
+        // Check to see if you have already initialized a temp directory
+        // for this class.
+        if (sTmpDir == null) {
+            // Initialize your temp directory. You use the java temp directory
+            // property, so you are sure to find the files on the next run.
+            String tmpDirName = System.getProperty("java.io.tmpdir");
+            File tmpDir = File.createTempFile(TEMP_DIR_PREFIX, ".tmp",
+                                              new File(tmpDirName));
+
+            // Delete the file if one was automatically created by the JVM.
+            // You are going to use the name of the file as a directory name,
+            // so you do not want the file laying around.
+            tmpDir.delete();
+
+            // Create a lock before creating the directory so
+            // there is no race condition with another application trying
+            // to clean your temp dir.
+            File lockFile = new File(tmpDirName, tmpDir.getName() + ".lck");
+            lockFile.createNewFile();
+
+            // Set the lock file to delete on exit so it is properly cleaned
+            // by the JVM. This will allow the TempFileManager to clean
+            // the overall temp directory next time.
+            lockFile.deleteOnExit();
+
+            // Make a temp directory that you will use for all future requests.
+            if (!tmpDir.mkdirs()) {
+                throw new IOException("Unable to create temporary directory:"
+                                      + tmpDir.getAbsolutePath());
+            }
+
+            sTmpDir = tmpDir;
+        }
+
+        // Generate a temp file for the user in your temp directory
+        // and return it.
+        return File.createTempFile(prefix, suffix, sTmpDir);
+    }
+
+
+    /**
+     * Utility method to load the TempFileManager at any time and allow it to clean the temporary
+     * files that may be left from previous instances
+     *
+     * @param args command line arguments are currently not supported
+     */
+    public static void main(String[] args) {
+        // Although the JVM will load the class in order to
+        // run the main method, this gives a little clarity to
+        // what is happening and why we want the main method.
+        try {
+            // This will load the TempFileManager, which will
+            // cause the static block to execute, cleaning
+            // any old temp files.
+            Class.forName(TempFileManager.class.getName());
+        }
+        catch (ClassNotFoundException ex) {
+            ex.printStackTrace();
+        }
+    }
+
+
+    /**
+     * Deletes all of the files in the given directory, recursing into any sub directories found. Also
+     * deletes the root directory.
+     *
+     * @param rootDir the root directory to be recursively deleted
+     * @throws IOException if any file or directory could not be deleted
+     */
+    private static void recursiveDelete(File rootDir)
+            throws IOException {
+        // Select all the files
+        File[] files = rootDir.listFiles();
+        for (File file : files) {
+            // If the file is a directory, we will
+            // recursively call delete on it.
+            if (file.isDirectory()) {
+                recursiveDelete(file);
+            } else {
+                // It is just a file so we are safe to
+                // delete it
+                if (!file.delete()) {
+                    throw new IOException("Could not delete: " + file.getAbsolutePath());
+                }
+            }
+        }
+
+        // Finally, delete the root directory now
+        // that all of the files in the directory have
+        // been properly deleted.
+        if (!rootDir.delete()) {
+            throw new IOException("Could not delete: " + rootDir.getAbsolutePath());
+        }
+    }
+
+
+    /** The prefix for the temp directory in the system temp directory */
+    private final static String TEMP_DIR_PREFIX = "axis2-tmp-";
+
+    /** The temp directory to generate all files in */
+    private static File sTmpDir = null;
+
+    /**
+     *  Static block used to clean up any old temp directories found -- the JVM
+     *  will run this block when a class loader loads the class.
+     */
+    static {
+        // Clean up any old temp directories by listing
+        // all of the files, using a filter that will
+        // return only directories that start with your
+        // prefix.
+        FileFilter tmpDirFilter =
+                new FileFilter() {
+                    public boolean accept(File pathname) {
+                        return (pathname.isDirectory() &&
+                                pathname.getName().startsWith(TEMP_DIR_PREFIX));
+                    }
+                };
+
+        // Get the system temp directory and filter the files.
+        String tmpDirName = System.getProperty("java.io.tmpdir");
+        File tmpDir = new File(tmpDirName);
+        File[] tmpFiles = tmpDir.listFiles(tmpDirFilter);
+
+        // Find all the files that do not have a lock by
+        // checking if the lock file exists.
+        for (File tmpFile : tmpFiles) {
+            // Create a file to represent the lock and test.
+            File lockFile = new File(tmpFile.getParent(), tmpFile.getName() + ".lck");
+            if (!lockFile.exists()) {
+                // Delete the contents of the directory since
+                // it is no longer locked.
+                Logger.getLogger("default").log(Level.FINE,
+                                                "TempFileManager::deleting old temp directory " +
+                                                tmpFile);
+
+                try {
+                    recursiveDelete(tmpFile);
+                }
+                catch (IOException ex) {
+                    // You log at a fine level since not being able to delete
+                    // the temp directory should not stop the application
+                    // from performing correctly. However, if the application
+                    // generates a lot of temp files, this could become
+                    // a disk space problem and the level should be raised.
+                    Logger.getLogger("default").log(Level.INFO,
+                                                    "TempFileManager::unable to delete " +
+                                                    tmpFile.getAbsolutePath());
+
+                    // Print the exception.
+                    ByteArrayOutputStream ostream = new ByteArrayOutputStream();
+                    ex.printStackTrace(new PrintStream(ostream));
+
+                    Logger.getLogger("default").log(Level.FINE, ostream.toString());
+                }
+            }
+        }
+    }
+}

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java?rev=725315&r1=725314&r2=725315&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/deployment/util/Utils.java Wed Dec 10 07:45:38 2008
@@ -221,68 +221,72 @@
                                       final File tmpDir) throws IOException {
         byte data[] = new byte[2048];
         int count;
-        File f;
-        if (tmpDir == null) {
-            String directory = (String)org.apache.axis2.java.security.AccessController
-                    .doPrivileged(new PrivilegedAction() {
-                        public Object run() {
-                            return System.getProperty("java.io.tmpdir");
-                        }
-                    });
-            final File tempFile = new File(directory, "_axis2");
-            Boolean exists = (Boolean)org.apache.axis2.java.security.AccessController
-                    .doPrivileged(new PrivilegedAction() {
-                        public Object run() {
-                            return tempFile.exists();
-                        }
-                    });
-            if (!exists) {
-                Boolean mkdirs = (Boolean)org.apache.axis2.java.security.AccessController
-                        .doPrivileged(new PrivilegedAction() {
-                            public Object run() {
-                                return tempFile.mkdirs();
-                            }
-                        });
-                if (!mkdirs) {
-                    throw new IOException("Unable to create the directory");
-                }
-            }
-            try {
-                f = (File)org.apache.axis2.java.security.AccessController
-                        .doPrivileged(new PrivilegedExceptionAction() {
-                            public Object run() throws IOException {
-                                return File.createTempFile("axis2", suffix,
-                                                           tempFile);
-                            }
-                        });
-            } catch (PrivilegedActionException e) {
-                throw (IOException)e.getException();
-            }
-        } else {
-            try {
-                f = (File)org.apache.axis2.java.security.AccessController
-                        .doPrivileged(new PrivilegedExceptionAction() {
-                            public Object run() throws IOException {
-                                return File.createTempFile("axis2", suffix,
-                                                           tmpDir);
-                            }
-                        });
-            } catch (PrivilegedActionException e) {
-                throw (IOException)e.getException();
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug("Created temporary file : " + f.getAbsolutePath());// $NON-SEC-4
-        }
-        final File f2 = f;
-        org.apache.axis2.java.security.AccessController
-                .doPrivileged(new PrivilegedAction() {
-                    public Object run() {
-                        f2.deleteOnExit();
-                        return null;
-                    }
-                });
+        File f = TempFileManager.createTempFile("axis2", suffix);
+        
+//        if (tmpDir == null) {
+//            String directory = (String)org.apache.axis2.java.security.AccessController
+//                    .doPrivileged(new PrivilegedAction() {
+//                        public Object run() {
+//                            return System.getProperty("java.io.tmpdir");
+//                        }
+//                    });
+//            final File tempFile = new File(directory, "_axis2");
+//            Boolean exists = (Boolean)org.apache.axis2.java.security.AccessController
+//                    .doPrivileged(new PrivilegedAction() {
+//                        public Object run() {
+//                            return tempFile.exists();
+//                        }
+//                    });
+//            if (!exists) {
+//                Boolean mkdirs = (Boolean)org.apache.axis2.java.security.AccessController
+//                        .doPrivileged(new PrivilegedAction() {
+//                            public Object run() {
+//                                return tempFile.mkdirs();
+//                            }
+//                        });
+//                if (!mkdirs) {
+//                    throw new IOException("Unable to create the directory");
+//                }
+//            }
+//            try {
+//                f = (File)org.apache.axis2.java.security.AccessController
+//                        .doPrivileged(new PrivilegedExceptionAction() {
+//                            public Object run() throws IOException {
+//                                return File.createTempFile("axis2", suffix,
+//                                                           tempFile);
+//                            }
+//                        });
+//                f.deleteOnExit();
+//            } catch (PrivilegedActionException e) {
+//                throw (IOException)e.getException();
+//            }
+//        } else {
+//            try {
+//                f = (File)org.apache.axis2.java.security.AccessController
+//                        .doPrivileged(new PrivilegedExceptionAction() {
+//                            public Object run() throws IOException {
+//                                return File.createTempFile("axis2", suffix,
+//                                                           tmpDir);
+//                            }
+//                        });
+//                f.deleteOnExit();
+//            } catch (PrivilegedActionException e) {
+//                throw (IOException)e.getException();
+//            }
+//        }
+//        if (log.isDebugEnabled()) {
+//            log.debug("Created temporary file : " + f.getAbsolutePath());// $NON-SEC-4
+//        }
+//        final File f2 = f;
+//        org.apache.axis2.java.security.AccessController
+//                .doPrivileged(new PrivilegedAction() {
+//                    public Object run() {
+//                        f2.deleteOnExit();
+//                        return null;
+//                    }
+//                });
         FileOutputStream out;
+        final File f2 = f;
         try {
             out = (FileOutputStream)org.apache.axis2.java.security.AccessController
                     .doPrivileged(new PrivilegedExceptionAction() {

Modified: webservices/axis2/trunk/java/modules/osgi/pom.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/osgi/pom.xml?rev=725315&r1=725314&r2=725315&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/osgi/pom.xml (original)
+++ webservices/axis2/trunk/java/modules/osgi/pom.xml Wed Dec 10 07:45:38 2008
@@ -67,6 +67,7 @@
                             javax.xml.namespace; version=0.0.0,
                             javax.servlet; version=2.4.0,
                             javax.servlet.http; version=2.4.0,
+                            javax.transaction,
                             org.apache.commons.io,
                             org.osgi.framework; version=1.3.0,
                             org.osgi.service.http; version=1.2.0,