You might consider the following post as a starting point: https://stackoverflow.com/a/2575156/471129
Basically, dependency injection and inversion of control are used to externally specify configuration of and dynamically load code often from different .jar files, which seems like what you're trying to do.
Of course, you can always load code by class name with something like this:
public interface IPlugin {
// some methods that all the plugins will have in common
}
private static IPlugin loadIPluginByClassName(String plugInClassName, ClassLoader classLoader) {
// NOTE: throws NoClassDefFoundError or ClassNotFoundException if cannot load the class
// or throws ClassCastException if the loaded class does not implement the interface
Class<?> cls = classLoader.loadClass(plugInClassName);
IPlugin ans = (IPlugin) cls.newInstance()
return ans;
}
You'll need to call loadIPluginByClassName() with a package qualified class name and class loader, as in
IPlugin pi = loadIPluginByClassName("com.test.something.MyPlugin", SomeClassInYourProject.class.getClassLoader());
The plugin can be in its own .jar as long as that .jar is on the classpath.
If you don't want to load them from an external .jar, you can use the simpler
IPlugin pi = loadIPluginByClassName(MyPlugin.class.getName(), SomeClassInYourProject.class.getClassLoader());
this creates a direct reference to your plugin class (which can be helpful in that such can be found as a reference)