28 June 2019
To load calsses in runtime java uses ClassLoader mechanism which is based on next core principles:
parent-first delegation
, - child ClassLoader will be used if parent is not able to find or load class. This behavior can be changed to child-first
by overwriting ClassLoader.loadClass(...)
;The main scenarios to use custom ClassLoader is:
So, let's see how using of custom ClassLoader looks from source code perspective:
List<File> jars = Arrays.asList(new File("/tmp/jars").listFiles());
URL[] urls = new URL[files.size()];
for (int i = 0; i < jars.size(); i++) {
try {
urls[i] = jars.get(i).toURI().toURL();
} catch (Exception e) {
e.printStackTrace();
}
}
URLClassLoader childClassLoader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
Then load class with custom ClassLoader:
Class.forName("org.kostenko.examples.core.classloader.ClassLoaderTest", true , childClassLoader);
Note! If your loaded libraries uses some resources like properties or something else, you need to provide context class loader:
Thread.currentThread().setContextClassLoader(childClassLoader);
Also, you can use custom ClassLoaders to load services with Java Service Provider Interface(SPI)
ServiceLoader<MyProvider> serviceLoader = ServiceLoader.load(MyProvider.class, childClassLoader);
...