Add jar to classpath at runtime under java 9

Prior to to add an external jar for the classpath at runtime programmatically:

URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
method.invoke(sysloader, new Object[]{file.toURI().toURL()});

Now with java9 there is a problem:

Exception in thread "main" java.lang.ClassCastException: java.base / jdk.internal.loader.ClassLoaders $ AppClassLoader cannot be added to java.base / java.net.URLClassLoader

URLClassLoader no longer works in Java 9. What now does jdk9 do to add an external ban to the classpath at runtime programmatically?

+11
source share
2 answers

JavaSE9 :

java.net.URLClassLoader ( , ).

, , ClassLoader::getSytemClassLoader URLClassLoader, .

, Java SE JDK API .

, ,

Class<?> clazz = Class.forName("nameofclass", true, new URLClassLoader(urlarrayofextrajarsordirs));

Oracle. :

  • java.util.ServiceLoader ClassLoader Thread.currentThread(). setContextClassLoader (specialloader);

  • java.sql.DriverManager ClassLoader, ClassLoader. , Class.forName("drivername", true, new URLClassLoader(urlarrayofextrajarsordirs).newInstance();

  • javax.activation ClassLoader ( javax.mail).

+7

, . jar Java 9 - appendToSystemClassLoaderSearch(JarFile jarfile) Java Instrumentation.

MANIFEST.MF.

Launcher-Agent-Class: com.yourpackage.Agent

. Agent.addClassPath(File f) Jar- Agent.addClassPath(File f) classpath Java 8 9+.

public class Agent {
    private static Instrumentation inst = null;

    // The JRE will call method before launching your main()
    public static void agentmain(final String a, final Instrumentation inst) {
        Agent.inst = inst;
    }

    public static boolean addClassPath(File f) {
        ClassLoader cl = ClassLoader.getSystemClassLoader();

        try {
            // If Java 9 or higher use Instrumentation
            if (!(cl instanceof URLClassLoader)) {
                inst.appendToSystemClassLoaderSearch(new JarFile(f));
                return;
            }

            // If Java 8 or below fallback to old method
            Method m = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
            m.setAccessible(true);
            m.invoke(cl, (Object)f.toURI().toURL());
        } catch (Throwable e) { e.printStackTrace(); }
    }

}
0

All Articles