Java - get a list of all classes loaded in the JVM

I would like to get a list of all classes belonging to a particular package, as well as to all my children. Classes may or may not already be loaded in the JVM.

+50
java reflection jvm
Mar 30 '10 at 20:16
source share
10 answers

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

-one
Mar 31 '10 at 16:00
source share

This is not a software solution, but you can run

java -verbose:class .... 

and the JVM will unload the download 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.

+90
Mar 30 '10 at 20:20
source share

Using the Reflections library, it's easy:

 Reflections reflections = new Reflections("my.pkg", new SubTypesScanner(false)); 

This scans all classes in url / s that contain the package my.pkg.

  • false - does not exclude the Object class, which is excluded by default.
  • in some scenarios (different containers) you can pass classLoader as well as a parameter.

So, getting all classes effectively gets all subtypes of Object, transitively:

 Set<String> allClasses = reflections.getStore().getSubTypesOf(Object.class.getName()); 

(The usual way of reflections.getSubTypesOf(Object.class) will load all classes in PermGen and will probably throw OutOfMemoryError, you won't want to do this ...)

If you want to get all the direct subtypes of an object (or any other type) without getting its transitive subtypes at a time, use this:

 Collection<String> directSubtypes = reflections.getStore().get(SubTypesScanner.class).get(Object.class.getName()); 
+24
Mar 09 '13 at 16:25
source share

There are several answers to this question, partly due to a controversial question - the heading speaks of classes loaded by the JVM, while the content of the question says β€œmay or may not be loaded by the JVM”.

Assuming the OP requires classes loaded by the JVM with the given class loader, and only these classes - my need - have a solution ( developed here ) that looks like this:

 import java.net.URL; import java.util.Enumeration; import java.util.Iterator; import java.util.Vector; public class CPTest { private static Iterator list(ClassLoader CL) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Class CL_class = CL.getClass(); while (CL_class != java.lang.ClassLoader.class) { CL_class = CL_class.getSuperclass(); } java.lang.reflect.Field ClassLoader_classes_field = CL_class .getDeclaredField("classes"); ClassLoader_classes_field.setAccessible(true); Vector classes = (Vector) ClassLoader_classes_field.get(CL); return classes.iterator(); } public static void main(String args[]) throws Exception { ClassLoader myCL = Thread.currentThread().getContextClassLoader(); while (myCL != null) { System.out.println("ClassLoader: " + myCL); for (Iterator iter = list(myCL); iter.hasNext();) { System.out.println("\t" + iter.next()); } myCL = myCL.getParent(); } } } 

One neat thing is that you can choose the arbitrary classloader you want to test. However, it is likely to be destroyed if the inner classes of the classload class change, so it should be used as a one-time diagnostic tool.

+12
Dec 01 '14 at 8:14
source share

An alternative approach to the ones described above could be to create an external agent using java.lang.instrument to find out which classes are loaded and run your program using 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 giving you information about which ClassLoader loaded the class.

+6
Mar 30 '10 at 20:30
source share

I also suggest you write the -javagent agent, but use getAllLoadedClasses instead of converting any classes.

To synchronize with your client code (regular Java code), create a socket and exchange an agent with it. Then you can run the list of all classes method when you need to.

+6
Mar 30 '10 at 20:33
source share

In one case, if you already know the top-level path of the package, use OpenPojo

 final List<PojoClass> pojoClasses = PojoClassFactory.getPojoClassesRecursively("my.package.path", null); 

Then you can view the list and execute any functionality that you want.

+3
Aug 28 2018-12-12T00:
source share

You may be able to get a list of classes loaded through the class loader, but this will not include classes that you have not loaded yet, but are in your class path.

In order to get ALL the classes in your class path, you have to do something like your second solution. If you really need classes that are currently "loaded" (in other words, classes that you have already referenced, accessed, or instantiated), you should clarify your question to indicate this.

+2
Mar 30 '10 at 20:21
source share

Run your code under the JRockit JVM, then use JRCMD <PID> print_class_summary

This will output all loaded classes, one on each line.

+2
Nov 11 '11 at 17:07
source share

This program will print all classes with its physical path. use can just copy this to any JSP if you need to analyze class loading from any application web server.

 import java.lang.reflect.Field; import java.util.Vector; public class TestMain { public static void main(String[] args) { Field f; try { f = ClassLoader.class.getDeclaredField("classes"); f.setAccessible(true); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Vector<Class> classes = (Vector<Class>) f.get(classLoader); for(Class cls : classes){ java.net.URL location = cls.getResource('/' + cls.getName().replace('.', '/') + ".class"); System.out.println("<p>"+location +"<p/>"); } } catch (Exception e) { e.printStackTrace(); } } } 
0
Oct 15 '17 at 6:54 on
source share



All Articles