Bug 24918 - [PATCH] Permit console input to be sent to <java>
Summary: [PATCH] Permit console input to be sent to <java>
Status: RESOLVED FIXED
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: 1.6.0
Hardware: All All
: P1 enhancement with 22 votes (vote)
Target Milestone: 1.6.3
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks: 34461 36903
  Show dependency tree
 
Reported: 2003-11-22 16:05 UTC by Jesse Glick
Modified: 2005-09-29 04:55 UTC (History)
3 users (show)



Attachments
Possible patch to add <java standardinput="true"> (7.83 KB, patch)
2003-11-22 16:06 UTC, Jesse Glick
Details | Diff
Ant script to help manually test patch functionality (1.33 KB, text/plain)
2003-11-22 16:08 UTC, Jesse Glick
Details
Better Ant script to manually test functionality (2.01 KB, text/plain)
2005-01-27 01:28 UTC, Jesse Glick
Details
Revised patch (against HEAD) (10.07 KB, patch)
2005-01-27 01:34 UTC, Jesse Glick
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jesse Glick 2003-11-22 16:05:04 UTC
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
Comment 1 Jesse Glick 2003-11-22 16:06:34 UTC
Created attachment 9240 [details]
Possible patch to add <java standardinput="true">
Comment 2 Jesse Glick 2003-11-22 16:08:45 UTC
Created attachment 9241 [details]
Ant script to help manually test patch functionality
Comment 3 Conor MacNeill 2003-11-23 14:28:14 UTC
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.

Comment 4 Jesse Glick 2003-11-24 18:15:08 UTC
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.
Comment 5 Jesse Glick 2004-05-09 21:10:53 UTC
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.)
Comment 6 Jesse Glick 2004-07-27 19:13:14 UTC
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.
Comment 7 Curtis Clauson 2004-08-28 00:49:24 UTC
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.
Comment 8 Jiri Kovalsky 2004-09-01 09:16:18 UTC
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
Comment 9 Matt Benson 2004-09-01 14:42:25 UTC
What is the anticipated release date for NetBeans 4.0?
Comment 10 David Strupl 2004-09-01 19:15:32 UTC
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.
Comment 11 Matt Benson 2004-09-02 16:42:42 UTC
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
Comment 12 Curtis Clauson 2004-09-02 22:05:05 UTC
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?
Comment 13 Matt Benson 2004-09-02 22:15:06 UTC
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.
Comment 14 Curtis Clauson 2004-09-03 00:02:58 UTC
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.
Comment 15 Michael Ruflin 2005-01-12 20:49:34 UTC
Any updates regarding this issue?
Comment 16 Jesse Glick 2005-01-27 01:28:32 UTC
Created attachment 14108 [details]
Better Ant script to manually test functionality
Comment 17 Jesse Glick 2005-01-27 01:34:39 UTC
Created attachment 14109 [details]
Revised patch (against HEAD)

Tested on Linux so far and works as expected.
Comment 18 Matt Benson 2005-01-27 16:03:37 UTC
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.
Comment 19 Matt Benson 2005-01-27 16:05:16 UTC
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.  ;)
Comment 20 Jesse Glick 2005-01-27 17:36:45 UTC
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
Comment 21 Jesse Glick 2005-03-16 17:52:47 UTC
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
Comment 22 Jesse Glick 2005-03-16 17:56:47 UTC
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