這是種簡單:
的Throwable有方法getStackTrace()
和setStackTrace()
。
從one of my projects(非開源,但也許我有一天打開遠程調用引擎):
/**
* 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".
*/
翻譯爲您提供方便:
融合了堆棧跟蹤。低端(呼叫層次結構中的較深處,在陣列的末尾 處)是堆棧中已經存在的內容,高端 將取自當前堆棧。在他們之間,我們將把一個 遠程呼叫標記。
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);
}
(在服務器端,我已經切斷的堆棧跟蹤不涉及到方法的調用零件本身,即一切相關的消息處理。)
這導致這樣的組合堆棧跟蹤:
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)
我想RMI系統確實非常相似(只是沒有══════════════════════════
)的東西。
編輯: 爲了您的用例,你必須保存在內部線程啓動外線程的堆棧跟蹤信息,然後在run方法捕獲異常和外堆棧跟蹤追加到內部異常的堆棧跟蹤。不過,我真的會推薦使用某種類型的分隔符。
我想內部異常有外附加的堆棧跟蹤,即使它被什麼東西深藏於內螺紋抓獲。我想這是不可能的,因爲我不能應用自定義異常。 – 2011-06-10 11:06:39
您的捕獲代碼必須執行此操作(或者在拋出之前必須執行此操作,覆蓋fillInStackTrace或在構造函數中執行此操作)。這些都不適用於未知代碼拋出和捕獲的未知異常。 – 2011-06-10 12:40:25
我喜歡你在一個代碼片段中有3種語言 - 英文,德文和Java :) – bacar 2012-08-17 18:29:20