Understanding and Locating System.err on Windows

Hero image for Where is 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.

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