Author: scolebourne Date: Sat Oct 7 04:56:25 2006 New Revision: 453889 URL: http://svn.apache.org/viewvc?view=rev&rev=453889 Log: IO-93 - FileSystemUtils - Fixed resource leak leading to 'Too many open files' error - Previously did not destroy Process instances (as JDK Javadoc is so poor) - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4801027
Modified: jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileSystemUtils.java jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileSystemUtilsTestCase.java Modified: jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt URL: http://svn.apache.org/viewvc/jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt?view=diff&rev=453889&r1=453888&r2=453889 ============================================================================== --- jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt (original) +++ jakarta/commons/proper/io/trunk/RELEASE-NOTES.txt Sat Oct 7 04:56:25 2006 @@ -51,6 +51,11 @@ - FileSystemUtils.freeSpace [IO-91] - This is now documented not to work on SunOS 5 +- FileSystemUtils [IO-93] + - Fixed resource leak leading to 'Too many open files' error + - Previously did not destroy Process instances (as JDK Javadoc is so poor) + - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4801027 + - FileCleaner - This now handles the situation where an error occurs when deleting the file Modified: jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileSystemUtils.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileSystemUtils.java?view=diff&rev=453889&r1=453888&r2=453889 ============================================================================== --- jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileSystemUtils.java (original) +++ jakarta/commons/proper/io/trunk/src/java/org/apache/commons/io/FileSystemUtils.java Sat Oct 7 04:56:25 2006 @@ -18,7 +18,9 @@ import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -113,8 +115,8 @@ * As this is not very useful, this method is deprecated in favour * of [EMAIL PROTECTED] #freeSpaceKb(String)} which returns a result in kilobytes. * <p> - * Note that some OS's are NOT currently supported, including OS/390 - * and SunOS 5. (SunOS is supported by <code>freeSpaceKb</code>.) + * Note that some OS's are NOT currently supported, including OS/390, + * OpenVMS and and SunOS 5. (SunOS is supported by <code>freeSpaceKb</code>.) * <pre> * FileSystemUtils.freeSpace("C:"); // Windows * FileSystemUtils.freeSpace("/volume"); // *nix @@ -374,6 +376,7 @@ } } + //----------------------------------------------------------------------- /** * Performs the os command. * @@ -383,16 +386,31 @@ * @throws IOException if an error occurs */ List performCommand(String[] cmdAttribs, int max) throws IOException { - List lines = new ArrayList(); - BufferedReader in = null; + // this method does what it can to avoid the 'Too many open files' error + // based on trial and error and these links: + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4784692 + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4801027 + // http://forum.java.sun.com/thread.jspa?threadID=533029&messageID=2572018 + // however, its still not perfect as the JDK support is so poor + // (see commond-exec or ant for a better multi-threaded multi-os solution) + + List lines = new ArrayList(20); + Process proc = null; + InputStream in = null; + OutputStream out = null; + InputStream err = null; + BufferedReader inr = null; try { - Process proc = openProcess(cmdAttribs); - in = openProcessStream(proc); - String line = in.readLine(); + proc = openProcess(cmdAttribs); + in = proc.getInputStream(); + out = proc.getOutputStream(); + err = proc.getErrorStream(); + inr = new BufferedReader(new InputStreamReader(in)); + String line = inr.readLine(); while (line != null && lines.size() < max) { line = line.toLowerCase().trim(); lines.add(line); - line = in.readLine(); + line = inr.readLine(); } proc.waitFor(); @@ -416,6 +434,12 @@ "' for command " + Arrays.asList(cmdAttribs)); } finally { IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(err); + IOUtils.closeQuietly(inr); + if (proc != null) { + proc.destroy(); + } } } @@ -428,18 +452,6 @@ */ Process openProcess(String[] cmdAttribs) throws IOException { return Runtime.getRuntime().exec(cmdAttribs); - } - - /** - * Opens the stream to the operating system. - * - * @param proc the process - * @return a reader - * @throws IOException if an error occurs - */ - BufferedReader openProcessStream(Process proc) throws IOException { - return new BufferedReader( - new InputStreamReader(proc.getInputStream())); } } Modified: jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileSystemUtilsTestCase.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileSystemUtilsTestCase.java?view=diff&rev=453889&r1=453888&r2=453889 ============================================================================== --- jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileSystemUtilsTestCase.java (original) +++ jakarta/commons/proper/io/trunk/src/test/org/apache/commons/io/FileSystemUtilsTestCase.java Sat Oct 7 04:56:25 2006 @@ -17,12 +17,12 @@ package org.apache.commons.io; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.StringReader; import junit.framework.Test; import junit.framework.TestSuite; @@ -479,17 +479,17 @@ //----------------------------------------------------------------------- static class MockFileSystemUtils extends FileSystemUtils { private final int exitCode; - private final StringReader reader; + private final byte[] bytes; private final String cmd; public MockFileSystemUtils(int exitCode, String lines) { this(exitCode, lines, null); } public MockFileSystemUtils(int exitCode, String lines, String cmd) { this.exitCode = exitCode; - this.reader = new StringReader(lines); + this.bytes = lines.getBytes(); this.cmd = cmd; } - protected Process openProcess(String[] params) { + Process openProcess(String[] params) { if (cmd != null) { assertEquals(cmd, params[params.length - 1]); } @@ -498,7 +498,7 @@ return null; } public InputStream getInputStream() { - return null; + return new ByteArrayInputStream(bytes); } public OutputStream getOutputStream() { return null; @@ -512,9 +512,6 @@ public void destroy() { } }; - } - protected BufferedReader openProcessStream(Process p) { - return new BufferedReader(reader); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]