How to run JTombstone

Get JTombstone

If you have built JTombstone from source, skip to the next section. If not, download a JTombstone distribution file. It should have a name like jtombstone-1-2-3.zip. You will also need to have Java installed.

Prepare Input File

You will need to prepare an input file so that JTombstone knows what to analyze. The input file is in xml file, formatted according to this XML Schema file. JTombstone needs to know three things to find dead code:

  1. The classpath for your program (i.e. what files are being analyzed).
  2. The starting points (roots) for your program. For a simple program, this may be just be the main program.
  3. The packages to report on. This ensures your are not overwhelmed with information about classes you don't care about.

An example input file is given here. It is for JTombstone itself. The output will be discussed later on this page. Note that a number of root methods are specified besides the main program. JTombstone uses castor to read in XML files. Castor in turn uses reflections to call some of the methods in JTombstone. JTombstone can't detect which methods are being called via reflections, and to simplify the output, these methods are treated as roots. See the Limitations page for how to work around other JTombstone limitations. The specification of all methods of the Object class as root methods is a failed attempt to get methods like toString() (which are convenient in the debugger, but may not be called anywhere in the code) to show up as inherited. See the interpretation of results for a discussion of this.

Note that the method names are specified via a format that is similar, but not exactly the same as you may have seen in stack traces. Not also that you can end root method names, and packages to report on with the * wildcard - which will match anything beginning as specified. This is convenient for methods, since you can skip the somewhat hard to remember notation for method arguments, e.g. the main method for a class will match "main*".

There are some pitfalls when using wildcards with package names. For instance, the specification "java*" matches all subpackages of the java package, the javax package, and other packages beginning with java. The specification "java.*" is more likely to be what you want - it doesn't include javax or its subpackages.

Run JTombstone

JTombstone is run from the command line. Type in something like the following (this will work from the lib directory):

$ java -jar jtombstone.jar -inFile myInput.xml -outHtml myOutput.html

This will produce HTML output formatted by the default XSL template (lib/jtombstone.xml). You can get the usage as follows:

$ java -jar jtombstone.jar -help

USAGE: java -jar jtombstone.jar
[-inFile <filename>] [-stylesheet <filename>] [-outXml <filename>] [-outHtml
<filename>]

-inFile <filename> - get input from file <filename>. if not specified, comes from System.in.
-stylesheet <filename> - use XSL template <filename>. if not specified, comes from ./jtombstone.xsl
-outXml <filename> - send XML output to file <filename>.
-outHtml <filename> - send HTML output to file <filename>. if neither -outXml nor -outHtml specified, HTML goes to System.out.
-showLifeType <type> - highest type of life to show (filter). Types are: Rooted, Inherited (default), Constant, Dead. Only the first character is checked, and case is not considered.
-help - print this output.

Note that if you leave off input or output files that input and/or output goes to System.in and System.out respectively. Also note that the -showLifeType option doesn't affect the XML output (other than to pass the supported type to the XML output - it is a hint to the XSL processor on which output to filter out.

The example output was produced by running the command

$ java -jar jtombstone.jar -inFile ../documentation/examples/jtombstone-conf.xml -outXml ../documentation/examples/jtombstone-results.xml -outHtml ../documentation/examples/jtombstone-results.html

JTombstone can take a lot of memory, and a fair bit of time to run if there are a lot of classes. for instance, if you add rt.jar to your classpath (the base Java jar file), your JTombstone will required more than the default amount of memory. In this case if you don't specify something like the -Xmx256m to increase the maximum java memory, you will get an Out of Memory Error. Adding rt.jar also adds at least one minute of run time on my 2.8Ghz Pentium machine. Since JTombstone loads all classes in the classpath, it may be expected to take more memory than the program itself.

In the lib directory you will find a log4j.xml file which may be modified to change the amount of debug output. Output goes to log4j.log in the directory where you run the program and to standard output. You may find it interesting to change the logging level on the FileAppender from WARN to INFO or DEBUG. Watch out, DEBUG produces a lot of output. The ConsoleAppender should always have a debug level of ERROR or lower - otherwise you won't get messages on serious error conditions.

Interpreting the Output

The standard HTML output is the easiest to interpret. It will be discussed here. The format of the XML output is given in this XML Schema file.

The example output has a large number of warnings because some of the jar files in the classpath are not specified in the input file - particularly rt.jar. I did it this way not just to illustrate the warnings, but to show that you can have a quick partial run of JTombstone that produces useful results. Unlick the box next to Show Warnings to hide these.

The summary output tells us that out of 4 packages, 22 classes, and 200 methods, there 2 package and 6 classes containing 11 methods that may be dead.

JTombstone detects four levels of life:

  1. Rooted - This method is either a root method, or there is a direct call sequence from a root method to it. These methods are invariable alive, and do not show up in reports.
  2. Inherited - There is a call sequence from a root method to such a method, but it goes through a method call where there were subclassing of the methods involved, and so the particular code may or may not have been called. It is known that where subclassing was involved that at least one of the constructors for the class was called. Generally such methods are alive.
  3. Constant - This level only applies to classes. A class typically has the life of its most alive method, but if all are dead, and JTombstone cannot find any references to its data members in other classes,, then it may be put in this category. This category occurs when a class has defined a non-private static final data member which is initialized by a constant, e.g. private static final int num = 2; References to such members are replaced by the constant value by the Java compiler, so even though such a class is still used, there is no evidence of it in the class files. Such classes may be dead. Sometimes, however, a class or interface may be used only as a holding point for constants. Such a class or interface would be alive.
  4. Dead - JTombstone can detect no evidence that this class or method is alive.

Occasionally you will see the level None, which simply means that there are no relevant methods (for instance, the least alive column will show None for an Interface).

This output shows a number of methods that I haven't brought myself to remove, because they could come in handy later. For example, right now there is no need for the JavaClass.ClassComparator class, but there might be in the future. Note that this class marked as Rooted. This is a bug - inner classes are marked as Rooted, even if they are not (somewhat difficult to fix). This class should be marked Dead.

There are a number of methods that actually are used that show up as Dead, such as those on the Method class. I added a line to the input file making all methods on Object root methods. Had I also run with rt.jar in the classpath, then Method.equals and Method.hashcode would have shown up as Inherited. If I had additionally marked Comparable.compareTo as a root method, then Method.compareTo would have shown up as inherited. These methods get used by container classes from the java.util package. The method Method.toString actually doesn't get called when the program is running, but I do use it in the debugger to help see what is going on.

Note that even in classes with no constructor defined in the source, there is a default constructor defined in the class file. JTombstone can't tell whether this constructor actually exists in the source code. It will treat it like any other method, and if it is not called, mark it as Dead, even though there is not corresponding source code!


SourceForge.net Logo RSS Feed Available JTombstone Home