How to load JAR files dynamically at Runtime?

前端 未结 20 3196
伪装坚强ぢ
伪装坚强ぢ 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 05:55

    In case anyone searches for this in the future, this way works for me with OpenJDK 13.0.2.

    I have many classes that I need to instantiate dynamically at runtime, each potentially with a different classpath.

    In this code, I already have an object called pack, that holds some metadata about the class I am trying to load. The getObjectFile() method returns the location of the class file for the class. The getObjectRootPath() method returns the path to the bin/ directory containing the class files that include the class I am trying to instantiate. The getLibPath() method returns the path to a directory containing the jar files constituting the classpath for the module the class is a part of.

    File object = new File(pack.getObjectFile()).getAbsoluteFile();
    Object packObject;
    try {
        URLClassLoader classloader;
    
        List classpath = new ArrayList<>();
        classpath.add(new File(pack.getObjectRootPath()).toURI().toURL());
        for (File jar : FileUtils.listFiles(new File(pack.getLibPath()), new String[] {"jar"}, true)) {
            classpath.add(jar.toURI().toURL());
        }
        classloader = new URLClassLoader(classpath.toArray(new URL[] {}));
    
        Class clazz = classloader.loadClass(object.getName());
        packObject = clazz.getDeclaredConstructor().newInstance();
    
    } catch (Exception e) {
        e.printStackTrace();
        throw e;
    }
    return packObject;
    

    I was using the Maven dependency: org.xeustechnologies:jcl-core:2.8 to do this before, but after moving past JDK 1.8, it sometimes froze and never returned being stuck "waiting for references" at Reference::waitForReferencePendingList().

    I am also keeping a map of class loaders so that they can be reused if the class I am trying to instantiate is in the same module as a class that I have already instantiated, which I would recommend.

提交回复
热议问题