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?
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".
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With