You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by hi...@apache.org on 2010/08/18 15:38:16 UTC

svn commit: r986668 - in /ant/core/trunk: WHATSNEW src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java src/main/org/apache/tools/ant/taskdefs/Redirector.java src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java

Author: hibou
Date: Wed Aug 18 13:38:15 2010
New Revision: 986668

URL: http://svn.apache.org/viewvc?rev=986668&view=rev
Log:
bug #49119:
 - put the fix back again but only for input which is not a string or a file
 - and a unit test

Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Redirector.java
    ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java

Modified: ant/core/trunk/WHATSNEW
URL: http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=986668&r1=986667&r2=986668&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Wed Aug 18 13:38:15 2010
@@ -123,6 +123,10 @@ Fixed bugs:
    attribute has been specified.
    Bugzilla Report 49755.
 
+ * If forked, after finished <java> was still reading the input stream
+   for a bunch of characters, then stealing them from a following <input>.
+   Bugzilla Report 49119.
+
 Other changes:
 --------------
 

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java?rev=986668&r1=986667&r2=986668&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java Wed Aug 18 13:38:15 2010
@@ -32,23 +32,38 @@ public class PumpStreamHandler implement
 
     private Thread outputThread;
     private Thread errorThread;
-    private StreamPumper inputPump;
+    private Thread inputThread;
 
     private OutputStream out;
     private OutputStream err;
     private InputStream input;
