tags:

views:

191

answers:

3

What is the easiest way to obtain a list of all classes used while running a Java application?

Assume that com.package.Foo.main is invoked by running:

java com.package.Foo

After running the program I'd like to have a list of all classes that have been used while running the program:

cat classes-used.txt
com.package.Foo
com.package.FooHelper
com.otherpackage.SomeClass
java.lang.String
java.util.List
java.util.ArrayList

In this context a class is defined as being used if it the class has been loaded by the class loader during program execution and the class' static block would have been run if such static block had existed.

+7  A: 

Run java with the flag verbose:class

java -verbose:class com.package.Foo

To append it to a file:

java -verbose:class com.package.Foo > classes-used.txt

etc.

It also list the jar where those files are defined:

For instance for this class

public class Test {
     public static void main( String [] args ) {
     }
}

I've got ( among others )

$ java -verbose:class Test 
[Opened /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/classes.jar]
[Opened /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/ui.jar]
[Opened /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/laf.jar]
[Opened /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/jsse.jar]
[Opened /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/jce.jar]
[Opened /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
OscarRyz
Thanks for a quick and precise answer! Just what I was looking for.
knorv
A: 

You could do something along these lines:

1) Enable verbose class loading by passing -verbose:class on your java command line

This will print a line like

[Loaded org.foo.Bar from file:XYZ.jar]

for each class loaded.

2) Post-process the output with the *nix text utilities (grep, sed, etc.) to find all instances of these messages and extract and sort the class names

dstine
+1  A: 

I believe you could also use Jakarta Commons Discovery, with code similar to the following:

ResourceNameIterator classes = new DiscoverClasses().findResourceClasses(Object.class);
while (classes.hasNext()) {
    String className = classes.nextResourceClass().getName();
    Class clazz = classes.nextResourceClass().loadClass();
}
Stephen