Author: gnodet
Date: Mon Nov 29 10:07:27 2010
New Revision: 1040053

URL: http://svn.apache.org/viewvc?rev=1040053&view=rev
Log:
[KARAF-282] The shell:exec may not capture the whole output

Added:
    karaf/trunk/util/src/main/java/org/apache/karaf/util/process/
    
karaf/trunk/util/src/main/java/org/apache/karaf/util/process/PumpStreamHandler.java
      - copied, changed from r1040052, 
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/PumpStreamHandler.java
    
karaf/trunk/util/src/main/java/org/apache/karaf/util/process/StreamPumper.java
      - copied, changed from r1040052, 
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/StreamPumper.java
Removed:
    
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/PumpStreamHandler.java
    
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/StreamPumper.java
Modified:
    
karaf/trunk/itests/kittests/src/test/java/org/apache/karaf/kittests/Helper.java
    karaf/trunk/shell/commands/pom.xml
    
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/ExecuteAction.java
    karaf/trunk/shell/wrapper/pom.xml
    
karaf/trunk/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/PumpStreamHandler.java

Modified: 
karaf/trunk/itests/kittests/src/test/java/org/apache/karaf/kittests/Helper.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/itests/kittests/src/test/java/org/apache/karaf/kittests/Helper.java?rev=1040053&r1=1040052&r2=1040053&view=diff
==============================================================================
--- 
karaf/trunk/itests/kittests/src/test/java/org/apache/karaf/kittests/Helper.java 
(original)
+++ 
karaf/trunk/itests/kittests/src/test/java/org/apache/karaf/kittests/Helper.java 
Mon Nov 29 10:07:27 2010
@@ -24,9 +24,7 @@ import org.apache.commons.compress.compr
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.felix.utils.properties.InterpolationHelper;
-import org.apache.karaf.admin.Instance;
-import org.apache.karaf.admin.internal.InstanceImpl;
-import org.apache.karaf.shell.commands.utils.StreamPumper;
+import org.apache.karaf.util.process.PumpStreamHandler;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -39,10 +37,7 @@ import java.io.OutputStream;
 import java.net.Socket;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -343,202 +338,4 @@ public final class Helper {
         }
     }
 
