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]