What is the point of System.err? - java

In UNIX, I'm supposed to write a Java file that will print "EXIT 1" to the standard error, and then exit with a status of 1.
Here is my approach..
System.err.println("EXIT 1");
System.exit(1);
Is this what I'm supposed to do?
If so, how am I supposed to use it in the Unix shells? When I compile and run it in the bash, it just prints "EXIT 1" (so it does the same thing as System.out.println, why should I use "err"?). What is the "standard error" here?

Every running program has these three streams:
Standard input (stdin), which normally comes from the keyboard. Exposed as System.in
Standard out (stdout), which normally goes to the console. Exposed as
System.out
Standard error (stderr), which normally also goes to the console. Exposed as System.err
Your program is correct – it does print to stderr. But under normal circumstances, the stderr stream goes to the console just like the stdout stream, so they are visually indistinguishable.
However, the reason you should use stderr instead of stdout for error messages, is redirection. That means that you send stderr to a file instead of the console. Meanwhile, stdout will be unaffected, because the two streams are independent.
For example, you can do this in bash, cmd, PowerShell, etc:
$ java Program 2> errors.txt
Now, all output with System.err.println() will end up in errors.txt, while System.out.println() will still go to the screen. This can help with debugging.

There are three data streams associated with nearly every process:
Standard Input: This is the stream of input into a program, either from a terminal, a console, piped output from another process, or some other means.
Standard Error: This is where all debugging and error messages should go. This is so that this sort of information can easily be separately captured from the regular output of a program. Web servers do this, by sending error messages to an error_log file via stderr, while the normal log file would be e. g. access_log.
Standard Output: This is the where all typical, expected output that a user running a program should expect to see said output appear.
Standard Output (stdout) and Standard Error (stderr) are nearly always the first and second output streams coming from a process, respectively. This allows me to do something like /path/to/my/neat/program > logs/program.log 2> logs/program.err and have output and errors nicely sorted.

Related

Why does System.out.println() in Java print to the console?

