10

我们有一个有时包含其他 JAR 文件的可执行 JAR 文件。(整个过程依赖于其他四个下载的 JAR,它们骑在太空中部署的巨型海龟的背上。)在运行时,我们动态加载嵌套的 JAR 文件,执行以下操作:

// 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

这种技术以前在这里提出过;链接包括这个这个。我们目前拥有的代码有效......

...大多。我真的很想找到一些方法来避免临时文件的创建和复制(以及最终的清理,因为众所周知,deleteOnExit 是邪恶的)。毕竟,在开始时获得的 URL 指向一个 JAR:

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");

但是 loadClass 会抛出 ClassNotFound。

URLClassLoader 可以简单地不处理这种 JAR-within-a-JAR 案例吗?或者我是否需要对涉及的一个或多个路径(nestedURL 或传递给 loadClass 的字符串)执行某些操作才能使其工作?

4

1 回答 1

1

AFAIK vanilla URLClassloader 无法处理它。

到目前为止,这是你的答案。

除了您的解决方案外,我还知道其他两种可能性:

  1. 创建一个胖罐子(例如使用 Maven Shade)
  2. 创建一个自定义类加载器,但这是一项艰苦的工作。
于 2014-06-17T21:22:22.060 回答