Class ThreadMappedStdIO
Note, this is neessarily imperfect - if some other code replaces Syetem.out with something else, we do not detect that situation (it would be impossible to know what to do anyway - maybe the replacement wraps our output, maybe it doesn't) - so this code assumes it is the only thing in the system fiddling with the identity of the system stdout.
System.out and System.err will be restored fully
when the last concurrent thread exits a closure that replaced either, so this
class is zero-impact when not actively in use. Note: There are synchronized
blocks on initiating and exiting, so if many threads are contending to
replace stdio, liveness issues are possible.
Reentrancy is supported, so a thread may replace stdout and stderr, then do so again, and state will be restored correctly as each caller exits its closure.
Basically, the issue is that Antlr has calls to println baked into it, parsers and lexers by default attach listeners that do so as well, and catching every case where one might not have them removed is difficult. The output is more usefully routed to the output window anyway, so getting it out of the console output is handy.
- Author:
- Tim Boudreau
-
Method Summary
Modifier and TypeMethodDescriptionstatic voidblackhole(ThrowingRunnable toRun) Discard any attempts at writing to stdout or stderr during the closure of the passed runnable, while not interfering with output from other threads.static <T> Tblackhole(ThrowingSupplier<T> toRun) Discard any attempts at writing to stdout or stderr during the closure of the passed supplier, while not interfering with output from other threads.static voidDiscard any attempts at writing to stdout or stderr during the closure of the passed runnable, while not interfering with output from other threads.static <T> TblackholeNonThrowing(Supplier<T> toRun) Discard any attempts at writing to stdout or stderr during the closure of the passed supplier, while not interfering with output from other threads.static voidIf any alternate stdout or stderr is set for the current thread, bypass that and use the original for one runnable; this is needed in cases where you are patching or subclassing in a library that is sloppy with stdout, but you have things you legitimately need to log, and want to be sure that a console logger logs to the right place.static voidenter(PrintStream output, ThrowingRunnable toRun) Replace the standard output and error with a single stream, for the current thread, for the duration of the closure of the passed ThrowingRunnable.static <T> Tenter(PrintStream output, ThrowingSupplier<T> toRun) Replace the standard output and error with a single stream, for the current thread, for the duration of the closure of the passed ThrowingSupplier.static voidenter(PrintStream output, PrintStream error, ThrowingRunnable toRun) Replace the standard output and error with the passed streams, for the current thread, for the duration of the closure of the passed ThrowingRunnable.static <T> Tenter(PrintStream output, PrintStream error, ThrowingSupplier<T> toRun) Replace the standard output and error with the passed streams, for the current thread, for the duration of the closure of the passed ThrowingSupplier.static voidenterNonThrowing(PrintStream output, PrintStream error, Runnable toRun) Replace the standard output and error with the passed streams, for the current thread, for the duration of the closure of the passed ThrowingRunnable.static <T> TenterNonThrowing(PrintStream stdout, PrintStream stderr, Supplier<T> toRun) Replace the standard output and error with a single stream, for the current thread, for the duration of the closure of the passed ThrowingSupplier.static voidenterNonThrowing(PrintStream output, Runnable toRun) Replace the standard output and error with the passed stream, for the current thread, for the duration of the closure of the passed Runnable.static <T> TenterNonThrowing(PrintStream output, Supplier<T> toRun) Replace the standard output and error with a single stream, for the current thread, for the duration of the closure of the passed ThrowingSupplier.
-
Method Details
-
bypass
If any alternate stdout or stderr is set for the current thread, bypass that and use the original for one runnable; this is needed in cases where you are patching or subclassing in a library that is sloppy with stdout, but you have things you legitimately need to log, and want to be sure that a console logger logs to the right place.- Parameters:
r- A runnable
-
blackholeNonThrowing
Discard any attempts at writing to stdout or stderr during the closure of the passed supplier, while not interfering with output from other threads.- Type Parameters:
T- The return type- Parameters:
toRun- A supplier- Returns:
- The value returned by the supplier
-
blackhole
Discard any attempts at writing to stdout or stderr during the closure of the passed runnable, while not interfering with output from other threads.- Parameters:
toRun- A runnable
-
blackhole
Discard any attempts at writing to stdout or stderr during the closure of the passed runnable, while not interfering with output from other threads.- Parameters:
toRun- A runnable- Throws:
Exception
-
blackhole
Discard any attempts at writing to stdout or stderr during the closure of the passed supplier, while not interfering with output from other threads.- Type Parameters:
T- The return type- Parameters:
toRun- A supplier- Returns:
- The value returned by the supplier
- Throws:
Exception
-
enter
Replace the standard output and error with a single stream, for the current thread, for the duration of the closure of the passed ThrowingSupplier.- Type Parameters:
T- The return type- Parameters:
output- The print stream to output to instead of the system onetoRun- The code to run with that set as the stdout and stderr- Returns:
- The result of the supplier
- Throws:
Exception- If something goes wrong
-
enterNonThrowing
Replace the standard output and error with a single stream, for the current thread, for the duration of the closure of the passed ThrowingSupplier.- Type Parameters:
T- The return type- Parameters:
output- The print stream to output to instead of the system onetoRun- The code to run with that set as the stdout and stderr- Returns:
- The result of the supplier
- Throws:
Exception- If something goes wrong
-
enterNonThrowing
Replace the standard output and error with a single stream, for the current thread, for the duration of the closure of the passed ThrowingSupplier.- Type Parameters:
T- The return type- Parameters:
stdout- The print stream to output to instead of the system onetoRun- The code to run with that set as the stdout and stderr- Returns:
- The result of the supplier
- Throws:
Exception- If something goes wrong
-
enter
Replace the standard output and error with a single stream, for the current thread, for the duration of the closure of the passed ThrowingRunnable.- Parameters:
output- The print stream to output to instead of the system onetoRun- The code to run with that set as the stdout and stderr- Throws:
Exception- If something goes wrong
-
enter
public static void enter(PrintStream output, PrintStream error, ThrowingRunnable toRun) throws Exception Replace the standard output and error with the passed streams, for the current thread, for the duration of the closure of the passed ThrowingRunnable.- Parameters:
output- The print stream to output stdout to instead of the system oneerror- The print stream to output stderr to instead of the system onetoRun- The code to run with that set as the stdout and stderr- Throws:
Exception- If something goes wrong
-
enterNonThrowing
Replace the standard output and error with the passed streams, for the current thread, for the duration of the closure of the passed ThrowingRunnable.- Parameters:
output- The print stream to output stdout to instead of the system oneerror- The print stream to output stderr to instead of the system onetoRun- The code to run with that set as the stdout and stderr- Throws:
Exception- If something goes wrong
-
enterNonThrowing
Replace the standard output and error with the passed stream, for the current thread, for the duration of the closure of the passed Runnable.- Parameters:
output- The print stream to output stdout to instead of the system onetoRun- The code to run with that set as the stdout and stderr- Throws:
Exception- If something goes wrong
-
enter
public static <T> T enter(PrintStream output, PrintStream error, ThrowingSupplier<T> toRun) throws Exception Replace the standard output and error with the passed streams, for the current thread, for the duration of the closure of the passed ThrowingSupplier.- Type Parameters:
T- The return type- Parameters:
output- The print stream to output stdout to instead of the system oneerror- The print stream to output stderr to instead of the system onetoRun- The code to run with that set as the stdout and stderr- Returns:
- The result of the supplier
- Throws:
Exception- If something goes wrong
-