Unfortunately there's no easy way to do it. The JVM has no information about a particular class until it gets loaded by a classloader. But to have the classloader actually load the class, you must know the name of the class. Chicken and egg problem.
However, there is some other, but a bit more complicated way.
- To determine which
.jar
files are on the classpath when running your application, you can call the System.getProperty("java.class.path")
then split the classpath entries along the File.separatorChar
characters. Classpath entries may be numerous, consider filtering them somehow (limiting only to a specific directory, leaving out standard entries like rt.jar
, etc.)
- If you know which
.jar
file contains your classes of interest, you can open it with an instance of the class JarFile
. Then you can iterate over all entries (eg. .class
files) and from their internal path in the JAR file you are able to construct their fully qualified class name.
- With the classname in your hand, you can call
Class.forName()
to load the class, and the you can use reflection to get the superclasses of each class to find out whether it extends your particular class or not.
Note that this method is quite resource consuming, you make the JVM to actually load all the classes from a .jar
file (or multiple .jar
files), even if you won't use them later. This wastes a fair amount af memory (PermGen space).
There are some low-level libraries that manipulate Java bytecode and class files (see BCEL or ASM). Using them you will be able to determine the superclass for a class without actually (class)loading it, thus this way is more faster and uses less memory.
Your question resembles the way JavaEE application servers work when deploying a web application. To find out which classes to load and initialize as for example HTTP servlets they must examine all classes in the web archive looking for a specific Java annotation or superclass. However they are at least know which .war
file to scan. Apache Tomcat for example uses BCEL instead of Java classloading mechanism.
If you're designing some sort of dynamic classloading mechanism for your application, then consider other design options to narrow down the numbers of classes your loader must scan to find the proper class to load: Telling the exact name of the .jar
file instead of putting it on the classpath, using some meta information in the JAR (you can use the aforementioned JarFile
to read entries from the META-INF/manifest.mf
file) to specify which classes to look for, etc.