Java 9 - add jar dynamically at runtime

被刻印的时光 ゝ 提交于 2019-12-07 04:56:20

问题


I've got a classloader problem with Java 9.

This code worked with previous Java versions:

 private static void addNewURL(URL u) throws IOException {
    final Class[] newParameters = new Class[]{URL.class};
    URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    Class newClass = URLClassLoader.class;
    try {
      Method method = newClass.getDeclaredMethod("addNewURL", newParameters );
      method.setAccessible(true);
      method.invoke(urlClassLoader, new Object[]{u});
    } catch (Throwable t) {
      throw new IOException("Error, could not add URL to system classloader");
    }
  }

From this thread I learned that this has to be replaced by something like this:

Class.forName(classpath, true, loader);

loader = URLClassLoader.newInstance(
            new URL[]{u},
            MyClass.class.getClassLoader()

MyClass is the class I'm trying to implement the Class.forName() method in.

u = file:/C:/Users/SomeUser/Projects/MyTool/plugins/myNodes/myOwn-nodes-1.6.jar

String classpath = URLClassLoader.getSystemResource("plugins/myNodes/myOwn-nodes-1.6.jar").toString();

For some reason - I really can't figure out, why - I get a ClassNotFoundException when running Class.forName(classpath, true, loader);

Does someone know what I'm doing wrong?


回答1:


From the documentation of the Class.forName(String name, boolean initialize, ClassLoader loader) :-

throws ClassNotFoundException - if the class cannot be located by the specified class loader

Also, note the arguments used for the API includes the name of the class using which the classloader returns the object of the class.

Given the fully qualified name for a class or interface (in the same format returned by getName) this method attempts to locate, load, and link the class or interface.

In your sample code, this can be redressed to something like :

// Constructing a URL form the path to JAR
URL u = new URL("file:/C:/Users/SomeUser/Projects/MyTool/plugins/myNodes/myOwn-nodes-1.6.jar");

// Creating an instance of URLClassloader using the above URL and parent classloader 
ClassLoader loader = URLClassLoader.newInstance(new URL[]{u}, MyClass.class.getClassLoader());

// Returns the class object
Class<?> yourMainClass = Class.forName("MainClassOfJar", true, loader);

where MainClassOfJar in the above code shall be replaced by the main class of the JAR myOwn-nodes-1.6.jar.



来源:https://stackoverflow.com/questions/48322201/java-9-add-jar-dynamically-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!