I read several posts online explaining what System.out.println() is in Java. Most of them go like this:
System is a final class in the java.lang package.
out is a public static object inside the System class of type PrintStream.
println() prints a line of text to the output stream.
My question is when we do System.out.println() in our code, why does it end up writing to the console? This article explains how we can make it write to a file by calling System.setOut(). So my question translates to where is System.setOut() called to redirect its output to the console?
I checked System.setOut()'s source. It makes a call to setOut0() which is a native method. This method is directly called inside the initializeSystemClass() method by passing it fdOut which is a FileOutputStream defined here. I did not find a console output stream passed to setOut0() anywhere, nor did I find a call to the non-native setOut() done anywhere. Is it done somewhere else outside the System class by the JVM while starting execution? If so, can someone point me to it?
My doubt is when we do System.out.println() in our code, why it ends up in writing to console?
In any POSIX compliant shell, each process gets three "standard" streams when the shell starts it:
The "standard input" stream is for reading input.
The "standard output" stream is for writing ordinary output.
The "standard error" stream is for writing error output.
(The same idea is also used in many non-POSIX compliant shells as well.)
For an interactive POSIX shell, the default is for these streams to read from and write to the shell's "console" ... which could be a physical console, but is more likely to be a "terminal emulator" on the user's (ultimate) desktop machine. (Details vary.)
A POSIX shell allows you to redirect the standard streams in various ways; e.g.
$ some-command < file # read stdin from 'file'
$ some-command > file # write stdout to 'file'
$ some-command 2> file # write stderr to 'file'
$ some-command << EOF # read stdin from a 'here' document
lines of input
...
EOF
$ some-command | another # connect stdout for one command to
# stdin for the next one in a pipeline
and so on. If you do this, one or more of the standard streams is NOT connected to the console.
Further reading:
"What are stdin, stdout and stderr on Linux?"
"Standard Streams"
So how does this relate to the question?
When a Java program start, the System.in/out/err streams are connected to the standard input / output / error streams specified by the parent process; typically a shell.
In the case of System.out, that could be the console (however you define that) or it could be a file, or another program or ... /dev/null. But where the output goes is determined by how the JVM was launched.
So, the literal answer is "because that is what the parent process has told the Java program to do".
How internally shell communicates with jvm to set standard input / output in both Windows and Linux?
This is what happens with Linux, UNIX, Mac OSX and similar. (I don't know for Windows ... but I imagine it is similar.)
Suppose that the shell is going to run aaa > bbb.txt.
The parent shell forks a child process ... sharing the parent shell's address space.
The child process closes file descriptor 1 (the standard output file descriptor)
The child process opens "bbb.txt" for writing on file descriptor 1.
The child process execs the "aaa" command, and it becomes the "aaa" command process. The file descriptors 0, 1, and 2 are preserved by the exec call.
The "aaa" command starts ...
When the "aaa" command starts, it finds that file descriptors 0 and 2 (stdin and stderr) refer to the same "file" as the parent shell. File descriptor 1 (stdout) refers to "bbb.txt".
The same thing happens when "aaa" is the java command.
It doesn't need to. We can redirect to somewhere else. Here is the code to re-direct into the file:
PrintStream output = new PrintStream(new File("output.txt"));
System.setOut(output);
System.out.println("This will be written to file");
By default, the console is the standard output stream (System.in) in Java.
System.out.println does not print to the console, it prints to the standard output stream (System.out is Java's name of the standard output stream). The standard output stream is usually the console, but it doesn't have to be. The Java runtime just wraps the standard output stream of the operating system in a nice Java object.
A non-interactive program often uses a few standard input and output channels: it reads input from the standard input stream, does some operations on it, and produces output on the standard output stream. The standard output stream can be the console, but it can also be piped to the standard input stream of another program or to a file. In the end, the operating system running the programming decides what the standard output stream output to.
For example, in Unix terminals you can do something like:
java -jar your.program.jar > output.txt
and store the output of your program in a text file, or
java -jar your.program.jar | grep hello
to only display the lines of the output which contain 'hello'. Only if you don't specify another destination, the standard output stream writes to the console.

Is there a way to pick System.out or System.err messages when java program is executed using shell script

I needed to execute java class third party from shell script. When exception occurs, they are writing error message with System.err as per requirement. Now, when i executed the class in shell, i want to get that error message. I cannot get complete message in standard output and search for this message as its a big script and there are lot of messages. Is there a way to capture that specific System.err printed in java when i executed it in shell. ?Just let me know, if the problem is not clear enough.
To pick your java application (or whatever program for that matter) standard error in a variable while discarding its standard output, you can use this shell construction:
var=$(java MyApplication 2>&1 1>/dev/null)
If you don't want to discard the standard output, you can redirect it to a file instead of /dev/null, or redirect it to your terminal emulator using /dev/tty.
Please refer this-
How to print an error message to standard error?
I think the best answer to that question answers your question as well.

java/c++ How does output work? cout<< System.out.print

I am mostly concerned with Linux but answers involving windows are welcome.
When I use System.out.println or cout<< what is actually happening and what happens when I do a cout in a gui application (does it go anywhere)?
One case that I am interested in is the Netbeans IDE. When I run a java program in Netbeans what makes it possible for the IDE to "steal" the output from the program and display it?
Update/Sidenote
http://www.linfo.org/standard_output.html
One of the features of standard output is that it has a default
destination but can easily be redirected (i.e., diverted) to another
destination. That default destination is the display screen on the
computer that initiated the program. Because the standard streams are
plain text, they are by definition human readable.
What is meant by "initiate the program"?
I'm not very familiar with how the execution of a program begins but in the case of my netbeans example it's pretty clear that the IDE initiated the program. So what does that mean? When the program is being setup to be executed is there some meta data that is floating around letting the OS know that Netbeans is initiating the program?
When the program gets executed, three special file descriptors: stdin, stdout and stderr are associated to some device to determine how input and output is managed. If you execute a program from a terminal shell, stdin is associated to the keyboard, stdout and stderr to the terminal window. When you execute the program in a development environment usually stdout and stderr are displayed in some special console tabs. In other situations the output goes to some log file or maybe get discarded...
System.out and cout are the objects representing the stdout stream in Java and C++.

How to handle different stdout behaviour in external program?

Hi I am trying to execute external program from Java program and read the stdout message in real time, without waiting for the program to exit. However, i found that there are different stdout behaviour in different .exe program, and I don't know how to handle it.
Example 1:
server1.exe is a console program. When i run it, it will continuously listening on a port. When a client is connected to it, it will generate 1 line of stdout output every 1 second. It will not exit unless i press "ctrl-C".
In a command prompt, I run this:
server1.exe > stdout.out 2> stderr.err
When client is connected to it, I found that stdout.out file will be updated in real time. Even though server1.exe is still running, I can open stdout.out file and read the stdout output in real time.
Example 2:
Similar to server1.exe, server2.exe is also a console program. When i run it, it will also continuously listening on a port. When client is connected to it, it will generate 1 line of stdout output every 1 second. It will not exit unless i press "ctrl-C".
In a command prompt, I run this:
server2.exe > stdout.out 2> stderr.err
Even though client has connected to server2.exe, I found that stdout.out file is empty. As long as server2.exe is still running, no stdout is written to stdout.out file. That file is not updated in real time. When i press ctrl-C, it suddenly write many lines of output to stdout.out file.
Assuming that i press ctrl-C at t=11, it will write all stdout output from t=1 until t=11 into the stdout.out file. Before this, at t=10, the stdout.out file is empty.
The program in example 2 is giving me problem because I am unable to read the stdout in real time in my Java program. My java program is as below:
process = Runtime.getRuntime().exec(command);
input = new BufferedReader(new InputStreamReader(process.getInputStream()));
String inputtext = null;
while ((inputtext = input.readLine()) != null)
{
//print out the text in Real Time, when the .exe program is still running
}
May i know why the program in example 2 will not generate stdout output unless I press ctrl-C?
The strange thing is, when i run that program in console window manually, I can see the stdout output printed on the console window every 1 second. But when I try to read it from Java using inputtext = input.readLine(), inputtext will be null as long as the program is still running (I have tested it by printing out inputtext). When I press ctrl-C, the BufferedReader will suddenly be filled with all the pending stdout output.
How can I read stdout of server2.exe in real time?
The way you describe things, there is some buffering happening in your second server. The server might decide to buffer output internally, unless it is connected to a live interactive console window.
While there may be ways to work around this, I would address this in the server2 source code. Whenever that application writes its once-per-second output, it should flush its output streams afterwards. Perhaps there is some option to enable that behaviour. If there isn't, and if the sources of that program are outside your control, kindly ask the developers to add flushing, in order to allow for better integration.
For short: You need to flush the buffers.
System.out.flush()
You need to do this after every chunk of relevant data written on these streams, try doing it after every line print.

System.out.println without printing to file when using " > filename"

I have a peculiar problem. I have a Java program that is run with the command :
cat input_file_name | ./script_name > file_output_name
the script_name script just does : java myprogram
My question is : how can I print out something in the console without it being "put in the file_output_name file" (since the > file puts all System.out.prints in that file)
I know this is possible because there are some already that come from some class in a library that I'm using from my java program. However I can't find the exact source of those prints so I don't know how it is coded.
Thank you for any help.
The simple answer is to write those messages to System.err rather than System.out.
This will work since > redirects standard output but not standard error. (You can redirect standard error, but the shell syntax is different; e.g. foo 2> /tmp/somefile.)
A more complicated alternative is to change your program so that it can be called with the name of the output file as an argument. Then open the file, wrap it in a PrintWriter and write to that stream rather than System.out. With a bit of refactoring, you should be able to structure your program so that it can be used either way.
The easiest way is to use System.err.println() instead of System.out.
It will go to a different "device" (stderr instead of stdout), and it won't be redirected.
With what you've shown, you're only redirecting the standard out (stdout). You can write something to the standard error (stderr) instead to have it show on the console yet. In Java, this can be done by System.err.println(...), and related methods.
Notice that if a Java program writes to standard output, it can't control where does its output get redirected, that depends on how the program is invoked from the command line.
Having that clear, you can redirect the program's standard output only to the console, by simply removing the > file_output_name part from the command.
Or, you can redirect the output of the program to both the console and a file by using the tee command, take a look at this article which explains in detail how to do it.

Categories

Resources