Adverts
At first glance it looks like it should be fairly easy to find all classes that extend a given object or implement a given interface on the current classpath. After all, Java has fantastic tools for dynamically loading and inspecting classes and objects at runtime so something like this should be easy, right? Wrong. It's actually an impossible task because of the way classes are loaded.
The most obvious route to solve this problem appears to be to ask the class loader for a list of all objects and then inspect them one by one. The problem is the class loader can't furnish you with a list of the all classes because it itself doesn't know what classes exist. The reason it doesn't know is because it doesn't, in fact is can't, enumerate all classes at start or load.
The Java class loader system was designed from the ground up to load classes on demand from any source. Typically that source is a jar file which doesn't change during the life time of the application which leads developers to think that they could get a list of all classes. In fact the class loader could be given a URL and load a class via a stream from the Internet or it could be provided with a byte array by the currently running application. Since there is no way to know ahead of time which classes will be loaded there is no way to enumerate all classes and find the ones that implement a certain interface.
The long and the short of it is that until you ask for a class you don't know whether it will be loaded. If the class loader understands the resource path given to it, can access the path and finds valid byte code you will be presented with a class - otherwise an exception is thrown.
If you really need to know what classes may be available that implement a given interface the first thing to do is acquire a list of class names. This is best done by finding all jar files in the application and then using standard java.io facilities to open and inspect them. Once you have a list of class names filter them based on name (this isn't strictly necessary but you might find yourself loading a lot of classes otherwise) and then load the classes with a class loader. The type can be checked with a call like this Example.class.isAssignableFrom( exampleClass ) which checks the class is castable to the interface Example.
Of course this is far from perfect. It means potentially loading a huge number of classes many of which will be useless. This uses up unrecoverable space in the VM as classes, once loaded, are not discarded. A better solution is provide the application with a list of classes to load in a properties file or an XML file.