Understanding and Locating System.err on Windows

Explore how Java's System.err behaves on Windows, where its output goes by default, and how to redirect it for logging and debugging purposes.
When developing Java applications, System.out
and System.err
are fundamental streams for outputting information. While System.out
is typically used for standard program output, System.err
is designated for error messages and diagnostic information. On Unix-like systems, these often map directly to stdout
and stderr
file descriptors, which can be easily redirected. However, on Windows, the behavior can sometimes be less intuitive, leading to questions about where System.err
output actually goes.
Default Behavior of System.err on Windows
On Windows, when a Java application is executed from the command line (e.g., using java MyProgram
), both System.out
and System.err
typically print their output directly to the console window from which the program was launched. This means that, by default, error messages appear alongside standard output in the same command prompt. This can make it challenging to distinguish between normal program output and error messages, especially in verbose applications.
flowchart TD A[Java Application] --> B{System.out.println()} A --> C{System.err.println()} B --> D[Console (stdout)] C --> D[Console (stderr)] D[Console (stdout & stderr)]
Default output flow of System.out and System.err to the console on Windows.
Redirecting System.err Output
The ability to redirect System.err
is crucial for robust error handling, logging, and debugging. On Windows, you can redirect System.err
(file descriptor 2) independently of System.out
(file descriptor 1) using command-line operators. This allows you to capture error messages into a separate log file, preventing them from cluttering the standard output or being lost.
public class ErrorTest {
public static void main(String[] args) {
System.out.println("This is standard output.");
System.err.println("This is an error message.");
System.out.println("Another standard output line.");
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.err.println("Caught an exception: " + e.getMessage());
}
}
}
A simple Java program demonstrating System.out and System.err usage.
Command-Line Redirection on Windows
To redirect System.err
to a file, you use the 2>
operator. If you want to redirect both System.out
and System.err
to different files, or both to the same file, you can combine these operators. It's important to understand the order and syntax to achieve the desired redirection.
2>
for stderr
redirection and 1>
(or just >
) for stdout
redirection. The &1
syntax redirects stderr
to the same location as stdout
.1. Redirect System.err to a file
To send only error messages to a file named errors.log
, leaving standard output on the console, use: java ErrorTest 2> errors.log
2. Redirect System.out to a file and System.err to another
To send standard output to output.log
and error messages to errors.log
, use: java ErrorTest 1> output.log 2> errors.log
3. Redirect both System.out and System.err to the same file
To send both standard and error output to a single file named all_output.log
, use: java ErrorTest > all_output.log 2>&1
(Note: 2>&1
must come after > all_output.log
). Alternatively, java ErrorTest &> all_output.log
can be used in some shells like PowerShell.
4. Redirect System.err to NUL
If you want to suppress error messages entirely, you can redirect System.err
to the NUL
device: java ErrorTest 2> NUL