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@0x00AA7B98

That'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@0x011819F0

Instead 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@0x04103530

In 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

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