Ich verwende ExecutorService
, um Mails asynchron zu versenden, also gibt es eine Klasse:
Das erledigt das Senden. Jede Ausnahme, die abgefangen wird, wird protokolliert, für (anonymisiertes) Beispiel:
%Vor% Nicht sehr hilfreich - Ich muss den Stack-Trace sehen, der die ExecutorService
aufgerufen hat, die das alles verursacht hat. Meine Lösung besteht darin, ein leeres Exception
zu erstellen und es in Mailer
:
Und jetzt im Ausnahmefall möchte ich das Problem selbst und seine Ursache von dem anderen Thread protokollieren:
%Vor% Das funktioniert großartig, produziert aber zwei Protokolle. Ich möchte t
und cause
zu einer einzigen Ausnahme kombinieren und diese protokollieren. Meiner Meinung nach verursacht t
cause
, also sollte cause.initCause(t)
der richtige Weg sein. Und funktioniert. Ich sehe einen vollständigen Stack-Trace: von wo der Aufruf den ganzen Weg bis zum AddressException
herrührt.
Problem ist, initCause()
funktioniert nur einmal und stürzt dann ab. Frage 1: kann ich Exception
klonen? Ich würde cause
klonen und es jedes Mal mit t
initiieren.
Ich habe versucht, t.initCause(cause)
, aber das stürzt sofort ab.
Frage 2: Gibt es eine andere clevere Möglichkeit, diese beiden Ausnahmen zu kombinieren? Oder behalte nur einen Thread-Kontext im anderen Thread-Kontext für Protokollierungszwecke?
Nach meinem Kommentar, das ist tatsächlich, was ich im Sinn hatte. Wohlgemerkt, ich kann es im Moment nicht testen.
Was Sie von Ihrem übergeordneten Thread übergeben, ist New Exception().getStackTrace()
. Oder noch besser, wie @Radiodef kommentierte, Thread.currentThread().getStackTrace()
. Es ist also im Grunde ein StackTraceElement[]
-Array.
Nun können Sie etwas wie:
haben %Vor%Nun können Sie in Ihrer catch-Klausel etwas wie:
tun %Vor%Damit erhalten Sie eine Grenze zwischen den beiden Stack-Traces.
Sie können das Objekt Future<v>
verwenden, das von Ihrem Submit-Aufruf zurückgegeben wurde, und anschließend die Methode get()
aufrufen. Wenn während der Ausführung der Task eine Ausnahme aufgetreten ist, wird sie erneut ausgelöst.
Eine weitere Option besteht darin, den standardmäßigen Ausnahmebehandler für die Thread-Factory anzupassen, der die Threads für Ihr ExecutorService
erstellt. Weitere Informationen finden Sie unter Thread.UncaughtExceptionHandler
Was ich tue, ist, dass der Thread, den du aufruft, die Ausnahme speichert, anstatt sie zu werfen.
Dann kann der Haupt-Thread, der ihn gestartet hat, ihn abfragen, um festzustellen, ob eine Ausnahme aufgetreten ist. Wenn einer hat, dann kann er die Ausnahme bekommen und einen als Ursache dafür ausgeben.
Ich glaube nicht, dass Sie eine Ausnahme klonen können.
Als eine allgemeine Regel ist diese Art des Bastelns mit Ausnahmen schlechte Nachrichten und ein Zeichen, dass es einige Probleme mit dem allgemeinen Ansatz zur Fehlerbehandlung im Code geben kann.
Es ist schwer zu tun, weil Sie nicht wirklich dazu bestimmt sind.
Sie können die Klasse ListableFuture
aus der Google Guava-Bibliothek verwenden. Siehe Ссылка
Tags und Links java multithreading logging stack-trace