+    private final boolean nonBlockingRead;
 
     /**
      * Construct a new <code>PumpStreamHandler</code>.
      * @param out the output <code>OutputStream</code>.
      * @param err the error <code>OutputStream</code>.
      * @param input the input <code>InputStream</code>.
+     * @param nonBlockingRead set it to <code>true</code> if the input should be
+     *                      read with simulated non blocking IO.
      */
     public PumpStreamHandler(OutputStream out, OutputStream err,
-                             InputStream input) {
+                             InputStream input, boolean nonBlockingRead) {
         this.out = out;
         this.err = err;
         this.input = input;
+        this.nonBlockingRead = nonBlockingRead;
+    }
+
+    /**
+     * Construct a new <code>PumpStreamHandler</code>.
+     * @param out the output <code>OutputStream</code>.
+     * @param err the error <code>OutputStream</code>.
+     * @param input the input <code>InputStream</code>.
+     */
+    public PumpStreamHandler(OutputStream out, OutputStream err,
+                             InputStream input) {
+        this(out, err, input, false);
     }
 
     /**
@@ -102,7 +117,7 @@ public class PumpStreamHandler implement
      */
     public void setProcessInputStream(OutputStream os) {
         if (input != null) {
-            inputPump = createInputPump(input, os, true);
+            inputThread = createPump(input, os, true, nonBlockingRead);
         } else {
             try {
                 os.close();
@@ -118,9 +133,7 @@ public class PumpStreamHandler implement
     public void start() {
         outputThread.start();
         errorThread.start();
-        if (inputPump != null) {
-            Thread inputThread = new Thread(inputPump);
-            inputThread.setDaemon(true);
+        if (inputThread != null) {
             inputThread.start();
         }
     }
@@ -129,10 +142,7 @@ public class PumpStreamHandler implement
      * Stop pumping the streams.
      */
     public void stop() {
-
-        if (inputPump != null) {
-            inputPump.stop();
-        }
+        finish(inputThread);
 
         try {
             err.flush();
@@ -159,6 +169,10 @@ public class PumpStreamHandler implement
      * @since Ant 1.8.0
      */
     protected final void finish(Thread t) {
+        if (t == null) {
+            // nothing to terminate
+            return;
+        }
         try {
             StreamPumper s = null;
             if (t instanceof ThreadWithPumper) {
@@ -241,25 +255,30 @@ public class PumpStreamHandler implement
      */
     protected Thread createPump(InputStream is, OutputStream os,
                                 boolean closeWhenExhausted) {
-        final Thread result
-            = new ThreadWithPumper(new StreamPumper(is, os,
-                                                    closeWhenExhausted,
-                                                    true));
-        result.setDaemon(true);
-        return result;
+        return createPump(is, os, closeWhenExhausted, true);
     }
 
     /**
      * Creates a stream pumper to copy the given input stream to the
-     * given output stream. Used for standard input.
-     * @since Ant 1.6.3
+     * given output stream.
+     * @param is the input stream to copy from.
+     * @param os the output stream to copy to.
+     * @param closeWhenExhausted if true close the inputstream.
+     * @param useAvailable set it to <code>true</code> to use simulated non
+     *                     blocking IO.
+     * @return a thread object that does the pumping, subclasses
+     * should return an instance of {@link ThreadWithPumper
+     * ThreadWithPumper}.
+     * @since Ant 1.8.2
      */
-    /*protected*/ StreamPumper createInputPump(InputStream is, OutputStream os,
-                                boolean closeWhenExhausted) {
-        StreamPumper pumper = new StreamPumper(is, os, closeWhenExhausted,
-                                               false);
-        pumper.setAutoflush(true);
-        return pumper;
+    protected Thread createPump(InputStream is, OutputStream os,
+                                boolean closeWhenExhausted, boolean nonBlockingIO) {
+        final Thread result
+            = new ThreadWithPumper(new StreamPumper(is, os,
+                                                    closeWhenExhausted,
+                                                    nonBlockingIO));
+        result.setDaemon(true);
+        return result;
     }
 
     /**

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Redirector.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Redirector.java?rev=986668&r1=986667&r2=986668&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Redirector.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Redirector.java Wed Aug 18 13:38:15 2010
@@ -753,9 +753,9 @@ public class Redirector {
      */
     public ExecuteStreamHandler createHandler() throws BuildException {
         createStreams();
+        boolean nonBlockingRead = input == null && inputString == null;
         return new PumpStreamHandler(getOutputStream(), getErrorStream(),
-                getInputStream());
-
+                getInputStream(), nonBlockingRead);
     }
 
     /**

Modified: ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java
URL: http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java?rev=986668&r1=986667&r2=986668&view=diff
==============================================================================
--- ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java (original)
+++ ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java Wed Aug 18 13:38:15 2010
@@ -21,10 +21,14 @@ package org.apache.tools.ant.taskdefs;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
 
 import org.apache.tools.ant.BuildFileTest;
+import org.apache.tools.ant.input.DefaultInputHandler;
 import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.TeeOutputStream;
 
@@ -214,6 +218,49 @@ public class JavaTest extends BuildFileT
         executeTarget("redirector2");
     }
 
+    public void testReleasedInput() throws Exception {
+        PipedOutputStream out = new PipedOutputStream();
+        final PipedInputStream in = new PipedInputStream(out);
+        project.setInputHandler(new DefaultInputHandler() {
+            protected InputStream getInputStream() {
+                return in;
+            }
+        });
+        project.setDefaultInputStream(in);
+
+        Java java = new Java();
+        java.setProject(project);
+        java.setClassname("org.apache.tools.ant.Main");
+        java.setArgs("-version");
+        java.setFork(true);
+        // note: due to the missing classpath it will fail, but the input stream
+        // reader will be read
+        java.execute();
+
+        Thread inputThread = new Thread(new Runnable() {
+            public void run() {
+                Input input = new Input();
+                input.setProject(project);
+                input.setAddproperty("input.value");
+                input.execute();
+            }
+        });
+        inputThread.start();
+
+        // wait a little bit for the task to wait for input
+        Thread.sleep(100);
+
+        // write some stuff in the input stream to be catched by the input task
+        out.write("foo\n".getBytes());
+        out.flush();
+        out.write("bar\n".getBytes());
+        out.flush();
+
+        inputThread.join(2000);
+
+        assertEquals("foo", project.getProperty("input.value"));
+    }
+
     /**
      * entry point class with no dependencies other
      * than normal JRE runtime