How to load JAR files dynamically at Runtime?

前端 未结 20 3189
伪装坚强ぢ
伪装坚强ぢ 2020-11-21 05:15

Why is it so hard to do this in Java? If you want to have any kind of module system you need to be able to load JAR files dynamically. I\'m told there\'s a way of doing it b

相关标签:
20条回答
  • 2020-11-21 06:13

    The solution proposed by jodonnell is good but should be a little bit enhanced. I used this post to develop my application with success.

    Assign the current thread

    Firstly we have to add

    Thread.currentThread().setContextClassLoader(classLoader);
    

    or you will not able to load resource (such as spring/context.xml) stored into the jar.

    Do not include

    your jars into the parent class loader or you will not able to understand who is loading what.

    see also Problem reloading a jar using URLClassLoader

    However, OSGi framework remain the best way.

    0 讨论(0)
  • 2020-11-21 06:14

    With Java 9, the answers with URLClassLoader now give an error like:

    java.lang.ClassCastException: java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to java.base/java.net.URLClassLoader
    

    This is because the class loaders used have changed. Instead, to add to the system class loader, you can use the Instrumentation API through an agent.

    Create an agent class:

    package ClassPathAgent;
    
    import java.io.IOException;
    import java.lang.instrument.Instrumentation;
    import java.util.jar.JarFile;
    
    public class ClassPathAgent {
        public static void agentmain(String args, Instrumentation instrumentation) throws IOException {
            instrumentation.appendToSystemClassLoaderSearch(new JarFile(args));
        }
    }
    

    Add META-INF/MANIFEST.MF and put it in a JAR file with the agent class:

    Manifest-Version: 1.0
    Agent-Class: ClassPathAgent.ClassPathAgent
    

    Run the agent:

    This uses the byte-buddy-agent library to add the agent to the running JVM:

    import java.io.File;
    
    import net.bytebuddy.agent.ByteBuddyAgent;
    
    public class ClassPathUtil {
        private static File AGENT_JAR = new File("/path/to/agent.jar");
    
        public static void addJarToClassPath(File jarFile) {
            ByteBuddyAgent.attach(AGENT_JAR, String.valueOf(ProcessHandle.current().pid()), jarFile.getPath());
        }
    }
    
    0 讨论(0)
提交回复
热议问题