I have a large Java desktop application and I want 3rd party developers to
be able to create plugins for it. And I am exploring whether Guice might
help with the API.
I expect 3rd party developers to create plugins as jars and deploy them
into a specified dir.
At runtime I plan to pick up plugin classes using annotations (much like
EJBs in an EE container). I am investigating whether Guice will be suitable
for injecting important components into the plugins.
A plugin annotation that decorates a plugin class:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Plugin {}
A plugin annotation that decorates a method to be called on startup:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PluginInit {}
A plugin class:
@Plugin
public class MyPlugin {
private final MyImportantClassUser myImportantClassUser;
public MyPlugin() {
myImportantClassUser = new MyImportantClassUser();
}
@PluginInit
public void init() {
System.out.println("MyPlugin Started");
myImportantClassUser.doSomething();
}
}
The important class user that needs an important class injected from the
"franework".
public class MyImportantClassUser {
@Inject
ImportantClass importantClass;
public MyImportantClassUser() {
}
public void doSomething() {
System.out.println("IM DOING SOMETHING WITH THE IMPORTANT CLASS: "
+ importantClass.getSomeMethod());
}
}
The important class:
public class MyImportantClassUser {
@Inject
ImportantClass importantClass;
public MyImportantClassUser() {
}
public void doSomething() {
System.out.println("IM DOING SOMETHING WITH THE IMPORTANT CLASS: "
+ importantClass.getSomeMethod());
}
}
The important class Guice module:
public class ImportantClassesModule extends AbstractModule {
private final ImportantClass importantClass;
public ImportantClassesModule() {
importantClass = new ImportantClass();
}
@Override
protected void configure() {
System.out.println("ImportantClassesModule configured");
}
@Provides
ImportantClass provideImportantClass() {
return importantClass;
}
}
Current (crude) test Harness:
public class PluginProcessor {
public void test() throws IOException, ClassNotFoundException,
IllegalAccessException, InstantiationException, InvocationTargetException {
final URL[] pluginJarUrls = getPluginURLs();
// Using Scannotation to index annotations
final AnnotationDB db = new AnnotationDB();
db.scanArchives(pluginJarUrls);
// ClassLoader for plugin jars
final URLClassLoader classLoader = new
URLClassLoader(pluginJarUrls);
// Create injector for important classes
Injector injector = Guice.createInjector(new
ImportantClassesModule());
// Find plugin classes and initialise them
final Map<String, Set<String>> annotationIndex =
db.getAnnotationIndex();
for (final String annotation : annotationIndex.keySet()) {
if (Plugin.class.getName().equals(annotation)) {
for (final String pluginClassName :
annotationIndex.get(annotation)) {
final Class<?> pluginClass =
Class.forName(pluginClassName, false, classLoader);
for (final Method method : pluginClass.getMethods()) {
if (method.isAnnotationPresent(PluginInit.class)) {
// Get plugin class via injector to use
injection
method.invoke(injector.getInstance(pluginClass));
break;
}
}
}
break;
}
}
}
private URL[] getPluginURLs() throws MalformedURLException {
// TODO - Just one jar for now
final File pluginBin = new File("some_plugin.jar");
return new URL[] { pluginBin.toURI().toURL() };
}
public static void main(String[] args) throws Exception {
new PluginProcessor().test();
}
}
I've just thrown this together to see if I can do what I envisage. But the
injection of ImportantClass is not occuring into the instance of
MyImportantClassUser.
Is that because I have not instantiated MyImportantClassUser via the
injector?
I don't want my users (3rd party developers) to have to instantiate every
class via the injector. So is there a way to globally inject things in this
manner? Am I misunderstanding or trying to abuse the purpose of Guice?
Thanks!
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/google-guice/-/TVPN0QQ8F7MJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-guice?hl=en.