You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2006/10/07 13:56:26 UTC

svn commit: r453889 - in /jakarta/commons/proper/io/trunk: RELEASE-NOTES.txt src/java/org/apache/commons/io/FileSystemUtils.java src/test/org/apache/commons/io/FileSystemUtilsTestCase.java

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 {@link #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: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org