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