-    public static class PumpStreamHandler
-    {
-        private InputStream in;
-
-        private OutputStream out;
-
-        private OutputStream err;
-
-        private Thread outputThread;
-
-        private Thread errorThread;
-
-        private StreamPumper inputPump;
-
-        //
-        // NOTE: May want to use a ThreadPool here, 3 threads per/pair seems 
kinda expensive :-(
-        //
-
-        public PumpStreamHandler(final InputStream in, final OutputStream out, 
final OutputStream err) {
-            assert in != null;
-            assert out != null;
-            assert err != null;
-
-            this.in = in;
-            this.out = out;
-            this.err = err;
-        }
-
-        public PumpStreamHandler(final OutputStream out, final OutputStream 
err) {
-            this(null, out, err);
-        }
-
-        public PumpStreamHandler(final OutputStream outAndErr) {
-            this(outAndErr, outAndErr);
-        }
-
-        /**
-         * Set the input stream from which to read the standard output of the 
child.
-         */
-        public void setChildOutputStream(final InputStream in) {
-            assert in != null;
-
-            createChildOutputPump(in, out);
-        }
-
-        /**
-         * Set the input stream from which to read the standard error of the 
child.
-         */
-        public void setChildErrorStream(final InputStream in) {
-            assert in != null;
-
-            if (err != null) {
-                createChildErrorPump(in, err);
-            }
-        }
-
-        /**
-         * Set the output stream by means of which input can be sent to the 
child.
-         */
-        public void setChildInputStream(final OutputStream out) {
-            assert out != null;
-
-            if (in != null) {
-                inputPump = createInputPump(in, out, true);
-            }
-            else {
-                try {
-                    out.close();
-                } catch (IOException e) { }
-            }
-        }
-
-        /**
-         * Attach to a child streams from the given process.
-         *
-         * @param p     The process to attach to.
-         */
-        public void attach(final Process p) {
-            assert p != null;
-
-            setChildInputStream(p.getOutputStream());
-            setChildOutputStream(p.getInputStream());
-            setChildErrorStream(p.getErrorStream());
-        }
-        /**
-         * Start pumping the streams.
-         */
-        public void start() {
-            if (outputThread != null) {
-                outputThread.start();
-            }
-
-            if (errorThread != null) {
-                errorThread.start();
-            }
-
-            if (inputPump != null) {
-                Thread inputThread = new Thread(inputPump);
-                inputThread.setDaemon(true);
-                inputThread.start();
-            }
-        }
-
-        /**
-         * Stop pumping the streams.
-         */
-        public void stop() {
-            if (outputThread != null) {
-                try {
-                    outputThread.join();
-                }
-                catch (InterruptedException e) {
-                    // ignore
-                }
-            }
-
-            if (errorThread != null) {
-                try {
-                    errorThread.join();
-                }
-                catch (InterruptedException e) {
-                    // ignore
-                }
-            }
-
-            if (inputPump != null) {
-                inputPump.stop();
-            }
-
-            try {
-                err.flush();
-            } catch (IOException e) { }
-            try {
-                out.flush();
-            } catch (IOException e) { }
-        }
-
-        /**
-         * Create the pump to handle child output.
-         */
-        protected void createChildOutputPump(final InputStream in, final 
OutputStream out) {
-            assert in != null;
-            assert out != null;
-
-            outputThread = createPump(in, out);
-        }
-
-        /**
-         * Create the pump to handle error output.
-         */
-        protected void createChildErrorPump(final InputStream in, final 
OutputStream out) {
-            assert in != null;
-            assert out != null;
-
-            errorThread = createPump(in, out);
-        }
-
-        /**
-         * Creates a stream pumper to copy the given input stream to the given 
output stream.
-         */
-        protected Thread createPump(final InputStream in, final OutputStream 
out) {
-            assert in != null;
-            assert out != null;
-
-            return createPump(in, out, false);
-        }
-
-        /**
-         * Creates a stream pumper to copy the given input stream to the
-         * given output stream.
-         *
-         * @param in                    The input stream to copy from.
-         * @param out                   The output stream to copy to.
-         * @param closeWhenExhausted    If true close the inputstream.
-         * @return                      A thread object that does the pumping.
-         */
-        protected Thread createPump(final InputStream in, final OutputStream 
out, final boolean closeWhenExhausted) {
-            assert in != null;
-            assert out != null;
-
-            final Thread result = new Thread(new StreamPumper(in, out, 
closeWhenExhausted));
-            result.setDaemon(true);
-            return result;
-        }
-
-        /**
-         * Creates a stream pumper to copy the given input stream to the
-         * given output stream. Used for standard input.
-         */
-        protected StreamPumper createInputPump(final InputStream in, final 
OutputStream out, final boolean closeWhenExhausted) {
-            assert in != null;
-            assert out != null;
-
-            StreamPumper pumper = new StreamPumper(in, out, 
closeWhenExhausted);
-            pumper.setAutoflush(true);
-            return pumper;
-        }
-    }
 }
\ No newline at end of file

Modified: karaf/trunk/shell/commands/pom.xml
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/commands/pom.xml?rev=1040053&r1=1040052&r2=1040053&view=diff
==============================================================================
--- karaf/trunk/shell/commands/pom.xml (original)
+++ karaf/trunk/shell/commands/pom.xml Mon Nov 29 10:07:27 2010
@@ -49,6 +49,10 @@
             <artifactId>org.apache.felix.gogo.runtime</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.karaf</groupId>
+            <artifactId>org.apache.karaf.util</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.compendium</artifactId>
             <scope>provided</scope>
@@ -89,6 +93,9 @@
                             org.apache.karaf.shell.console,
                             *
                         </Import-Package>
+                        <Private-Package>
+                            org.apache.karaf.util.process
+                        </Private-Package>
                         <_versionpolicy>${bnd.version.policy}</_versionpolicy>
                     </instructions>
                 </configuration>

Modified: 
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/ExecuteAction.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/ExecuteAction.java?rev=1040053&r1=1040052&r2=1040053&view=diff
==============================================================================
--- 
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/ExecuteAction.java
 (original)
+++ 
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/ExecuteAction.java
 Mon Nov 29 10:07:27 2010
@@ -20,8 +20,8 @@ import java.util.List;
 
 import org.apache.felix.gogo.commands.Argument;
 import org.apache.felix.gogo.commands.Command;
-import org.apache.karaf.shell.commands.utils.PumpStreamHandler;
 import org.apache.karaf.shell.console.AbstractAction;
