views:

423

answers:

7

Hi all,

I would like to get a list of all the classes belonging to a certain package as well as all of their children. The classes may or may not be already loaded in the JVM.

Walter

+8  A: 

It's not a programmatic solution but you can run

java -verbose:class ....

and the JVM will dump out what it's loading, and from where.

[Opened /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/sunrsasign.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/jsse.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/jce.jar]
[Opened /usr/java/j2sdk1.4.1/jre/lib/charsets.jar]
[Loaded java.lang.Object from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.io.Serializable from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.lang.Comparable from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.lang.CharSequence from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]
[Loaded java.lang.String from /usr/java/j2sdk1.4.1/jre/lib/rt.jar]

See here for more details.

Brian Agnew
+1 for teaching me something new!
Mike Daniels
The question is a bit unclear; it asked about showing children, but did not specify if the children should be shown with their associated parent. If the parent-child relationship is desired, then will this also supply that information?
Dave Jarvis
+1  A: 

You might be able to get a list of classes that are loaded through the classloader but this would not include classes you haven't loaded yet but are on your classpath.

To get ALL classes on your classpath you have to do something like your second solution. If you really want classes that are currently "Loaded" (in other words, classes you have already referenced, accessed or instantiated) then you should refine your question to indicate this.

Bill K
+3  A: 

An alternative approach to those described above would be to create an external agent using java.lang.instrument to find out what classes are loaded and run your program with the -javaagent switch:

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

public class SimpleTransformer implements ClassFileTransformer {

    public SimpleTransformer() {
        super();
    }

    public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) throws IllegalClassFormatException {
        System.out.println("Loading class: " + className);
        return bytes;
    }
}

This approach has the added benefit of providing you with information about which ClassLoader loaded a given class.

Amir Afghani
+3  A: 

I'd also suggest you write a -javagent agent, but use the getAllLoadedClasses method instead of transforming any classes.

To synchronize with your client code (Normal Java code), create a socket and communicate with the agent through it. Then you can trigger a "list all classes" method whenever you need.

daveb
+3  A: 

again not a programatic solution but you should be able to see that information with - https://visualvm.dev.java.net/

KingInk
A: 

Well, what I did was simply listing all the files in the classpath. It may not be a glorious solution, but it works reliably and gives me everything I want, and more.

Thanks,

Walter

A: 

An API that uses BCEL for class analysis:

http://whitemagicsoftware.com/software/java/hierarchy/

There is one example that shows how to create an output format compatible with dot from the Graphviz suite. You could easily adapt it to create an XML format or use the names directly in a program.

Dave Jarvis