Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load JAR files dynamically at Runtime?

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 by writing your own ClassLoader, but that's a lot of work for something that should (in my mind at least) be as easy as calling a method with a JAR file as its argument.

Any suggestions for simple code that does this?

like image 970
Allain Lalonde Avatar asked Sep 13 '08 18:09

Allain Lalonde


People also ask

How do I import a class from a specific JAR file?

One option is to call File. listFiles() on the File that denotes the folder, then iterate the resulting array. To traverse trees of nested folders, use recursion. Scanning the files of a JAR file can be done using the JarFile API ... and you don't need to recurse to traverse nested "folders".


2 Answers

The reason it's hard is security. Classloaders are meant to be immutable; you shouldn't be able to willy-nilly add classes to it at runtime. I'm actually very surprised that works with the system classloader. Here's how you do it making your own child classloader:

URLClassLoader child = new URLClassLoader(         new URL[] {myJar.toURI().toURL()},         this.getClass().getClassLoader() ); Class classToLoad = Class.forName("com.MyClass", true, child); Method method = classToLoad.getDeclaredMethod("myMethod"); Object instance = classToLoad.newInstance(); Object result = method.invoke(instance); 

Painful, but there it is.

like image 133
jodonnell Avatar answered Oct 18 '22 08:10

jodonnell


The following solution is hackish, as it uses reflection to bypass encapsulation, but it works flawlessly:

File file = ... URL url = file.toURI().toURL();  URLClassLoader classLoader = (URLClassLoader)ClassLoader.getSystemClassLoader(); Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); method.setAccessible(true); method.invoke(classLoader, url); 
like image 25
Allain Lalonde Avatar answered Oct 18 '22 07:10

Allain Lalonde