Author: noel
Date: Wed Aug  2 21:53:49 2006
New Revision: 428237

URL: http://svn.apache.org/viewvc?rev=428237&view=rev
Log:
JAMES-585.  This change consists of the following changes:

  1) RemoteManagerHander.java
     Added two UNDOCUMENTED commands:
       1) SHOWTRACKERS - Call the FileCleaner to display
          a list of files that it is tracking to delete.
       2) GC - Force a JVM garbage collection, which will
          normally cause the FileCleaner to delete files
          whose marker object (MimeMessageInputStreamSource
          in our case) is not currently reachable.

  2) MimeMessageInputStreamSource.java
     Three changes:
       1) Register all temporary files with FileCleaner.
       2) At Stefano's suggestion, revert change to use
          SharedFileInputStream,
       3) Comment out finalize(), which is replaced by
          using FileCleaner. The mere presence of the
          finalize() method can actually cause problems.

  3) FileCleaner
     Two changes from what I copied from Commons I/O:
       1) Add some instrumentation to let us inspect the
          state of the tracker collection.
       2) Print (to System.err, normally redirected to
          ${JAMES}/temp/phoenix.console) an error if
          we cannot delete the file when asked.
     In both cases, a stack trace is used to let us see
     how the file was allocated, just to make sure that
     we're not missing something about the behavior.

So far, with these changes I am no longer seeing any leaks.  A few times, there 
were some files still around, but forcing a GC cleaned them up.  The 
instrumentation was added to help investigate this behavior.

Modified:
    
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageInputStreamSource.java
    
james/server/branches/v2.3/src/java/org/apache/james/remotemanager/RemoteManagerHandler.java
    
james/server/branches/v2.3/src/java/org/apache/james/util/io/FileCleaner.java

Modified: 
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageInputStreamSource.java
URL: 
http://svn.apache.org/viewvc/james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageInputStreamSource.java?rev=428237&r1=428236&r2=428237&view=diff
==============================================================================
--- 
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageInputStreamSource.java
 (original)
+++ 
james/server/branches/v2.3/src/java/org/apache/james/core/MimeMessageInputStreamSource.java
 Wed Aug  2 21:53:49 2006
@@ -71,6 +71,7 @@
         OutputStream fout = null;
         try {
             file = File.createTempFile(key, ".m64");
+            org.apache.james.util.io.FileCleaner.track(file, this);
             fout = new BufferedOutputStream(new FileOutputStream(file));
             int b = -1;
             while ((b = in.read()) != -1) {
@@ -115,7 +116,7 @@
      * @return a <code>BufferedInputStream</code> containing the data
      */
     public synchronized InputStream getInputStream() throws IOException {
-        return new SharedFileInputStream(file);
+        return new java.io.BufferedInputStream(new 
java.io.FileInputStream(file));
     }
 
     /**
@@ -149,11 +150,9 @@
      * formal mechanism for cleanup through use of the dispose() method.
      * @throws Throwable 
      *
-     */
     public void finalize() throws Throwable {
         dispose();
         super.finalize();
     }
-    
-
+     */
 }

Modified: 
james/server/branches/v2.3/src/java/org/apache/james/remotemanager/RemoteManagerHandler.java
URL: 
http://svn.apache.org/viewvc/james/server/branches/v2.3/src/java/org/apache/james/remotemanager/RemoteManagerHandler.java?rev=428237&r1=428236&r2=428237&view=diff
==============================================================================
--- 
james/server/branches/v2.3/src/java/org/apache/james/remotemanager/RemoteManagerHandler.java
 (original)
+++ 
james/server/branches/v2.3/src/java/org/apache/james/remotemanager/RemoteManagerHandler.java
 Wed Aug  2 21:53:49 2006
@@ -391,6 +391,12 @@
         command = command.toUpperCase(Locale.US);
         if (command.equals(COMMAND_ADDUSER)) {
             doADDUSER(argument);
+        } else if (command.equals("SHOWTRACKERS")) {
+            org.apache.james.util.io.FileCleaner.dump(out);
+            return true;
+        } else if (command.equals("GC")) {
+            System.gc();
+            return true;
         } else if (command.equals(COMMAND_SETPASSWORD)) {
             return doSETPASSWORD(argument);
         } else if (command.equals(COMMAND_DELUSER)) {

Modified: 
james/server/branches/v2.3/src/java/org/apache/james/util/io/FileCleaner.java
URL: 
http://svn.apache.org/viewvc/james/server/branches/v2.3/src/java/org/apache/james/util/io/FileCleaner.java?rev=428237&r1=428236&r2=428237&view=diff
==============================================================================
--- 
james/server/branches/v2.3/src/java/org/apache/james/util/io/FileCleaner.java 
(original)
+++ 
james/server/branches/v2.3/src/java/org/apache/james/util/io/FileCleaner.java 
Wed Aug  2 21:53:49 2006
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Copyright 2004 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,9 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.io;
+
+package org.apache.james.util.io;
 
 import java.io.File;
+import java.io.PrintWriter;
 import java.lang.ref.PhantomReference;
 import java.lang.ref.ReferenceQueue;
 import java.util.Collection;
@@ -112,6 +114,16 @@
         return trackers.size();
     }
 
+    static public void dump(PrintWriter os) {
+        java.util.Iterator tracker = trackers.iterator();
+        if (tracker.hasNext()) {
+            os.println("--------------------------");
+            os.println("Outstanding File Trackers:");
+            while (tracker.hasNext()) ((Tracker)tracker.next()).dump(os);
+            os.println("--------------------------");
+        }
+    }
+
     /**
      * Inner class which acts as the reference for a file pending deletion.
      */
@@ -122,6 +134,13 @@
          */
         private String path;
 
+        private Throwable record = new Throwable();
+
+        public void dump(PrintWriter os) {
+            os.println(path + " allocated at:");
+            record.printStackTrace(os);
+        }
+
         /**
          * Constructs an instance of this class from the supplied parameters.
          *
@@ -152,7 +171,14 @@
          *         <code>false</code> otherwise.
          */
         public boolean delete() {
-            return new File(path).delete();
+            File f = new File(path);
+            if (!f.exists() || f.delete()) return true;
+            else {
+                System.err.println("FileCleaner could not delete " + path);
+                System.err.println("File " + path + " was allocated by:");
+                record.printStackTrace(System.err);
+                return false;
+            }
         }
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to