Debugging Java exceptions is not always easy to do as the exception messages are often too generic. IBM SDK has provided a mechanism for triggering additional data generated on various events using the -Xdump option. It allows an additional level of filtering on the method that is throwing the exception. Javacore and System dump are useful to capture detailed information about the general state of the Java runtime and the application running on it. We can generate those dumps on purpose when certain exception raises from specified method. This is useful for larger and complex applications throwing, for example, NullPointerException frequently from various places. Now we can filter on the exception message by using a hash (#) separator in the filtering argument followed by the method throwing the exception.
Here is a sample stack when a thread throws NullPointerException:
In order to capture Javacore and System dump at the top method (my/test/ExcepTest3$ExceptionCache.<init>) when the Java exception is thrown, we can use a customized -Xdump option to update default dump settings by setting the method name with a hash (#) separator as below:
JVM will create Javacore (javacore.*.txt) and System dump (core.*.dmp) at the next exception occurrence. The 'events=throw' is an event trigger when an exception is thrown during JVM operation. The 'filter=java/lang/NullPointerException' setting is a part to set the exception name which interesting to debug. Next to the exception name, we can set the class and method name specifically as [#ThrowingClassName.throwingMethodName] for advanced filtering. The 'range=1..2' option can use to limit dumps twice to avoid excessive dumps being produced. Adding '#stackFrameOffset' parameter is beneficial in case that the top method of the exception stack is in general. IBM SDK allows to specify a number of stack frame offset within the filter option.
Here is another sample exception stack which is throwing a ClassNotFoundException:
(#0) at java.net.URLClassLoader.findClass(URLClassLoader.java:434)
(#1) at java.lang.ClassLoader.loadClass(ClassLoader.java:646)
(#2) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:358)
(#3) at java.lang.ClassLoader.loadClass(ClassLoader.java:612)
(#4) at my.test.TriggerClass.<init>(TriggerClass.java:10)
ClassNotFoundException may happen hundreds of times during the lifetime of an application to look for a Class on WebSphere Application Server. It may be thrown at java.net.URLClassLoader.findClass() method at various place. In order to troubleshoot a ClassNotFoundException which is coming from a specific method like ‘com.test.TriggerClass.<init>’, we need to filter the others to avoid excessive dump creations to save disk space. In such a case we can use the '#stackFrameOffset' parameter after counting on the exception stack frame from the top (#0) to the target method (#4):
Those advanced -Xdump filter option to add class name, method name and stack frame offset would help to obtain JVM dumps at the best timing to debug Java exceptions. Please note that package prefix in filter option should be slash [ / ]. Incorrect setting like using dot [ . ] prefix would be ignored by the JVM (filter=java/lang/NullPointerException#my.ibm.ExcepTest3$ExceptionCache.<init> doesn't work). After getting JVM successfully, IBM Thread and Monitor Dump Analyzer is useful for Javacore analysis and IBM Monitoring and Diagnostic Tools for Java - Memory Analyzer or IBM Monitoring and Diagnostic Tools - Interactive Diagnostics Data Explorer (IDDE) are good for System dump analysis.