Browse Source

bug #49119:

- put the fix back again but only for input which is not a string or a file
 - and a unit test


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@986668 13f79535-47bb-0310-9956-ffa450edef68
master
Nicolas Lalevee 15 years ago
parent
commit
1b30eea462
4 changed files with 96 additions and 26 deletions
  1. +4
    -0
      WHATSNEW
  2. +43
    -24
      src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
  3. +2
    -2
      src/main/org/apache/tools/ant/taskdefs/Redirector.java
  4. +47
    -0
      src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java

+ 4
- 0
WHATSNEW View File

@@ -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:
--------------



+ 43
- 24
src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java View File

@@ -32,23 +32,38 @@ public class PumpStreamHandler implements ExecuteStreamHandler {

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 implements ExecuteStreamHandler {
*/
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 implements ExecuteStreamHandler {
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 implements ExecuteStreamHandler {
* Stop pumping the streams.
*/
public void stop() {

if (inputPump != null) {
inputPump.stop();
}
finish(inputThread);

try {
err.flush();
@@ -159,6 +169,10 @@ public class PumpStreamHandler implements ExecuteStreamHandler {
* @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 implements ExecuteStreamHandler {
*/
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;
}

/**


+ 2
- 2
src/main/org/apache/tools/ant/taskdefs/Redirector.java View File

@@ -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);
}

/**


+ 47
- 0
src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java View File

@@ -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 BuildFileTest {
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


Loading…
Cancel
Save