JTombstone Limitations


In practice this is this the most common problem using JTombstone. You can deal with it by identifing which methods are called by reflections, and including them in the root methods.

Reflections are used extensively by Java and its extensions. One of the most common patterns is to have the type of a particular object be specified by a user in a configuration file. The object must implement a specific interface. Its constructor is called by code after reading the configuration file. This supports pluggable behavior very nicely.

One can handle this in JTombstone, and then list the constructors that are called by reflections as root methods. If you don't want to analyze the calling code, you can additionally specify all the interface methods as root methods.

Another common pattern is the bean pattern. In this pattern getFoo gets the foo property, and setFoo sets the foo property. You may find yourselve entering root method descriptions such as "get*", "is*", and "set*" to match all these methods.


JNI (Java Native Interface) allows a method to call native code, which can then call back Java code. JTombstone has no way of know that this is going on. Its not that this feature is used so often, but it is used in key parts of the JDK. For instance, once Thread.start is called, Thread.run is likely to be called at some later time. Typically such a situation would be handle similarly to reflections - after investigation, Thread.run should be added to the list of root methods.

JTombstone assumes that if any code in a method is alive, all of it is.

This assumption is not true, but it would be hard to do better. Problems occur with code such as:

boolean ImFalse = false;

if (ImFalse) {
neverRun(); // never get to here

JTombstone will assume that neverRun() gets called, and so is live code.

Some java compilers may use optimizations to decouple files. This in turn may make it impossible to detect dependencies between classes. For instance,
if Class B references the following variable in Class A

public static final boolean FALSE = false;

the class file for Class B will typically NOT have a reference to Class A - instead the constant "false" will be found. In addition, some compilers
will remove code such as this:

if (FALSE) {
neverRun(); // never get to here

which may or may not be what you want.

SourceForge.net Logo RSS Feed Available JTombstone Home