When you use RMI in Java the remote stack trace of an exception will be prepended when you receive it, somewhat like this:
ERROR Client received error when doing stuff:
myapp.FooBarException: bla
at server.myMethod()
at rmi.callHandler() // and now, on the next line comes the client
at rmi.sendCall();
at client.doServerMethod()
at Thread.run()
How is that kind of stacktrace “forgery” done?
What do I want it for (apart from just being iterested)? Well, it would help me if I could do this:
outer() {
thread = new Thread(...
inner();
// inner() throws
// RuntimeException
// at inner();
// at Runnable.run();
// at Thread.run();
// at outer();
// at lalalala();
// ...
).start();
thread.join();
}
And make it so that an exception thrown in inner() would have outer() (and methods lower down the chain) in the stacktrace as well, for logging purposes.
It is kind of easy:
Throwable has methods
getStackTrace()andsetStackTrace().From one of my projects (non open-source, but maybe I’ll some day open the remote call engine):
Translated for your convenience:
(On the server side, I’m already cutting off the parts of the stack trace which do not relate to the method call itself, i.e. everything related to the message handling.)
This results in a combined stack trace like this:
I suppose the RMI system does something quite similar (just without the
══════════════════════════).Edit:
For your usecase, you would have to save the stack trace of the outer thread when the inner thread is started, then in the run method catch the exception and append the outer stack trace to the stack trace of the inner exception. I would really recommend putting some type of separator, though.