PR: 24918 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277513 13f79535-47bb-0310-9956-ffa450edef68master
@@ -24,6 +24,10 @@ Changes that could break older environments: | |||||
Fixed bugs: | Fixed bugs: | ||||
----------- | ----------- | ||||
* Programs run with <java fork="true"> can now accept standard input | |||||
from the Ant console. (Programs run with <java fork="false"> could | |||||
already do so.) Bugzilla Report 24918. | |||||
* Translate task does not remove tokens when a key is not found. | * Translate task does not remove tokens when a key is not found. | ||||
It logs a verbose message. Bugzilla Report 13936. | It logs a verbose message. Bugzilla Report 13936. | ||||
@@ -15,10 +15,9 @@ specified.</p> | |||||
If odd things go wrong when you run this task, set fork="true" to use a new | If odd things go wrong when you run this task, set fork="true" to use a new | ||||
JVM. | JVM. | ||||
<p>Note that you cannot interact with a forked VM, the only way to | |||||
send input to it is via the input and inputstring attributes. Also note that | |||||
in Ant 1.6, any attempt to read input in the forked VM will receive an | |||||
EOF (-1). This is a change from Ant 1.5, where such an attempt would block.</p> | |||||
<p>As of Ant 1.7, you can interact with a forked VM, as well as | |||||
sending input to it via the <code>input</code> and <code>inputstring</code> | |||||
attributes.</p> | |||||
<h3>Parameters</h3> | <h3>Parameters</h3> | ||||
<table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
@@ -157,14 +156,16 @@ EOF (-1). This is a change from Ant 1.5, where such an attempt would block.</p> | |||||
<td valign="top">A file from which the executed command's standard input | <td valign="top">A file from which the executed command's standard input | ||||
is taken. This attribute is mutually exclusive with the | is taken. This attribute is mutually exclusive with the | ||||
inputstring attribute</td> | inputstring attribute</td> | ||||
<td align="center" valign="top">No</td> | |||||
<td align="center" valign="top">No; default is to take standard input from console | |||||
(unless <code>spawn="true"</code>)</td> | |||||
</tr> | </tr> | ||||
<tr> | <tr> | ||||
<td valign="top">inputstring</td> | <td valign="top">inputstring</td> | ||||
<td valign="top">A string which serves as the input stream for the | <td valign="top">A string which serves as the input stream for the | ||||
executed command. This attribute is mutually exclusive with the | executed command. This attribute is mutually exclusive with the | ||||
input attribute.</td> | input attribute.</td> | ||||
<td align="center" valign="top">No</td> | |||||
<td align="center" valign="top">No; default is to take standard input from console | |||||
(unless <code>spawn="true"</code>)</td> | |||||
</tr> | </tr> | ||||
<tr> | <tr> | ||||
<td valign="top">newenvironment</td> | <td valign="top">newenvironment</td> | ||||
@@ -353,4 +354,3 @@ Reserved.</p> | |||||
</body> | </body> | ||||
</html> | </html> | ||||
@@ -1,5 +1,5 @@ | |||||
/* | /* | ||||
* Copyright 2000-2004 The Apache Software Foundation | |||||
* Copyright 2000-2005 The Apache Software Foundation | |||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
* you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||||
@@ -37,6 +37,7 @@ import org.apache.tools.ant.types.Permissions; | |||||
import org.apache.tools.ant.types.RedirectorElement; | import org.apache.tools.ant.types.RedirectorElement; | ||||
import org.apache.tools.ant.taskdefs.condition.Os; | import org.apache.tools.ant.taskdefs.condition.Os; | ||||
import org.apache.tools.ant.util.JavaEnvUtils; | import org.apache.tools.ant.util.JavaEnvUtils; | ||||
import org.apache.tools.ant.util.KeepAliveInputStream; | |||||
/** | /** | ||||
* Launcher for Java applications. Allows use of | * Launcher for Java applications. Allows use of | ||||
@@ -639,11 +640,8 @@ public class Java extends Task { | |||||
*/ | */ | ||||
public int handleInput(byte[] buffer, int offset, int length) | public int handleInput(byte[] buffer, int offset, int length) | ||||
throws IOException { | throws IOException { | ||||
if (redirector.getInputStream() != null) { | |||||
return redirector.handleInput(buffer, offset, length); | |||||
} else { | |||||
return super.handleInput(buffer, offset, length); | |||||
} | |||||
// Should work whether or not redirector.inputStream == null: | |||||
return redirector.handleInput(buffer, offset, length); | |||||
} | } | ||||
/** | /** | ||||
@@ -702,6 +700,10 @@ public class Java extends Task { | |||||
if (redirectorElement != null) { | if (redirectorElement != null) { | ||||
redirectorElement.configure(redirector); | redirectorElement.configure(redirector); | ||||
} | } | ||||
if (!spawn && input == null && inputString == null) { | |||||
// #24918: send standard input to the process by default. | |||||
redirector.setInputStream(new KeepAliveInputStream(getProject().getDefaultInputStream())); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -1,5 +1,5 @@ | |||||
/* | /* | ||||
* Copyright 2000-2004 The Apache Software Foundation | |||||
* Copyright 2000-2005 The Apache Software Foundation | |||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
* you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||||
@@ -31,7 +31,7 @@ public class PumpStreamHandler implements ExecuteStreamHandler { | |||||
private Thread outputThread; | private Thread outputThread; | ||||
private Thread errorThread; | private Thread errorThread; | ||||
private Thread inputThread; | |||||
private StreamPumper inputPump; | |||||
private OutputStream out; | private OutputStream out; | ||||
private OutputStream err; | private OutputStream err; | ||||
@@ -101,7 +101,7 @@ public class PumpStreamHandler implements ExecuteStreamHandler { | |||||
*/ | */ | ||||
public void setProcessInputStream(OutputStream os) { | public void setProcessInputStream(OutputStream os) { | ||||
if (input != null) { | if (input != null) { | ||||
inputThread = createPump(input, os, true); | |||||
inputPump = createInputPump(input, os, true); | |||||
} else { | } else { | ||||
try { | try { | ||||
os.close(); | os.close(); | ||||
@@ -117,7 +117,9 @@ public class PumpStreamHandler implements ExecuteStreamHandler { | |||||
public void start() { | public void start() { | ||||
outputThread.start(); | outputThread.start(); | ||||
errorThread.start(); | errorThread.start(); | ||||
if (inputThread != null) { | |||||
if (inputPump != null) { | |||||
Thread inputThread = new Thread(inputPump); | |||||
inputThread.setDaemon(true); | |||||
inputThread.start(); | inputThread.start(); | ||||
} | } | ||||
} | } | ||||
@@ -137,12 +139,8 @@ public class PumpStreamHandler implements ExecuteStreamHandler { | |||||
// ignore | // ignore | ||||
} | } | ||||
if (inputThread != null) { | |||||
try { | |||||
inputThread.join(); | |||||
} catch (InterruptedException e) { | |||||
// ignore | |||||
} | |||||
if (inputPump != null) { | |||||
inputPump.stop(); | |||||
} | } | ||||
try { | try { | ||||
@@ -210,5 +208,17 @@ public class PumpStreamHandler implements ExecuteStreamHandler { | |||||
result.setDaemon(true); | result.setDaemon(true); | ||||
return result; | return result; | ||||
} | } | ||||
/** | |||||
* Creates a stream pumper to copy the given input stream to the | |||||
* given output stream. Used for standard input. | |||||
* @since Ant 1.7 | |||||
*/ | |||||
/*protected*/ StreamPumper createInputPump(InputStream is, OutputStream os, | |||||
boolean closeWhenExhausted) { | |||||
StreamPumper pumper = new StreamPumper(is, os, closeWhenExhausted); | |||||
pumper.setAutoflush(true); | |||||
return pumper; | |||||
} | |||||
} | } |
@@ -202,6 +202,15 @@ public class Redirector { | |||||
this.inputString = inputString; | this.inputString = inputString; | ||||
} | } | ||||
/** | |||||
* Set a stream to use as input. | |||||
* | |||||
* @param inputStream the stream from which input will be read | |||||
* @since Ant 1.7 | |||||
*/ | |||||
/*public*/ void setInputStream(InputStream inputStream) { | |||||
this.inputStream = inputStream; | |||||
} | |||||
/** | /** | ||||
* File the output of the process is redirected to. If error is not | * File the output of the process is redirected to. If error is not | ||||
@@ -543,7 +552,7 @@ public class Redirector { | |||||
} | } | ||||
} | } | ||||
// if input files are specified, inputString is ignored; | |||||
// if input files are specified, inputString and inputStream are ignored; | |||||
// classes that work with redirector attributes can enforce | // classes that work with redirector attributes can enforce | ||||
// whatever warnings are needed | // whatever warnings are needed | ||||
if (input != null && input.length > 0) { | if (input != null && input.length > 0) { | ||||
@@ -1,5 +1,5 @@ | |||||
/* | /* | ||||
* Copyright 2000,2002-2004 The Apache Software Foundation | |||||
* Copyright 2000,2002-2005 The Apache Software Foundation | |||||
* | * | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
* you may not use this file except in compliance with the License. | * you may not use this file except in compliance with the License. | ||||
@@ -36,6 +36,7 @@ public class StreamPumper implements Runnable { | |||||
private OutputStream os; | private OutputStream os; | ||||
private boolean finished; | private boolean finished; | ||||
private boolean closeWhenExhausted; | private boolean closeWhenExhausted; | ||||
private boolean autoflush = false; | |||||
/** | /** | ||||
* Create a new stream pumper. | * Create a new stream pumper. | ||||
@@ -62,6 +63,14 @@ public class StreamPumper implements Runnable { | |||||
this(is, os, false); | this(is, os, false); | ||||
} | } | ||||
/** | |||||
* Set whether data should be flushed through to the output stream. | |||||
* @param autoflush if true, push through data; if false, let it be buffered | |||||
* @since Ant 1.7 | |||||
*/ | |||||
/*public*/ void setAutoflush(boolean autoflush) { | |||||
this.autoflush = autoflush; | |||||
} | |||||
/** | /** | ||||
* Copies data from the input stream to the output stream. | * Copies data from the input stream to the output stream. | ||||
@@ -78,8 +87,11 @@ public class StreamPumper implements Runnable { | |||||
int length; | int length; | ||||
try { | try { | ||||
while ((length = is.read(buf)) > 0) { | |||||
while ((length = is.read(buf)) > 0 && !finished) { | |||||
os.write(buf, 0, length); | os.write(buf, 0, length); | ||||
if (autoflush) { | |||||
os.flush(); | |||||
} | |||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
// ignore errors | // ignore errors | ||||
@@ -116,4 +128,17 @@ public class StreamPumper implements Runnable { | |||||
wait(); | wait(); | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Stop the pumper as soon as possible. | |||||
* Note that it may continue to block on the input stream | |||||
* but it will really stop the thread as soon as it gets EOF | |||||
* or any byte, and it will be marked as finished. | |||||
* @since Ant 1.7 | |||||
*/ | |||||
/*public*/ synchronized void stop() { | |||||
finished = true; | |||||
notifyAll(); | |||||
} | |||||
} | } |