Alex Rivera | Logout

Why is Throwable.fillInStackTrace() method public? Why would someone use it?

Asked 2012-03-20T14:45:44.003
37

I'm curious why is method fillInStackTrace of java.lang.Throwable public?

This method replaces original stack trace with that from the place it is called, removing the information needed to localize exception. It could be used for obfuscating, but without much effort, since new stack trace would direct to the obfuscation code. Better way would be to simply hide the exception or throw the new one.

But I can't find out any reasonable case for calling this method on existing Throwable. So the question is: why this method is public? Is there any sense behind?

Edit
Report

2 Answers

21

One possibly legitimate use is creating an exception in a different place from where you are actually throwing. For instance, maybe you have an application where you provide a plugin facility for generating custom exceptions. Since the stacktrace is filled in on construction, the trace of the exception will include possibly misleading information (it will include calls into the custom exception factory). thus, your application would call fillInStackTrace() on the exception after generation by the custom factory to give a more accurate stack trace to the eventual receiver of the exception.

This rejected bug indicates that you are not the only one confused by the need for this method.

answered 2012-03-20T14:58:12.223
6

One legitimate use case for Throwable.fillInStackTrace() is for non-local control flow:

For example, within my TrueZIP framework, I use a complex chain of decorators for file system controllers. One of the controllers in this chain is an instance of the class FsLockController. This object is responsible for managing a ReentrantReadWriteLock for the file system. Now a file system controller somewhere deeper in this chain might detect that a write-lock is required, but only a read-lock has been acquired by the FsLockController. Because you can't upgrade a read-lock to a write-lock without dead-locking, an exception must get thrown, which happens to be an instance of the class FsNeedsWriteLockException. The decorating FsLockController will then catch this exception, release the read-lock and acquire the write-lock before retrying the operation again.

This kind of non-local control flow works actually very well, but there is one thing to consider: Throwing and catching an exception is cheap, but filling in or examining its stack trace is expensive. Now because this particular exception type is solely thrown and catched within this file system controller chain, I do not need a stack trace at all and so I can safely override Throwable.fillInStackTrace() with an empty method body in order to suppress this expensive operation.

Source code for the base class of this exception type can be seen here.

answered 2012-03-29T21:39:46.930

Your Answer