检测写入标准错误流
Detecting write to standard error stream
有没有办法(不管"hacky"如何)以类似于以下代码的方式检测何时Java的System.err
has been written to in order to be able to execute logic if and when this happens? — I'm currently working with a custom subclass of Thread
(let's call it SwallowingThread
) which swallows a number of exceptions in its implementation of Thread.run()
:
public final class SwallowingThread extends Thread {
...
@Override
public void run() {
ServerSocket socket = new ServerSocket(80, 100);
try {
Socket connected = socket.accept();
// Do stuff with socket here
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是,在我的代码中,我希望能够处理在使用 SwallowingThread
的实例时发生的 UnknownHostException
和 IOException
的情况;有没有办法检测到这种捕获并在发生后打印到标准错误? — 我最初尝试编写一个 UncaughtExceptionHandler
来执行此操作只是为了发现它没有捕获异常,因为它们被吞没了而不是简单地被例如。包裹在 RuntimeException
中并向前抛出。
当然,解决这个问题的 "better" 方法是重新编写 class 的逻辑,但是没有快速而肮脏的方法来解决这个问题吗?触摸 SwallowingThread
?
您可以实现自己的 class(我称之为 DelegatingErrorPrintStream)派生自 PrintStream,它会在有新输出时通知您,然后委托给 System.err
现在您可以将 YOUR DelegatingErrorPrintStream 设置为 System.err 使用的输出流
System.setErr(错误);
包括用法在内的完整示例:
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
public class ErrorNotifierExample {
private static final class ErrorDelegatingPrintStream extends PrintStream {
public ErrorDelegatingPrintStream(PrintStream defaultErr)
throws FileNotFoundException, UnsupportedEncodingException {
super(defaultErr);
}
@Override
public void print(boolean b) {
super.print(b);
notifyListener(b);
}
@Override
public void print(char c) {
super.print(c);
notifyListener(c);
}
@Override
public void print(int i) {
super.print(i);
notifyListener(i);
}
@Override
public void print(long l) {
super.print(l);
notifyListener(l);
}
@Override
public void print(float f) {
super.print(f);
notifyListener(f);
}
@Override
public void print(double d) {
super.print(d);
notifyListener(d);
}
@Override
public void print(char[] s) {
super.print(s);
notifyListener(s);
}
@Override
public void print(String s) {
super.print(s);
notifyListener(s);
}
@Override
public void print(Object obj) {
super.print(obj);
notifyListener(obj);
}
@Override
public PrintStream append(CharSequence csq, int start, int end) {
notifyListener(csq); // TODO will need some special handling
return super.append(csq, start, end);
}
private void notifyListener(Object string) {
// TODO implement your handling here. System.out printing is just an
// example.
System.out.println(String.valueOf(string));
}
}
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
ErrorDelegatingPrintStream errReplacement = new ErrorDelegatingPrintStream(System.err);
System.setErr(errReplacement);
System.err.println("TEST01");
throw new RuntimeException("just a test output for ERROR handling");
}
}
正如几个人已经建议的那样,您可以使用自定义 PrintStream
。
它将取代标准错误流,但也会封装它并在需要时调用它。
由于异常和堆栈跟踪是您感兴趣的内容,因此覆盖 print(String)
应该就足够了(println(String)
已经调用了此方法 + newLine()
)。
流可能看起来像这样:
import java.io.PrintStream;
public class CustomPrintStream extends PrintStream {
public CustomPrintStream(final PrintStream out) {
super(out);
}
@Override
public void print(final String s) {
super.print(s);
// some String is written to the error stream, Do something !
}
}
你会那样使用它,在你的应用程序开始时,只需调用
System.setErr(new CustomPrintStream(System.err));
有没有办法(不管"hacky"如何)以类似于以下代码的方式检测何时Java的System.err
has been written to in order to be able to execute logic if and when this happens? — I'm currently working with a custom subclass of Thread
(let's call it SwallowingThread
) which swallows a number of exceptions in its implementation of Thread.run()
:
public final class SwallowingThread extends Thread {
...
@Override
public void run() {
ServerSocket socket = new ServerSocket(80, 100);
try {
Socket connected = socket.accept();
// Do stuff with socket here
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是,在我的代码中,我希望能够处理在使用 SwallowingThread
的实例时发生的 UnknownHostException
和 IOException
的情况;有没有办法检测到这种捕获并在发生后打印到标准错误? — 我最初尝试编写一个 UncaughtExceptionHandler
来执行此操作只是为了发现它没有捕获异常,因为它们被吞没了而不是简单地被例如。包裹在 RuntimeException
中并向前抛出。
当然,解决这个问题的 "better" 方法是重新编写 class 的逻辑,但是没有快速而肮脏的方法来解决这个问题吗?触摸 SwallowingThread
?
您可以实现自己的 class(我称之为 DelegatingErrorPrintStream)派生自 PrintStream,它会在有新输出时通知您,然后委托给 System.err 现在您可以将 YOUR DelegatingErrorPrintStream 设置为 System.err 使用的输出流 System.setErr(错误);
包括用法在内的完整示例:
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
public class ErrorNotifierExample {
private static final class ErrorDelegatingPrintStream extends PrintStream {
public ErrorDelegatingPrintStream(PrintStream defaultErr)
throws FileNotFoundException, UnsupportedEncodingException {
super(defaultErr);
}
@Override
public void print(boolean b) {
super.print(b);
notifyListener(b);
}
@Override
public void print(char c) {
super.print(c);
notifyListener(c);
}
@Override
public void print(int i) {
super.print(i);
notifyListener(i);
}
@Override
public void print(long l) {
super.print(l);
notifyListener(l);
}
@Override
public void print(float f) {
super.print(f);
notifyListener(f);
}
@Override
public void print(double d) {
super.print(d);
notifyListener(d);
}
@Override
public void print(char[] s) {
super.print(s);
notifyListener(s);
}
@Override
public void print(String s) {
super.print(s);
notifyListener(s);
}
@Override
public void print(Object obj) {
super.print(obj);
notifyListener(obj);
}
@Override
public PrintStream append(CharSequence csq, int start, int end) {
notifyListener(csq); // TODO will need some special handling
return super.append(csq, start, end);
}
private void notifyListener(Object string) {
// TODO implement your handling here. System.out printing is just an
// example.
System.out.println(String.valueOf(string));
}
}
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
ErrorDelegatingPrintStream errReplacement = new ErrorDelegatingPrintStream(System.err);
System.setErr(errReplacement);
System.err.println("TEST01");
throw new RuntimeException("just a test output for ERROR handling");
}
}
正如几个人已经建议的那样,您可以使用自定义 PrintStream
。
它将取代标准错误流,但也会封装它并在需要时调用它。
由于异常和堆栈跟踪是您感兴趣的内容,因此覆盖 print(String)
应该就足够了(println(String)
已经调用了此方法 + newLine()
)。
流可能看起来像这样:
import java.io.PrintStream;
public class CustomPrintStream extends PrintStream {
public CustomPrintStream(final PrintStream out) {
super(out);
}
@Override
public void print(final String s) {
super.print(s);
// some String is written to the error stream, Do something !
}
}
你会那样使用它,在你的应用程序开始时,只需调用
System.setErr(new CustomPrintStream(System.err));