views:

1505

answers:

8

Possible Duplicate:
How do you find all subclasses of a given class in Java?

Hi,

I would like to get a list of classes that implement an interface in Java at runtime so I can do a lookup service without having to hard code it. Is there a simple way of doing this? I fear not.

Cheers,

Cuvavu

+6  A: 

The short answer is no.

The long answer is that subclasses can come into existence in many ways, which basically makes it impossible to categorically find them all.

You can't do it at runtime but you can't find classes until they're loaded and how do you know they're loaded? You could scan every JAR and class file but that's not definitive. Plus there are things like URL class loaders.

Inner classes (static and non-static) are another case to consider. Named inner classes are easier to find. Anonymous inner classes are potentially much more difficult to find.

You also have to consider that if a class has subclasses then new subclasses can be created at a later point.

cletus
A: 

If you only load classes from the disk or from URLs then you can scan the classpath and find subclasses "manually".

flybywire
A: 

I am trying to reason through the answer here so I am probably wrong. It would not make sense for a class to have information about its descendants or subclasses because at any point in time someone can create a new subclass of your class. Then you would have to recompile your class to include this new information every time. This does not make sense for extendable code. It is more likely for a class to contain information about its ancestors. So the only solution that I can see is for you to iterate over every class in your problem space and check but this is more than likely a horrible solution for you.

uriDium
+1  A: 

I can always create a new subclass for any non-final class, add the subclass to the classpath, and defeat your intent. Subclassing is an open-ended proposition.

About the best you can do is say that for a given classpath, you know what the subclasses are, and to do that, you'd have to scan each class in the classpath.

Tim H
A: 

It's fairly simple using reflection. Read this article from JavaWorld

http://www.javaworld.com/javaworld/javatips/jw-javatip113.html

Amir Afghani
I misread the question, the article above is only to find subclasses that implement a given interface
Amir Afghani
+1  A: 

The only way you'd be able to do it is walking the package hierarchy for the packages available in the classpath checking each class via reflection (and that's gonna suck because you'll effectively load every class, unless you restrict your search to certain packages).

The trouble with this sort of auto-magical behavior is that it becomes hard to quantify the application without running it, which is a maintenance headache. I'd always prefer to go the injection route (a-la Spring) passing instances via some sort of configuration.

Nick Holt
A: 

Do you want to enumerate classes that implement a particular interface or enumerate classes that derive from some base class? These are two different issues. Both as far as I know would be hard to implement since new implementations can be created/installed on a PC at any time in the future. It sounds like you are trying to create a factory method to instantiate a particular instance and you don't want to hard-code the class name in the code. Usually using a config file that enumerates all the classes that implement the interface is the way to go (or a database can be used). As new classes implement the interface, you add them to the config file and the factory should pick up the new class name.

A: 

you should use Java ServiceLoader that is a builtin class. It is capable of iterating at runtime over all know service (interface) implementations.

If for some reason you don't want it, you can use ClassLoader.getSystemResources() to iterate over all resources; e.g. if you have 6 times the file /META-INF/com.interface you'll get 6 iterations.

dfa