We have an executable JAR file that sometimes contains other JAR files. (All this applies to four other loaded JAR servers that ride on the back of a giant deployed turtle in space.) At run time, we dynamically load this attached JAR file by doing the following:
// wearyingly verbose error handling elided URL nestedURL = the_main_system_classloader.getResource("path/to/nested.jar"); File temp = File.createTempFile (....); // copy out nestedURL contents into temp, byte for byte URL tempURL = temp.toURI().toURL(); URLClassLoader loader = URLClassLoader.newInstance(new URL[]{ tempURL }); Class<?> clazz = loader.loadClass("com.example.foo.bar.baz.Thing"); Thing thing = (Thing) clazz.newInstance(); // do stuff with thing
This type of technique has been raised here before; links include this and this . The code we have now works ...
... mostly. I would really like to find a way to avoid creating and copying files temporarily (and possible cleaning up, because, as we all know, deleteOnExit is evil ). The URL obtained right at the beginning points to the JAR, in the end:
URL nestedURL = the_main_system_classloader.getResource("path/to/nested.jar"); // nestedURL.toString() at this point is // "jar:file:/C:/full/path/to/the/executable.jar!/path/to/nested.jar" URLClassLoader loader = URLClassLoader.newInstance(new URL[]{ nestedURL }); Class<?> clazz = loader.loadClass("com.example.foo.bar.baz.Thing");
But loadClass throws a ClassNotFound.
Can a URLClassLoader just not handle this JAR-in-a-JAR case? Or do I need to do something for one or more paths associated with it (either a nested URL or in a string passed to loadClass) to make this work?
java jar classloader
Ti Strga
source share