+import org.apache.karaf.util.process.PumpStreamHandler;
 
 /**
  * Execute system processes.
@@ -37,7 +37,7 @@ public class ExecuteAction extends Abstr
     protected Object doExecute() throws Exception {
         ProcessBuilder builder = new ProcessBuilder(args);
 
-        PumpStreamHandler handler = new PumpStreamHandler(System.in, 
System.out, System.err);
+        PumpStreamHandler handler = new PumpStreamHandler(System.in, 
System.out, System.err, "Command" + args.toString());
 
         log.info("Executing: {}", builder.command());
         Process p = builder.start();

Modified: karaf/trunk/shell/wrapper/pom.xml
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/wrapper/pom.xml?rev=1040053&r1=1040052&r2=1040053&view=diff
==============================================================================
--- karaf/trunk/shell/wrapper/pom.xml (original)
+++ karaf/trunk/shell/wrapper/pom.xml Mon Nov 29 10:07:27 2010
@@ -49,6 +49,10 @@
             <artifactId>org.apache.karaf.main</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.karaf</groupId>
+            <artifactId>org.apache.karaf.util</artifactId>
+        </dependency>
+        <dependency>
             <groupId>tanukisoft</groupId>
             <artifactId>wrapper</artifactId>
         </dependency>
@@ -99,7 +103,9 @@
                             org.apache.karaf.shell.console,
                             *
                         </Import-Package>
-                        <Private-Package>!*</Private-Package>
+                        <Private-Package>
+                            org.apache.karaf.util.process
+                        </Private-Package>
                         <_versionpolicy>${bnd.version.policy}</_versionpolicy>
                     </instructions>
                 </configuration>

Modified: 
karaf/trunk/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/PumpStreamHandler.java
URL: 
http://svn.apache.org/viewvc/karaf/trunk/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/PumpStreamHandler.java?rev=1040053&r1=1040052&r2=1040053&view=diff
==============================================================================
--- 
karaf/trunk/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/PumpStreamHandler.java
 (original)
+++ 
karaf/trunk/shell/wrapper/src/main/java/org/apache/karaf/shell/wrapper/PumpStreamHandler.java
 Mon Nov 29 10:07:27 2010
@@ -34,15 +34,17 @@ import java.io.IOException;
  */
 public class PumpStreamHandler
 {
-    private InputStream in;
+    private final InputStream in;
 
-    private OutputStream out;
+    private final OutputStream out;
 
-    private OutputStream err;
+    private final OutputStream err;
 
-    private Thread outputThread;
+    private final String name;
 
-    private Thread errorThread;
+    private StreamPumper outputPump;
+
+    private StreamPumper errorPump;
 
     private StreamPumper inputPump;
 
@@ -50,14 +52,20 @@ public class PumpStreamHandler
     // NOTE: May want to use a ThreadPool here, 3 threads per/pair seems kinda 
expensive :-(
     //
 
-    public PumpStreamHandler(final InputStream in, final OutputStream out, 
final OutputStream err) {
+    public PumpStreamHandler(final InputStream in, final OutputStream out, 
final OutputStream err, String name) {
         assert in != null;
         assert out != null;
         assert err != null;
+        assert name != null;
 
         this.in = in;
         this.out = out;
         this.err = err;
+        this.name = name;
+    }
+
+    public PumpStreamHandler(final InputStream in, final OutputStream out, 
final OutputStream err) {
+        this(in, out, err, "<unknown>");
     }
 
     public PumpStreamHandler(final OutputStream out, final OutputStream err) {
@@ -120,18 +128,25 @@ public class PumpStreamHandler
      * Start pumping the streams.
      */
     public void start() {
-        if (outputThread != null) {
-            outputThread.start();
+        if (outputPump != null) {
+            Thread thread = new Thread(outputPump);
+            thread.setDaemon(true);
+            thread.setName("Output pump for " + this.name);
+            thread.start();
         }
 
-        if (errorThread != null) {
-            errorThread.start();
+        if (errorPump != null) {
+            Thread thread = new Thread(errorPump);
+            thread.setDaemon(true);
+            thread.setName("Error pump for " + this.name);
+            thread.start();
         }
 
         if (inputPump != null) {
-            Thread inputThread = new Thread(inputPump);
-            inputThread.setDaemon(true);
-            inputThread.start();
+            Thread thread = new Thread(inputPump);
+            thread.setDaemon(true);
+            thread.setName("Input pump for " + this.name);
+            thread.start();
         }
     }
 
@@ -139,18 +154,20 @@ public class PumpStreamHandler
      * Stop pumping the streams.
      */
     public void stop() {
-        if (outputThread != null) {
+        if (outputPump != null) {
             try {
-                outputThread.join();
+                outputPump.stop();
+                outputPump.waitFor();
             }
             catch (InterruptedException e) {
                 // ignore
             }
         }
 
-        if (errorThread != null) {
+        if (errorPump != null) {
             try {
-                errorThread.join();
+                errorPump.stop();
+                errorPump.waitFor();
             }
             catch (InterruptedException e) {
                 // ignore
@@ -176,7 +193,7 @@ public class PumpStreamHandler
         assert in != null;
         assert out != null;
 
-        outputThread = createPump(in, out);
+        outputPump = createPump(in, out);
     }
 
     /**
@@ -186,13 +203,13 @@ public class PumpStreamHandler
         assert in != null;
         assert out != null;
 
-        errorThread = createPump(in, out);
+        errorPump = createPump(in, out);
     }
 
     /**
      * Creates a stream pumper to copy the given input stream to the given 
output stream.
      */
-    protected Thread createPump(final InputStream in, final OutputStream out) {
+    protected StreamPumper createPump(final InputStream in, final OutputStream 
out) {
         assert in != null;
         assert out != null;
 
@@ -208,13 +225,12 @@ public class PumpStreamHandler
      * @param closeWhenExhausted    If true close the inputstream.
      * @return                      A thread object that does the pumping.
      */
-    protected Thread createPump(final InputStream in, final OutputStream out, 
final boolean closeWhenExhausted) {
+    protected StreamPumper createPump(final InputStream in, final OutputStream 
out, final boolean closeWhenExhausted) {
         assert in != null;
         assert out != null;
 
-        final Thread result = new Thread(new StreamPumper(in, out, 
closeWhenExhausted));
-        result.setDaemon(true);
-        return result;
+        StreamPumper pumper = new StreamPumper(in, out, closeWhenExhausted);
+        return pumper;
     }
 
     /**

Copied: 
karaf/trunk/util/src/main/java/org/apache/karaf/util/process/PumpStreamHandler.java
 (from r1040052, 
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/PumpStreamHandler.java)
URL: 
http://svn.apache.org/viewvc/karaf/trunk/util/src/main/java/org/apache/karaf/util/process/PumpStreamHandler.java?p2=karaf/trunk/util/src/main/java/org/apache/karaf/util/process/PumpStreamHandler.java&p1=karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/PumpStreamHandler.java&r1=1040052&r2=1040053&rev=1040053&view=diff
==============================================================================
--- 
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/PumpStreamHandler.java
 (original)
+++ 
karaf/trunk/util/src/main/java/org/apache/karaf/util/process/PumpStreamHandler.java
 Mon Nov 29 10:07:27 2010
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.karaf.shell.commands.utils;
+package org.apache.karaf.util.process;
 
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -34,15 +34,17 @@ import java.io.IOException;
  */
 public class PumpStreamHandler
 {
-    private InputStream in;
+    private final InputStream in;
 
-    private OutputStream out;
+    private final OutputStream out;
 
-    private OutputStream err;
+    private final OutputStream err;
 
-    private Thread outputThread;
+    private final String name;
 
-    private Thread errorThread;
+    private StreamPumper outputPump;
+
+    private StreamPumper errorPump;
 
     private StreamPumper inputPump;
 
@@ -50,14 +52,20 @@ public class PumpStreamHandler
     // NOTE: May want to use a ThreadPool here, 3 threads per/pair seems kinda 
expensive :-(
     //
 
-    public PumpStreamHandler(final InputStream in, final OutputStream out, 
final OutputStream err) {
+    public PumpStreamHandler(final InputStream in, final OutputStream out, 
final OutputStream err, String name) {
         assert in != null;
         assert out != null;
         assert err != null;
+        assert name != null;
 
         this.in = in;
         this.out = out;
         this.err = err;
+        this.name = name;
+    }
+
+    public PumpStreamHandler(final InputStream in, final OutputStream out, 
final OutputStream err) {
+        this(in, out, err, "<unknown>");
     }
 
     public PumpStreamHandler(final OutputStream out, final OutputStream err) {
@@ -120,18 +128,25 @@ public class PumpStreamHandler
      * Start pumping the streams.
      */
     public void start() {
-        if (outputThread != null) {
-            outputThread.start();
+        if (outputPump != null) {
+            Thread thread = new Thread(outputPump);
+            thread.setDaemon(true);
+            thread.setName("Output pump for " + this.name);
+            thread.start();
         }
 
-        if (errorThread != null) {
-            errorThread.start();
+        if (errorPump != null) {
+            Thread thread = new Thread(errorPump);
+            thread.setDaemon(true);
+            thread.setName("Error pump for " + this.name);
+            thread.start();
         }
 
         if (inputPump != null) {
-            Thread inputThread = new Thread(inputPump);
-            inputThread.setDaemon(true);
-            inputThread.start();
+            Thread thread = new Thread(inputPump);
+            thread.setDaemon(true);
+            thread.setName("Input pump for " + this.name);
+            thread.start();
         }
     }
 
@@ -139,18 +154,20 @@ public class PumpStreamHandler
      * Stop pumping the streams.
      */
     public void stop() {
-        if (outputThread != null) {
+        if (outputPump != null) {
             try {
-                outputThread.join();
+                outputPump.stop();
+                outputPump.waitFor();
             }
             catch (InterruptedException e) {
                 // ignore
             }
         }
 
-        if (errorThread != null) {
+        if (errorPump != null) {
             try {
-                errorThread.join();
+                errorPump.stop();
+                errorPump.waitFor();
             }
             catch (InterruptedException e) {
                 // ignore
@@ -176,7 +193,7 @@ public class PumpStreamHandler
         assert in != null;
         assert out != null;
 
-        outputThread = createPump(in, out);
+        outputPump = createPump(in, out);
     }
 
     /**
@@ -186,13 +203,13 @@ public class PumpStreamHandler
         assert in != null;
         assert out != null;
 
-        errorThread = createPump(in, out);
+        errorPump = createPump(in, out);
     }
 
     /**
      * Creates a stream pumper to copy the given input stream to the given 
output stream.
      */
-    protected Thread createPump(final InputStream in, final OutputStream out) {
+    protected StreamPumper createPump(final InputStream in, final OutputStream 
out) {
         assert in != null;
         assert out != null;
 
@@ -208,13 +225,12 @@ public class PumpStreamHandler
      * @param closeWhenExhausted    If true close the inputstream.
      * @return                      A thread object that does the pumping.
      */
-    protected Thread createPump(final InputStream in, final OutputStream out, 
final boolean closeWhenExhausted) {
+    protected StreamPumper createPump(final InputStream in, final OutputStream 
out, final boolean closeWhenExhausted) {
         assert in != null;
         assert out != null;
 
-        final Thread result = new Thread(new StreamPumper(in, out, 
closeWhenExhausted));
-        result.setDaemon(true);
-        return result;
+        StreamPumper pumper = new StreamPumper(in, out, closeWhenExhausted);
+        return pumper;
     }
 
     /**

Copied: 
karaf/trunk/util/src/main/java/org/apache/karaf/util/process/StreamPumper.java 
(from r1040052, 
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/StreamPumper.java)
URL: 
http://svn.apache.org/viewvc/karaf/trunk/util/src/main/java/org/apache/karaf/util/process/StreamPumper.java?p2=karaf/trunk/util/src/main/java/org/apache/karaf/util/process/StreamPumper.java&p1=karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/StreamPumper.java&r1=1040052&r2=1040053&rev=1040053&view=diff
==============================================================================
--- 
karaf/trunk/shell/commands/src/main/java/org/apache/karaf/shell/commands/utils/StreamPumper.java
 (original)
+++ 
karaf/trunk/util/src/main/java/org/apache/karaf/util/process/StreamPumper.java 
Mon Nov 29 10:07:27 2010
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.karaf.shell.commands.utils;
+package org.apache.karaf.util.process;
 
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -47,7 +47,7 @@ public class StreamPumper
 
     private boolean autoflush;
 
-    private Exception exception;
+    private Throwable exception;
 
     private int bufferSize = 128;
 
@@ -106,7 +106,7 @@ public class StreamPumper
         int length;
         try {
             do {
-                while (in.available() > 0 && !finish) {
+                while (in.available() > 0) {
                     length = in.read(buf);
                     if (length < 1 ) {
                         break;
@@ -118,11 +118,11 @@ public class StreamPumper
                 }
                 out.flush();
                 Thread.sleep(200);  // Pause to avoid tight loop if external 
proc is slow
-            } while (!finish && closeWhenExhausted);
+            } while (!finish);
         }
-        catch (Exception e) {
+        catch (Throwable t) {
             synchronized (this) {
-                exception = e;
+                exception = t;
             }
         }
         finally {
@@ -187,7 +187,7 @@ public class StreamPumper
      *
      * @return The Exception encountered; or null if there was none.
      */
-    public synchronized Exception getException() {
+    public synchronized Throwable getException() {
         return exception;
     }
 


Reply via email to