Not sure if this has already been discussed and rejected, but anyway here is an attempt at a patch to let you send console input to <java> - mainly so that you can use an Ant script to build and then interactively test a console-based Java app. The patch adds an attribute 'standardinput' to <java>. If true, Ant's stdin will be passed to the subprocess. It seems that this *already* happens when fork="false" - not sure if that is intentional, or if it should be explicitly disabled. Anyway, at least for fork="true" this patch appears to be necessary to let the subprocess read from stdin. Otherwise it gets an immediate EOF. Also adding a few more options to various classes to permit stdin to be read, and to make the stream pumper autoflush input - if you don't do that, then in forked mode the data will just build up somewhere and not get sent to the subprocess. Tested only on Linux, YMMV on other platforms. Not sure how to go about creating a unit test for something so inherently platform-specific and difficult to script (without using Expect or pty's!), but attaching a build file you can test with manually. Try to run each of the targets individually, and also try running two or more in sequence to verify that you can Ctrl-D (Unix) to end input to one task and still go and send some input to the next one. This patch does not attempt to add the same feature for general <exec>; I am not sure if it would even be useful to anyone. Related bug reports I can see: bug #2738 - Passing of Streams... bug #3452 - ... add "input" attribute for task "exec"... bug #24592 - support @input for the exec task
Created attachment 9240 [details] Possible patch to add <java standardinput="true">
Created attachment 9241 [details] Ant script to help manually test patch functionality
I have a quick question since I have not tried the code - won't putting a pump on standard input potentially pump more input into the task than it takes. A second task taking input might not get it. This might only be an issue when redirecting input to Ant itself - not sure. Also, I wonder if there is a potential for deadlock if the read is blocked. If this does work, it would be useful for exec and sicne it uses the same mechanism, it should be easy. BTW, working in non-forked mode is intentional and should be controllable by the -noinput flag if you don't want interactivity.
Re. pumping more input into the task than it takes - not sure, but it worked for me at least on Linux to run the process twice from the same Ant target. Feed the first process some input, it echoes it as it goes, press Ctrl-D, the first process ends and the second process begins, feed it some input, it gets echoed, press Ctrl-D, the second process ends and the build completes. However this test program was designed to accept stdin until it gets EOF, and react quickly to input relative to interactive typing speed. If there is a process which takes stdin for a while and then stops (e.g. upon receiving a line like "exit") and closed stdin and then does some lengthy calculation while you continue typing, then I suppose some of the input could be sent to the process where it will not be accepted, which would throw an IOException in StreamPumper. Not sure how to fix that except by checking the process after every byte is written to see if the OutputStream is closed. Anyway if the process does not close stdin but simply stops checking it then there is no way for the StreamPumper to know whether it is going to want more input or not, so it must assume that it will and send it. Realistically, I can't imagine many use cases for interactive process input that would involve more than one process per Ant run, or non-stdin-driven programs, so I imagine this is a corner case. Re. potential for deadlock while read is blocked - not sure what you mean. Re. <java fork="false"> accepting input (unless -noinput is given) while <java fork="true"> does not and this being intentional - OK I suppose, though this still sounds weird. Why (from a user perspective) should forking or not forking affect whether the <java> task accepts input? ---- Now for the experiment: change the Java code in the test build script to read: ... public static void main(String[] x) throws Exception { ... System.err.println("got: " + line); Thread.sleep(3000); ... so that the process waits to get further input. Then run ant -f /tmp/foo.xml nofork-nostdin nofork-nostdin (using an unpatched Ant here) and when the 1st process is ready, enter "a" RET, "b" RET, "c" RET, Ctrl-D, "1" RET, "2" RET, "3" RET, Ctrl-D in quick sequence. I get nofork-nostdin: [echo] nofork=true stdin=false a [java] got: a b c 1 2 3 [java] got: b [java] got: c [java] got: 1 [java] got: 2 [java] got: 3 compile: [echo] Ant: Apache Ant version 1.7alpha compiled on November 22 2003 [javac] Compiling 1 source file to /tmp nofork-nostdin: [echo] nofork=true stdin=false i.e. all the input was sent to the first process. Then it is waiting again for the second, which you can still use and finish normally. So basically if you type ahead, it will go to the process current running, even if you put in a Ctrl-D. By comparison, using bash if you run $ echo Running 1; java -cp /tmp TestIn; echo Running 2; java -cp /tmp TestIn and type the same things, it works almost exactly the same: Running 1 a got: a b c 1 2 3 got: b got: c got: got: 1 got: 2 got: 3 Running 2 So if this is a bug, it is a bug which is shared even by the Unix shell - probably not something to worry about.
Anyone looking at this? If there are specific objections, I can try to address them. Potentially important for NetBeans 4.0 (assuming that bundles Ant 1.6.2) as without some fix you would not be able to use the IDE to try programs which take console input. (Unless you run unforked, but this is dangerous in general.)
Are committers interested in this patch? If so I am quite willing to redo it to apply against the current trunk (does not merge cleanly any more, I think). Not sure if it would be accepted for 1.6.3 (not a bug fix) or only for 1.7.
A solution to this needs to be integrated as soon as possible. This issue is blocking progress in value-added products for the support of console apps and GUI apps that use an optional debug, monitor, or recovery console. In some environments, GUI independent consoles are considered a mandatory component of product monitoring and reliability.
Please note that this issue was identified as serious defect in functionality of upcoming NetBeans 4.0. For more information, take a look here: http://qa.netbeans.org/issues/show_bug.cgi?id=47708 This issue has already got 12 votes. How much is necessary to convince you to integrate Jesse's patch ? Thank you, Jiri Kovalsky NetCAT 4.0 Program Coordinator http://qa.netbeans.org/processes/cat/40/index.html
What is the anticipated release date for NetBeans 4.0?
Current plan for NB 4.0: # September 22 - 4.0 Beta-2 released based on Beta-1 feedback # End of September - High Resistance mode # Mid of November - RC build testing # End of November - CA survey launched # Mid of December - FCS release Would be very good to have it asap. Beta 2 preferably, definitelly before the RC builds are started to be produced.
Guys, maybe you should go ahead and try using standard input without an attribute with Ant 1.6.1-2 . It works for me; I am using a slightly modified version of the relevant code but I don't think there is anything that significantly different in my version. Thanks, Matt
As quoted in the original bug description above, the whole point of this bug is that, though stdin works for fork="false" (default), stdin does NOT work for fork="true". We can't just "go ahead and try using standard input without an attribute" when that attribute is what is required. All of my GUI server apps have optional consoles to allow for run-time debugging, monitoring, and recovery. It is a required feature in a reliability architecture. Since the execution of these consoles is impossible using Ant with fork="true" in any environment, I've upgraded the priority of this to "high". I absolutely must have this feature if I am to use Ant for run-time management. This bug has been open since 1.6.0, is 1 of only 16 bugs with this many votes, and already has a proposed implementation. Can we get some positive action here?
1. My apologies for having let it slip my mind that fork="true" was at the heart of the issue. 2. Calm down, there's no need to get all worked up. When's the last time that got you what you wanted? 3. Ant is not designed for run-time management in the first place ALTHOUGH this does not mean we don't want to arrive at a solution that will make everyone happy. I just want to make sure that whatever solution is chosen is the (or at least "a") right one for Ant's current architecture.
I introduced the run-time management concept to show yet another reason why this bug is of a high priority. It does not detract from the fact that stdin works for fork="false" and not for fork="true" (which, in my mind, makes this a bug and not an enhancement, but I was being nice). A polite, concise, and clear statement of facts does not indicate a "worked up" state. Please keep such personal comments off-line. This bug has been open for almost 10 months now, and it hasn't been assigned, progressed, or even discussed by the Ant team in this bug log until now. This reason, and the vote count, would seem more than appropriate for a call to action. Mr. Glick's patch is obviously proposed and would need appropriate review, but, given that it allows fork="true" to operate in a consistent manner with fork="false", it would seem an excellent basis from which to start and would encourage quick and effective progress.
Any updates regarding this issue?
Created attachment 14108 [details] Better Ant script to manually test functionality
Created attachment 14109 [details] Revised patch (against HEAD) Tested on Linux so far and works as expected.
I know this and the Redirector stuff were two competing initiatives--thanks for reworking your patch. I can (sometime) test this on Windows if you are looking for validation, but you've got commit rights now so if you're confident I have no problem with this going in and I can't see why anyone else would. I'm assuming the existing testcases pass which would verify that reading from System.in has no effect as no other input-expecting program would have worked before and thus would not be a part of an existing build, and programs not looking for input should be indifferent.
Well, part of that was wrong, I recall... I don't remember what circumstances allow input now but I'm pretty sure there are some after all. Anyway, the rest of what I said still stands. ;)
I just tested on Win XP and it works fine there too. All tests continue to pass for me (on JDK 1.4.2 on Linux). Compilation succeeds on JDK 1.2. Functionality also seems to work as expected embedded inside the NetBeans IDE. I am committing this to the Ant trunk (for 1.7) under the "lazy approval" theory. I think it would be a good candidate for a fix in 1.6.3, since this introduces no internal API or build script format changes and to my mind fixes a bug, but I will leave it to other committers to comment on that. Note that I am on vacation for the whole month of February, but if someone else would like to merge this to ANT_16_BRANCH that would be great. So a quick summary of what the problem was and what is now fixed: -------- In Ant 1.6.2 (for example), if you had a program which tried to read from standard input, and ran it with <java fork="false">, it would work fine. However if you ran it with <java fork="true">, it would not - it would get an immediate EOF. As far as I can tell, this is just because no one bothered to make it work, not that there is any particular benefit to disabling input for forked apps. In any case, as Conor mentions, passing the -noinput flag would cause even unforked apps to get an immediate EOF. With the patch, you can send console input to programs run with <java>, whether forked or not. (Not to spawned programs however.) -noinput still works in either case to suppress input. -------- You can use the "better Ant script..." to try it out. You can also confirm that it is possible to run more than one app taking stdin in the same Ant session; sending EOF (Ctrl-D on Unix, Ctrl-Z ENTER on Windows) stops input to the running app but does not prevent a subsequent app from accepting input normally. Unlike the original patch, the revised patch does *not* introduce a special attribute to the <java> task. I don't think one is required; it should be expected that forked and unforked apps work the same way unless there is a reason for them to differ, and that an app requesting input will get it unless you have a reason to suppress input. The current patch makes no API changes, since all code changes are in the same package and it is not necessary, but there are several places where an API addition would be natural; in those cases I have commented out "public" or "protected" but left it in the code so you can see what the API would be. Will leave it to other committers to comment on whether some or all of these API additions are desirable. Checking in WHATSNEW; /home/cvs/ant/WHATSNEW,v <-- WHATSNEW new revision: 1.731; previous revision: 1.730 done More commits to come... Checking in docs/manual/CoreTasks/java.html; /home/cvs/ant/docs/manual/CoreTasks/java.html,v <-- java.html new revision: 1.36; previous revision: 1.35 done More commits to come... Checking in src/main/org/apache/tools/ant/taskdefs/Java.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Java.java,v <-- Java.java new revision: 1.97; previous revision: 1.96 done Checking in src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java,v <-- PumpStreamHandler.java new revision: 1.21; previous revision: 1.20 done Checking in src/main/org/apache/tools/ant/taskdefs/Redirector.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Redirector.java,v <-- Redirector.java new revision: 1.24; previous revision: 1.23 done Checking in src/main/org/apache/tools/ant/taskdefs/StreamPumper.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java,v <-- StreamPumper.java new revision: 1.21; previous revision: 1.20 done
So, merging to the Ant 1.6.3 line: Checking in WHATSNEW; /home/cvs/ant/WHATSNEW,v <-- WHATSNEW new revision: 1.503.2.200; previous revision: 1.503.2.199 done More commits to come... Checking in docs/manual/CoreTasks/java.html; /home/cvs/ant/docs/manual/CoreTasks/java.html,v <-- java.html new revision: 1.24.2.12; previous revision: 1.24.2.11 done More commits to come... Checking in src/main/org/apache/tools/ant/taskdefs/Java.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Java.java,v <-- Java.java new revision: 1.77.2.12; previous revision: 1.77.2.11 done Checking in src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java,v <-- PumpStreamHandler.java new revision: 1.14.2.6; previous revision: 1.14.2.5 done Checking in src/main/org/apache/tools/ant/taskdefs/Redirector.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Redirector.java,v <-- Redirector.java new revision: 1.11.2.12; previous revision: 1.11.2.11 done Checking in src/main/org/apache/tools/ant/taskdefs/StreamPumper.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java,v <-- StreamPumper.java new revision: 1.16.2.5; previous revision: 1.16.2.4 done
Also backdating "since" text in the trunk: Checking in WHATSNEW; /home/cvs/ant/WHATSNEW,v <-- WHATSNEW new revision: 1.781; previous revision: 1.780 done More commits to come... Checking in docs/manual/CoreTasks/java.html; /home/cvs/ant/docs/manual/CoreTasks/java.html,v <-- java.html new revision: 1.40; previous revision: 1.39 done More commits to come... Checking in src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java,v <-- PumpStreamHandler.java new revision: 1.23; previous revision: 1.22 done Checking in src/main/org/apache/tools/ant/taskdefs/Redirector.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Redirector.java,v <-- Redirector.java new revision: 1.27; previous revision: 1.26 done Checking in src/main/org/apache/tools/ant/taskdefs/StreamPumper.java; /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java,v <-- StreamPumper.java new revision: 1.23; previous revision: 1.22 done