Ok, I read a lot about it.. I have a long answer and a short one.
The long one - I will write a blog post about it and link it here..
Here is the short one
Assumptions
- dep_1.jar - is a dependency I have, and is not dependent on any other jar. (a single jar packaging)
- The
API
is available in my classpath. I only want to separate the implementation's classpath.
- The class I want to instantiate has an empty constructor
Lets talk about a specific use case
// jar dep_1-api.jar
package guymograbi;
public interface IMyMessage {
public String getMessage();
}
// jar dep_1.jar
package guymograbi;
public class MyMessage implements IMyMessage{
public String getMessage(){ return "my message"; }
}
Code
ClassLoader classloader = new URLClassLoader(new URL[]{ new File("java_modules/dep_1.jar").toURI().toURL() })
return (IMyMessage.class) classloader.loadClass("guymograbi.MyMessage").newInstance();
This will return an IMyMessage
implementation without changing my classpath.
I can then load another implementation of the same interface from another jar, etc.. etc..
This solution is:
- small enough to embed in any library that wants to support it.
- small enough to quickly wrap any existing library with it.
- almost zero learning curve.. just a need to apply to an easy standard.
Further reading
So it seems there are many ways in which you can write this solution.
You can use Spring, Guice and ServiceLoader to do the actual implementation.
ServiceLoader - I kinda liked this solution has it has something similar to main
entry in package.json
. AND - obviously - it does not require a dependency that will mess with my classpath!
I also recommend checking io.github.lukehutch:fast-classpath-scanner
that allows you to easily find all classes that implement a specific interface.
Next Step
The next step for me is to construct a proper java_modules
folder and allow dep_1 to be a folder containing index.jar
and its own java_modules
folder and cascade the solution downwards..
I plan to do so using the answer from: How to get access to Maven's dependency hierarchy within a plugin
And then write a maven plugin (like assembly) to pack it all up properly.