Express (Distributed operating systems), v8.0 > Troubleshoot and support > Analyzing application server Java system dumps with the IBM Monitoring and Diagnostic Tools for Java - Dump Analyzer > Write Dump Analyzer modules for WAS diagnostics - Tutorial
Tutorial: Writing Dump Analyzer modules for WAS diagnostics
Work with J2SE Collections
In our WAS Thread Pool sample so far, we print the field
List of Threads: java/util/HashMap@0x00AA7B98That's not very useful. What we want to see in the report is not simply the address of the HashMap that contains the list of threads associated with this pool. We want to see the actual list of threads.
To accomplish this, we use the following code:
pool.printCollectionEntriesAtPath(out2, "List of Threads", "Thread", "threads_", HashMapWrapper.class.getName());which generates output like the following:
List of Threads: java/util/HashMap@0x036F18B8 (4 entries) Thread: com/ibm/ws/util/ThreadPool$Worker@0x012F3158 com/ibm/ws/util/ThreadPool$Worker@0x012F3158 Thread: com/ibm/ws/util/ThreadPool$Worker@0x011ACE18 com/ibm/ws/util/ThreadPool$Worker@0x011ACE18 Thread: com/ibm/ws/util/ThreadPool$Worker@0x012CE728 com/ibm/ws/util/ThreadPool$Worker@0x012CE728 Thread: com/ibm/ws/util/ThreadPool$Worker@0x011819F0 com/ibm/ws/util/ThreadPool$Worker@0x011819F0Instead of just showing an object reference to the HashMap that is the value of the field in the target object, we now show an object reference to that HashMap, followed by the current number of entries, followed by a sub-section that lists all the entries in that HashMap.
Each entry is printed on separate line, with a label (as specified with the third parameter to printCollectionEntriesAtPath(), followed by the key associated with that entry (printed as it would be printed as if it was any other value printed by printValueAtPath()), followed by the value associated with that entry (also printed as it would be printed by a direct call to printValueAtPath()).
This example output is slightly confusing, because in this particular implementation of the com/ibm/ws/util/ThreadPool data structure in WAS, the HashMap that lists all the threads in the pools stores a reference to the thread object (com/ibm/ws/util/ThreadPool$Worker) both in the key and in the value of each entry in the HashMap. It is not clear why a HashMap was needed in this case... maybe this could have been implemented with a HashSet or ArrayList...
A more typical example printing the contents of a HashMap can be found in other analyzers, for example a HashMap in the WAS Web Services component that lists the service objects associated with a given configuration:
allServices: java/util/HashMap@0x03FD02B0 (4 entries) Entry: "EchoService.EchoServicePort" org/apache/axis2/description/AxisService@0x040F6590 Entry: "EchoService12.EchoService12Port" org/apache/axis2/description/AxisService@0x040FCCA0 Entry: "PingService.PingServicePort" org/apache/axis2/description/AxisService@0x040D5F00 Entry: "PingService12.PingService12Port" org/apache/axis2/description/AxisService@0x04103530In this case, each entry has a key that is a String (automatically printed as such in the report) and a value that is a reference to some other object (printed as an object reference in the report, in the absence of additional code to further expand that object reference).
The Collection Analyzers
The key element that makes this printCollectionEntriesAtPath() method work lies in its last parameter: HashMapWrapper.class.getName(). This corresponds to the class name of an analyzer module called HashMapWrapper that is part of the library of standard analyzers shipped with the Dump Analyzer tool.
printCollectionEntriesAtPath allocates an instance of this HashMapWrapper analyzer, initializes it with a reference to the HashMap object from the original dump being analyzed, and asks it to figure out all the entries in that HashMap.
HashMapWrapper is in some ways similar to ObjectWrapper, in that it is an analyzer that represents or "wraps" one object instance from the dump being analyzed, and that provides a set of functions that other analyzers can invoke to obtain information from that object, such as printing the contents of its fields. But unlike ObjectWrapper which is generic and works with any object instance of any class but has no particular knowledge of any class, HashMapWrapper is specific and only works with instances of java.util.HashMap. HashMapWrapper encapsulates knowledge of the internal implementation of a java.util.HashMap, and it knows how to interpret the fields in that HashMap to extract the list of entries contained in that HashMap.
The Dump Analyzer tool ships with a library of such analyzers, each of which is specialized to interpret and extract the contents of a different class from the Java Collections framework: HashMapWrapper, HashTableWrapper, ArrayListWrapper, VectorWrapper, etc., as well as a few other commonly-found classes from the J2SE class library.
This library of J2SE analyzers is not yet complete, but so far it contains enough analyzers to handle most of the types of Collection classes routinely encountered while examining WAS data structures. New analyzers for other types can be easily added to the library as the need for them is discovered.
Different flavors of Collection traversal
The printCollectionEntriesAtPath() that we used above is one of several alternative methods provided by ObjectWrapper to work with fields that are references to a Collection or Map object. Other variants include
- printCollectionSizeAtPath(): prints the number of entries in the Collection or Map, but not the list of entries
- printCollectionValueReportsAtPath()
- printCollectionMapEntryReportsAtPath()~~
- ... etc. ...
We will encounters some of these other methods later in this tutorial, but first we need to describe Custom Wrappers
Next Topic
A Custom Wrapper Analyzer