Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 9, compatability issue with ClassLoader.getSystemClassLoader

The following code adds jar file to the build path, it works fine with Java 8. However, it throws exception with Java 9, the exception is related to the cast to URLClassLoader. Any ideas how this can be solved? an optimal solution will edit it to work with both Java 8 & 9.

private static int AddtoBuildPath(File f) {
    try {
        URI u = f.toURI();
        URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
        Class<URLClassLoader> urlClass = URLClassLoader.class;
        Method method = urlClass.getDeclaredMethod("addURL", URL.class);
        method.setAccessible(true);
        method.invoke(urlClassLoader, u.toURL());
    } catch (NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException | MalformedURLException | IllegalAccessException ex) {
        return 1;
    }

    return 0;
}
like image 520
Mostafa abdo Avatar asked Oct 11 '17 17:10

Mostafa abdo


People also ask

Which ClassLoader loads JAR files from JDK?

The Bootstrap class loader loads the basic runtime classes provided by the JVM, plus any classes from JAR files present in the system extensions directory. It is parent to the System class loader. To add JAR files to the system extensions, directory, see Using the Java Optional Package Mechanism.

What is Java Lang ClassLoader?

A class loader is an object that is responsible for loading classes. The class ClassLoader is an abstract class. Given the binary name of a class, a class loader should attempt to locate or generate data that constitutes a definition for the class.

Is URL class A Java ClassLoader?

Class URLClassLoader. This class loader is used to load classes and resources from a search path of URLs referring to both JAR files and directories. Any URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL is assumed to refer to a JAR file which will be opened as needed.

How does ClassLoader work in Java?

A Java Class is stored in the form of byte code in a . class file after it is compiled. The ClassLoader loads the class of the Java program into memory when it is required. The ClassLoader is hierarchical and so if there is a request to load a class, it is delegated to the parent class loader.


1 Answers

You've run into the fact that the system class loader is no longer a URLClassLoader. As indicated by ClassLoader::getSystemClassLoader's return type, this was an implementation detail, albeit one that a non-negligible amount of code relied upon.

Judging by the comments, you are looking for a way to dynamically load classes at run time. As Alan Bateman points out, this can not be done in Java 9 by appending to the class path.

You should instead consider creating a new class loader for that. This has the added advantage that you'll be able to get rid of the new classes as they are not loaded into the application class loader. If you're compiling against Java 9, you should read up on layers - they give you a clean abstraction for loading an entirely new module graph.

like image 84
Nicolai Parlog Avatar answered Sep 19 '22 11:09

Nicolai Parlog