I recently had a situation where Log4j wasn’t outputting the stacktrace of the logged exceptions. While I’m not sure that the following is the actual explanation, it seems very plausible (since the program was running Java 5). Quote from the Java 5 release notes:
The compiler in the server VM now provides correct stack backtraces for all "cold" built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace. To disable completely the use of preallocated exceptions, use this new flag: -XX:-OmitStackTraceInFastThrow
(Credit goes to Stackoverflow.com for pointing me in the right direction). Small rant here: I do realize that all the guys and gals working on the Hotspot VM are exceptionally smart and there is some incredibly wicked cool technology in it (just one example: the code is instrumented using the performance counters from the CPU – so there is virtually no performance impact – and if it observed that too many jumps are taken, the code is re-JIT-ed using the opposite jump direction. If you are interested in the topic, just take a listen to episode #174 of the JavaPosse). Still, don’t mess with our exceptions! They are called such, because they are exceptional. If some programmer is using throwing exceptions as a control structure at every second statement, it is his or her problem! But for the rest of us, please don’t optimize away our stacktraces, since debugging complex multi-threaded applications is hard-enough even when you know where exactly the exception occurred!
Picture taken from Wonderlane's photostream with permission/