This is a very simple implementation of a plugin system for Java - it only has one class!
The 'trick' is to leverage the little-used Java artifact package-info.class. This gives us a consistent pattern to search for while scanning the classpath (both directories and jar files).
Once a package-info.class file is found, the java.lang.Package for it can be loaded which in turn forces the resolution of any imports and annotations in the package-info class. In the following example, three different 'helper' classes are declared to be plugins:
@Plugin({Helper1.class, Helper2.class, Helper3.class})
packagesimple.test;
importorg.simple.pluginspi.PluginManager.Plugin;
importsimple.test.Helper1;
importsimple.test.Helper2;
importsimple.test.Helper3;Each helper class implements a common Helper interface:
publicinterfaceHelper {
publicvoidhelp();
}
importjavax.annotation.PostConstruct;
publicclassHelper1implementsHelper {
publicHelper1() {
//public default constructor required
}
@PostConstructprotectedvoidsetUp() {
System.out.println("Helper1 setUp");
}
publicvoidhelp() {
System.out.println("with a little help from my plugin friends");
}
}
importjavax.annotation.Resource;
publicclassHelper2implementsHelper {
@Resource(description="some random unique resource name", type = Integer.class)
intsomeValue;
publicHelper2() {
//public default constructor required
}
publicvoidhelp() {
System.out.printf("(some value=%d)some more help\n", someValue);
}
}
publicclassHelper3implementsHelper {
publicHelper3() {
//public default constructor required
}
publicvoidhelp() {
System.out.println("that's the last bit of help yer gonna get outa me!");
}
}Now it is possible to ask the PluginManager to find all Helper's without having to know exactly where they are on the classpath - or even what package they are in:
//javase importsimportjava.util.List;
//simple plugin importsimportorg.simple.pluginspi.PluginManager;
//domain importsimportsimple.test.Helper;
publicclassMain {
publicstaticvoidmain(String ...args) {
PluginManagerpluginManager = PluginManager.getPluginManager();
pluginManager.addResource("some random unique resource name", Integer.class, 3);
List<Helper> helpers = pluginManager.findPlugins(Helper.class);
for (Helperh : helpers) {
h.help();
}
}
}Helper1 setUp
with a little help from my plugin friends
(some value=3)some more help
that's the last bit of help yer gonna get outa me!