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: | |||
----------- | |||
* 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. | |||
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 | |||
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> | |||
<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 | |||
is taken. This attribute is mutually exclusive with the | |||
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> | |||
<td valign="top">inputstring</td> | |||
<td valign="top">A string which serves as the input stream for the | |||
executed command. This attribute is mutually exclusive with the | |||
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> | |||
<td valign="top">newenvironment</td> | |||
@@ -353,4 +354,3 @@ Reserved.</p> | |||
</body> | |||
</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"); | |||
* 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.taskdefs.condition.Os; | |||
import org.apache.tools.ant.util.JavaEnvUtils; | |||
import org.apache.tools.ant.util.KeepAliveInputStream; | |||
/** | |||
* 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) | |||
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) { | |||
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"); | |||
* 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 errorThread; | |||
private Thread inputThread; | |||
private StreamPumper inputPump; | |||
private OutputStream out; | |||
private OutputStream err; | |||
@@ -101,7 +101,7 @@ public class PumpStreamHandler implements ExecuteStreamHandler { | |||
*/ | |||
public void setProcessInputStream(OutputStream os) { | |||
if (input != null) { | |||
inputThread = createPump(input, os, true); | |||
inputPump = createInputPump(input, os, true); | |||
} else { | |||
try { | |||
os.close(); | |||
@@ -117,7 +117,9 @@ public class PumpStreamHandler implements ExecuteStreamHandler { | |||
public void start() { | |||
outputThread.start(); | |||
errorThread.start(); | |||
if (inputThread != null) { | |||
if (inputPump != null) { | |||
Thread inputThread = new Thread(inputPump); | |||
inputThread.setDaemon(true); | |||
inputThread.start(); | |||
} | |||
} | |||
@@ -137,12 +139,8 @@ public class PumpStreamHandler implements ExecuteStreamHandler { | |||
// ignore | |||
} | |||
if (inputThread != null) { | |||
try { | |||
inputThread.join(); | |||
} catch (InterruptedException e) { | |||
// ignore | |||
} | |||
if (inputPump != null) { | |||
inputPump.stop(); | |||
} | |||
try { | |||
@@ -210,5 +208,17 @@ public class PumpStreamHandler implements ExecuteStreamHandler { | |||
result.setDaemon(true); | |||
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; | |||
} | |||
/** | |||
* 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 | |||
@@ -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 | |||
// whatever warnings are needed | |||
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"); | |||
* 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 boolean finished; | |||
private boolean closeWhenExhausted; | |||
private boolean autoflush = false; | |||
/** | |||
* Create a new stream pumper. | |||
@@ -62,6 +63,14 @@ public class StreamPumper implements Runnable { | |||
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. | |||
@@ -78,8 +87,11 @@ public class StreamPumper implements Runnable { | |||
int length; | |||
try { | |||
while ((length = is.read(buf)) > 0) { | |||
while ((length = is.read(buf)) > 0 && !finished) { | |||
os.write(buf, 0, length); | |||
if (autoflush) { | |||
os.flush(); | |||
} | |||
} | |||
} catch (Exception e) { | |||
// ignore errors | |||
@@ -116,4 +128,17 @@ public class StreamPumper implements Runnable { | |||
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(); | |||
} | |||
} |