I want to make an application that can dynamically load plug-ins but I've not found any literature on Internet.
The difficult thing is: I don't know the name in advance.
For example I've a Plugin interface:
public interface Plugin {
public static Plugin newPlugin();
public void executePlugin(String args[]);
}
So that every Class implementing Plugin in the jar file are instantiated in a list:
Method method = classToLoad.getMethod ("newPlugin");
mylist.add(method.invoke(null);
Thanks for your help.
So it seems like you want to dynamically discover Classes that implement a specific interface (e.g., Plugin
) at runtime. You have basically two choices for this:
ServiceLoader
)Since there are many good tutorials on osgi (also small ones), I will not detail that here. To use Java's internal discovery process, you need to do the following:
META-INF/services/package.Plugin
You must use the full package qualifier herePlugin
in that jar-fileService discovery is done like this:
ServiceLoader<Plugin> loader = ServiceLoader.load(Plugin.class)
for (Plugin p : loader) {
// do something with the plugin
}
There are more details here: http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html
As for static methods in interfaces: not possible. The semantics of that would also be somewhat weird as static methods are accessible without an instance of a class, and interfaces just define the methods, without any functionality. Thus, static would allow to call Interface.doSomething()
whereas the interface does not define any functionality, this leads just to confusion.
edit:
added description what should be in the meta-file
Regarding your first problem, not being able to have static methods in the interface, my suggestion is to simply use the interface has a marker and instantiate it.
You're plugin interface can simply be:
public interface Plugin {
public void executePlugin(String args[]);
}
And then you can do:
if (someClass instanceOf Plugin) {
mylist.add(someClass.newInstance());
}
This leads to the second question, how will you get the someClass
reference.
There is no standard way to find all classes implementing a given interface in your classpath, although, an approach you can do is scan the jars in your classpath, if a given file ends with .class
determine it's full qualified name through it's path inside the jar and use Class.forName()
method to materialize the Class.
In pseudo code something like this:
for each jar in your classpath {
for each file in JarFile {
if (file ends with .class) {
materialize class using Class.forName
}
}
}
With the Class
instance you can check if it's implementing your Plugin
interface.
Also keep in mind that if you need to add any context to your plugins you can create a constructor in every plugin that receives your context object, instead of having the default constructor. In such case instead of using newInstance()
you would have to get the constructor with arguments you wanted via reflection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With