I am going through the Java IO. Just started with standard input and output streams. Please look at the simple program given below,
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
System.out.println("Give us your input");
String str = scanner.nextLine();
System.out.println("Standard Output: " + str);
System.err.println("Standard Error Output: " +str );
}
The output varies while running this two or three times. Please find couple of the outputs below,
Running for the first time:
Give us your input
my Name
Standard Error Output: my Name
Standard Output: my Name
Process finished with exit code 0
Running second time with the same code:
Give us your input
my Name
Standard Output: my Name
Standard Error Output: my Name
Process finished with exit code 0
I would like to know why the output changes with System.err
Your program will write to first System.out and then System.err (and println will flush these streams as well), but there is no guarantee in which order/interleaving the two streams will appear in your console.
Since you are writing to them at practically the same time, you will get both combinations. I suppose you might even get half-line interleavings.
System.out and System.err write to different streams that are connected via different pipes to your command shell. The command shell will then read from these pipes and write the data to your console application. That will ultimately write to your screen.
There are a number of places where data written to one stream could "overtake" data written to the other one.
It could possibly occur in the JVM itself, since the Java specs make no guarantees about which stream gets written first. (In fact, this is unlikely if there is only one thread doing the writing. With current Java implementations, the behavior will probably be deterministic ... though unspecified.)
It could be happening in the OS, since there are no guarantees on the order of delivery of data written to two independent pipes.
It could be happening in the shell, since nothing in the shell specs place any priority of reading from the pipes.
In short, there are lots of areas where the behavior is unspecified.
It is also worth noting that the observed behavior is liable to depend on the version of Java you use, the OS and OS tools, your hardware, and the load on your system.
Finally, there is probably nothing that you could do to guarantee that the observed interleaving (or not) are consistent. If you need consistency, write your output to one stream or the other exclusively.
no guarantee of order for System.out, System.in, System.err anything can be appeared first so order of these streams are not fixed
Related
How would you reprint a line after taking an input from the user (from terminal)?
I realise that you could reprint a line using:
System.out.print("\r foo");
System.out.print("\r bar");
Which will produce the output:
bar
but once you take an input from the user, this doesn't seem to work. For instance:
System.out.print("\r foo");
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
System.out.print("\r bar");
If you type in 1 as the input, you get:
foo1
bar
Can you reprint on the same line as foo (or more specifically, foo1) once the user has provided an input?
The key here is likely to be "raw" vs "cooked" mode of input. To do what you want, you will need to use "raw" mode where you collect each character as it is typed, and decide what to do with it, including whether you echo it to the console or not.
Cooked mode is more common for simple command line program input, and basically means "Give me the user's input, one line at a time". And "one line at a time" generally translates to "when the user presses enter." Most "cooked" implementations echo the keyboard input to the console.
For a host of reasons, doing "raw" mode in CLI programs is difficult -- not impossible, but difficult. I will spare the details in this venue (which are numerous and do not lend themselves to easy copy and paste here), and instead point you to the resource I used when attempting the same a few years ago:
Non blocking console input in Python and Java
A quick hunteke summary: the terminal/console needs to change state, not just your program, and there is no portable method for doing so. You'll be outsourcing to other libraries or programs to do what you want -- just don't forget to undo it when your program quits, or your users won't be happy!
I am asking this question particularly for an Expect implementation in Java. However, I would like to know general suggestions as well.
In Expect programming, is it possible to expect exactly what is prompted after spawning a new process?
For example, instead of expecting some pattern or a fixed string, isn't it better to just expect what is prompted. I feel this should be really helpful at times(especially when there's no conditional sending).
Consider the sample java code here that uses JSch and Expect4j java libraries to do ssh and execute list of commands(ls,pwd,mkdir testdir) on the remote machine.
My question here is why is it necessary to specify a pattern for the prompt? Is it not possible it to get the exact prompt from Channel itself and expect it?
I've programmed in "expect" and in "java".
I think you misunderstand what "expect" basically does. It doesn't look for exact items prompted after spawning a new process.
An expect program basically consists of:
Something that reads the terminal
A set of patterns (typically regular expressions), coupled to a blocks of code.
So, when a new process is spawned, there's a loop that looks something like this
while (terminal.hasMoreText()) {
buffered_text += terminal.readInput();
for (Pattern pattern : patterns) {
if (pattern.matches(buffered_text)) {
String match = pattern.getMatch(buffered_text);
bufferedText.removeAllTextBefore(match);
bufferedText.removeText(match);
pattern.executeBlock();
}
}
}
Of course, this is a massive generalization. But it is close enough to illustrate that expect itself doesn't "exactly expect" anything after launching a process. The program provided to the expect interpreter (which primarily consists of patterns and blocks of code to execute when the patterns match) contains the items which the interpreter's loop will use to match the process's output.
This is why you see some pretty odd expect scripts. For example, nearly everyone "expects" "ogin:" instead of "Login:" because there's little consistency on whether the login prompt is upper or lower case.
You don't have to expect anything. You're free to just send commands immediately and indiscriminately.
It's considered good practice to only reply to specific prompts so that you don't accidentally ruin something by saying the wrong thing at the wrong time, but you're entirely free to ignore this.
The main consideration is that while your normal flow might be:
$ create-backup
$ mkdir latest
$ mv backup.tar.gz latest
With no expectations and just blindly writing input, you can end up with this:
$ create-backup
Disk full, cleanup started...
Largest file: precious-family-memories.tar (510MB)
[R]emove, [S]ave, [A]bort
Invalid input: m
Invalid input: k
Invalid input: d
Invalid input: i
Removing file...
$ latest
latest: command not found
$ mv backup.tar.gz latest
whereas a program that expects $ before continuing would just wait and eventually realize that things are not going according to plan.
A few commands are sensitive to timing (e.g. telnet), but other than that you can send commands whenever you want, with or without waiting for anything at all.
My code is as follows:
public class BoxingUnboxingExample {
public static void main(String[] args) {
Integer i1 = null;
Integer i3 = 10;
BoxingUnboxingExample b = new BoxingUnboxingExample();
b.go(i3);
b.go(i1);
}
private void go(int a){
System.out.println("a");
}
}
Now my question is:
Sometimes I get the following error message,
Exception in thread "main" java.lang.NullPointerException
at scjp.wraperExample.BoxingUnboxingExample.main(BoxingUnboxingExample.java:12)
a
Whereas, I think It should always be the following,
a
Exception in thread "main" java.lang.NullPointerException
at scjp.wraperExample.BoxingUnboxingExample.main(BoxingUnboxingExample.java:12)
Am I correct?
One reason could be the exception stack trace uses standard error (System.err) to output the error data while System.out.println uses standard output (System.out).
That means both are using different mechanisms to output the data, these may not be properly synchronized.
You can also refer this earlier question.
ex
If you are in Eclipse, this is a known problem, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=32205
Output and Error are two different streams System.err and System.out.
Read this:
It is acceptable—and normal—for standard output and standard error to
be directed to the same destination, such as the text terminal.
Messages appear in the same order as the program writes them, unless
buffering is involved. (For example, a common situation is when the
standard error stream is unbuffered but the standard output stream is
line-buffered; in this case, text written to standard error later may
appear on the terminal earlier, if the standard output stream's buffer
is not yet full.)
from wikipeda
so your output stream (System.out.println) is actually buffered. Internally it calles the BufferedWriter.write() methode. take alook at this:
How System.out.println() really works
There are at least 2 effects at play here, both related to how System.out and System.err are (naturally) 2 different streams.
Buffering
System.err and System.out are both PrintStreams, which are buffered by default, however System.err is usually set to auto-flush after every write (of a byte array or whenever a newline is written).
As such, if System.err is flushed before System.out is flushed, it will appear on screen first.
The reading of those streams
In editors, it is not uncommon for both System.out and System.err to be displayed within a single console. The way this happens will influence the order in which they are displayed. Eclipse has 2 processes, one for every stream, to read from the streams and display them. The order in which they will read (and as such, display) is non-deterministic. The process that reads from System.err would have a 50% chance of being the first to receive input if both streams are written to quasi-simultanously. As such, they may appear to be randomly interleaved.
public class Main {
public static void main(String[] args) {
System.setErr(System.out); // this line seems to solve the problem
System.out.println("test");
throw new RuntimeException("Test");
}
}
This has been asked before, but was not clarified to the point where I get it. Similar to the one or two other threads I've seen on this subject, I'm working on a chat client with command line inputs for logging in/off, disconnecting, etc. and I am unsure how to simulate this in a JUnit test case. Other responses indicated that I should try changing the System.in to a separate InputStream but...then what?
tl;dr: I have a method in my actual code for parsing command line input, and need a JUnit way of testing that these were entered and appropriately processed.
EDIT: It seems I misunderstood the question. I usually use the term "command line input" to refer to command line arguments given to the process to start with, rather than interactive console input. However...
Handing your real code either a different InputStream or possibly even a Reader or Scanner would indeed help - anything to separate the "getting input" part from the console. You can then fake the input all in one go pretty easily, using a String as input in your test code, and then either converting it to bytes and wrapping those bytes in a ByteArrayInputStream or wrapping the string directly in StringReader.
The downside of this is that there's no easy way of making this "pause" after one command in order to check the results.
You may want to alter the design somewhat so that the part which reads the input is separated from the part which handles the input. The reading part could be a very simple loop, on the order of:
String line;
while ((line = reader.readLine()) != null) {
handleInput(line);
}
You could then potentially leave that part untested by unit tests, or write some relatively primitive tests - but you can then test handleInput extensively, as it's now separated from the input source.
Original answer
If you've extracted the parsing code from the code which really starts the application, it's easy: run that code, and check the results. This will be easiest if you have some sort of class encapsulating the options, of course. For example, your main method might look like this:
public static void main(String[] args) {
Options options = Options.parse(args);
// Use options here
}
Then you can just test Options.parse very easily.
I am trying to develop a class that reads the standard output of an external program(using an instance of Process, Runtime.getRuntime().exec(cmdLine, env, dir)).
The program takes user inputs during the process, and would not proceed until a valid input is given; this seems to be causing a problem in the way I am trying to read its output:
egm.execute(); // run external the program with specified arguments
BufferedInputStream stdout = new BufferedInputStream(egm.getInputStream());
BufferedInputStream stderr = new BufferedInputStream(egm.getErrorStream());
BufferedOutputStream stdin = new BufferedOutputStream(egm.getOutputStream());
int c; //standard output input stream
int e; //standadr error input stream
while((c=stdout.read()) != -1) //<-- the Java class stops here, waiting for input?
{
egm.processStdOutStream((char)c);
}
while((e=stderr.read()) != -1)
{
egm.processStdErrStream((char)e);
}
//...
How can I fix this so that the program takes in a valid input and proceed? Any help resolving this problem will be great!
You have to consume both the program's stdout and stderr concurrently to avoid blocking scenarios.
See this article for more info, and in particular note the StreamGobbler mechanism that captures stdout/err in separate threads. This is essential to prevent blocking and is the source of numerous errors if you don't do it properly!
In this situation you should have separate Threads reading InputStream and ErrStream.
Also you may want to do something like:
public void run() {
while( iShouldStillBeRunning ) {
int c;
while( stdout.available() > 0 && ((c=stdout.read()) != -1)) {
egm.processStdOutStream((char)c);
}
Thread.sleep(100);
}
}
Because you will get blocked on stdout.read() until there is input.
For one thing, this may block if it's writing to the error stream and has exhausted the buffer - you're not reading from the error stream until the output stream has completely finished.
Next, you say it takes user input during the process - are you giving it any user input by writing to stdin? If it's waiting for input, you should write to stdin appropriately, and flush it.
You're not saying in your question what is actually happening when you try to run this. Please update with a detailed description of what happens, and what you would expect to happen instead. Bonus points for telling us what the command is.
Also, is this UNIX/Linux or Windows? If this is UNIX/Linux (or some other POSIX platform), the program may be looking for input on /dev/console instead of /dev/stdin for security reasons.
For the benefit of others looking for solutions to this type of problem I just want to add that I had a very similar problem. But in my case the program was also waiting for a single line of input. So there need to be three threads involved to asynchronously handle all three channels.
Without writing to the output (i.e. the stdin of the executing program) caused the input (i.e. the output from the executing program) not to be captured completely. Writing to it hanged the process.
The solution was the three words by Jon Skeet: "and flush it". After adding the flush, no hang. Thanks!