es una especie de fácil:
Throwable tiene métodos getStackTrace()
y setStackTrace()
.
De one of my projects (de código abierto no, pero tal vez voy a abrir algún día el motor remoto de llamadas):
/**
* Setzt den Stack-Trace zusammen. Das untere Ende (tiefer in der
* Aufrufhierarchie, am Anfang des Arrays/der Ausgabe) ist das,
* welches im Throwable schon drin ist, das obere Ende wird aus
* dem aktuellen Stack genommen. Dazwischen
* kommt ein "Remote-Aufruf-Markierer".
*/
traducido para su conveniencia:
fusiona el seguimiento de la pila. El extremo inferior (más profundo en la jerarquía de llamadas, en el extremo de la matriz/la salida) es lo que ya está en la pila, el extremo superior se tomará de la pila actual. Entre ellos colocaremos un marcador de llamada remota .
private void mergeStackTraces(Throwable error)
{
StackTraceElement[] currentStack =
new Throwable().getStackTrace();
int currentStackLimit = 5; // TODO: raussuchen
StackTraceElement[] oldStack =
error.getStackTrace();
StackTraceElement[] zusammen =
new StackTraceElement[currentStack.length - currentStackLimit +
oldStack.length + 1];
System.arraycopy(oldStack, 0, zusammen, 0, oldStack.length);
zusammen[oldStack.length] =
new StackTraceElement("══════════════════════════",
"<remote call %" +callID+ ">",
"", -3);
System.arraycopy(currentStack, currentStackLimit,
zusammen, oldStack.length+1,
currentStack.length - currentStackLimit);
error.setStackTrace(zusammen);
}
(En el lado del servidor, ya estoy cortando las partes de la traza de la pila que no se refieren al método de llamar a sí mismo, es decir, todo lo relacionado con el manejo de mensajes.)
esto da lugar a un seguimiento de pila combinado de esta manera:
java.lang.SecurityException: Das Passwort für Nutzer »Paul« ist falsch.
at de.fencing_game.db.userdb.Db4oUserDB.login(Db4oUserDB.java:304)
at de.fencing_game.server.impl.StandardServers$SSServer$1.run(StandardServers.java:316)
at de.fencing_game.server.impl.StandardServers$SSServer$1.run(StandardServers.java:314)
at java.security.AccessController.doPrivileged(Native Method)
at de.fencing_game.server.impl.StandardServers$SSServer.login(StandardServers.java:313)
at de.fencing_game.transport.server.ServerTransport$ConnectionInfo$4.login(ServerTransport.java:460)
at ══════════════════════════.<remote call %2>()
at $Proxy1.login(Unknown Source)
at de.fencing_game.gui.basics.LoginUtils.login(LoginUtils.java:80)
at de.fencing_game.gui.Lobby.connectTo(Lobby.java:302)
at de.fencing_game.gui.Lobby$20.run(Lobby.java:849)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:226)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:647)
at java.awt.EventQueue.access$000(EventQueue.java:96)
at java.awt.EventQueue$1.run(EventQueue.java:608)
at java.awt.EventQueue$1.run(EventQueue.java:606)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:617)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)
supongo que el sistema RMI hace algo bastante similar (pero sin la ══════════════════════════
).
Editar: Para su caso de uso, que tendría que guardar el seguimiento de la pila de la rosca exterior cuando se inicia la rosca interior, a continuación, en el método run detectar la excepción y anexar el seguimiento de pila externa a el rastro de la pila de la excepción interna. Sin embargo, realmente recomendaría poner algún tipo de separador.
me gustaría la excepción interna para tener la StackTrace del exterior anexa, incluso si es capturado por algo profundo en la rosca interior. Supongo que eso no es posible, ya que no puedo aplicar una excepción personalizada. –
Su código de captura tiene que hacer esto (o la excepción debe hacerlo antes de lanzar, anular fillInStackTrace o hacer esto en el constructor). Nada de esto funcionará para excepciones desconocidas lanzadas y atrapadas por código desconocido. –
Me gusta que tenga 3 idiomas en un fragmento de código: inglés, alemán y Java :) – bacar