Another working solution using Instrumentation that works for me. It has the advantage of modifying the class loader search, avoiding problems on class visibility for dependent classes:
Create an Agent Class
For this example, it has to be on the same jar invoked by the command line:
package agent; import java.io.IOException; import java.lang.instrument.Instrumentation; import java.util.jar.JarFile; public class Agent { public static Instrumentation instrumentation; public static void premain(String args, Instrumentation instrumentation) { Agent.instrumentation = instrumentation; } public static void agentmain(String args, Instrumentation instrumentation) { Agent.instrumentation = instrumentation; } public static void appendJarFile(JarFile file) throws IOException { if (instrumentation != null) { instrumentation.appendToSystemClassLoaderSearch(file); } } }
Modify the MANIFEST.MF
Adding the reference to the agent:
Launcher-Agent-Class: agent.Agent Agent-Class: agent.Agent Premain-Class: agent.Agent
I actually use Netbeans, so this post helps on how to change the manifest.mf
Running
The Launcher-Agent-Class is only supported on JDK 9+ and is responsible for loading the agent without explicitly defining it on the command line:
java -jar <your jar>
The way that works on JDK 6+ is defining the -javaagent argument:
java -javaagent:<your jar> -jar <your jar>
Adding new Jar at Runtime
You can then add jar as necessary using the following command:
Agent.appendJarFile(new JarFile(<your file>));
I did not find any problems using this on documentation.