Evil JVM feature optimizes away error information

The other day I ran across a tricky bug in the Flying Saucer PDF generation library.  It’s been pretty useful so far, but it does not seem to be under active development, so it has the occasional stale bug. In this case, our designer tried to use “display: table”, which crashes Flying Saucer R8.  Workaround is to use a different “display” property, like “display: block”.

The really annoying part was researching the bug.  The JVM includes an “optimization” that causes it to lose stack trace information for repeated exceptions in some cases.  So the server log showed “Caused by ClassCastException” but without any trace.  You can disable this “optimization” with the JVM argument XX:-OmitStackTraceInFastThrow .  I keep using apologetic quotes because I think there is something terribly wrong with optimizing exception control flow at the expense of debugging information.  If your application is throwing exceptions all over the place, you probably want to do something about that, and having the stack trace can make a world of difference.  In the case above, it cost me hours of debugging time (since I had never heard of this “feature” previously, I assumed it was a problem in our codebase), when once I had the stack trace it only took a few minutes to figure out.

Personally I would rather never see this “optimization” used, but at the very least I think it should not be enabled by default.