I have a Java
program (an Eclipse plug-in
to be specific), which is using several JAR
files (which I can control). One of the core JAR
files defines an abstract class
called Strategy. When the user starts the program, the program needs to know all sub classes of Strategy, that are on the program ClassPath
.
As I described in this StackOverflow question, I tried to use static initializer blocks on the sub classes, so that they auto-register themselves in a registry. This approach is not working since the static initalizers are not executed before I explicitly use the class.
Is there any other way to find all classes with a certain base type that are on the current ClassPath
?
I can think of the following solutions:
JAR
s in a specific directory and check the classes they containI can implement both of them myself (so I do not ask for any code samples here). I merely want to know if there is another option I am missing. Any in-class solution (like the one I tried with static initializers) would be greatly appreciated.
If you're open to using a third-party library, Reflections seems to be the best fit here. It's a Java runtime metadata analysis library and is like geared to do this. From their website:
Using Reflections you can query your metadata such as:
- get all subtypes of some type
- get all types/constructos/methods/fields annotated with some annotation, optionally with annotation parameters matching
- get all resources matching matching a regular expression
- get all methods with specific signature including parameters, parameter annotations and return type
All you need is to create a configured instance of Reflections
in your StrategyRegistrar
class as
Reflections reflections = new Reflections(
new ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage("com.your.app.strategies.pkg"))
.setScanners(new SubTypesScanner())
);
And, then simply fire a query like
Set<Class<? extends Strategy>> strategies =
reflections.getSubTypesOf(com.your.app.strategies.pkg.Strategy.class);