2017-01-25 2 views
1

Gibt es keine Möglichkeit (unabhängig davon, wie "hacky" es ist) zu erkennen, wenn System.err von Java in geschrieben wurde, um Logik auszuführen, wenn und wenn dies geschieht? — Ich bin derzeit mit einer benutzerdefinierten Unterklasse von Thread arbeite (sie es SwallowingThread nennen), die eine Reihe von Ausnahmen bei der Umsetzung von Thread.run() in ähnlicher Weise wie in den folgenden Code schluckt:Erkennen von Schreiben in Standardfehlerstrom

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(); 
     } 
    } 
} 

In meinem Code, aber Ich möchte in der Lage sein, Fälle von UnknownHostException und IOException zu behandeln, die bei Verwendung einer Instanz von SwallowingThread auftreten; Gibt es keine Möglichkeit zu erkennen, dass dieses Abfangen und Drucken auf den Standardfehler, nachdem es aufgetreten ist? — Ich hatte ursprünglich versucht, eine UncaughtExceptionHandler zu schreiben, um dies nur zu tun, um herauszufinden, dass es die Ausnahmen nicht fängt, weil sie geschluckt wurden, anstatt einfach z. in eine RuntimeException gewickelt und weiter geworfen.

Natürlich ist ein "besserer" Weg, dieses Problem zu lösen, die Logik für die Klasse neu zu schreiben, aber gibt es keine schnelle und schmutzige Möglichkeit, dieses Problem zu lösen, ohne zu berühren?

+2

Sie konnten 'PrintStream' erstellen, die Wraps' System.err' vielleicht? 'System.setErr (neu MyDelegatingPrintStream (System.err));' –

+1

Mögliches Duplikat von [Redirect System.out und System.err] (http://stackoverflow.com/questions/14715748/redirect-system-out-and- system-err) –

+0

@MuratK, nein, ich möchte die Daten, die in stderr eingegeben wurden, nicht einfach an einen anderen Ort stellen: Ich möchte mal eine Logik ausführen können/wenn diese Daten in stderr geschrieben werden. – errantlinguist

Antwort

4

Sie können Ihre eigene Klasse implementieren (ich nenne es DelegatingErrorPrintStream) von Print abgeleitet, die Sie darüber informiert, wenn es neue Ausgabe ist, und die Delegierten dann System.err Und jetzt können Sie Ihre DelegatingErrorPrintStream als Ausgangsstrom für System.err eingestellt unter Verwendung von System.setErr (Fehler);

Voll Beispiel einschließlich Nutzung:

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"); 
} 
} 
+0

Alle diese Antworten waren ausgezeichnet, aber das war fast genau das, was ich getan habe (insbesondere durch die Übergabe eines 'Consumers ' als Delegat anstelle der 'notifyListener (Object)' Logik). – errantlinguist

2

Da mehrere Personen, die bereits vorgeschlagen, Sie mit einem benutzerdefinierten PrintStream gehen kann.

Es wird den Standardfehlerstrom ersetzen, aber auch einkapseln und bei Bedarf aufrufen.

Da die Ausnahmen und Stack-Traces Sie interessieren, sollte das Überschreiben print(String) reichen (println(String) nennt diese Methode bereits + newLine()).

Der Strom könnte so aussehen:

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 ! 

    } 

} 

Sie es, auf diese Weise verwenden würde zu Beginn der Anwendung, rufen Sie einfach

System.setErr(new CustomPrintStream(System.err));