2013-09-25 36 views
8

我们有一个可执行的JAR文件,有时包含其他JAR文件。 (整个事情搁在其他四个下载JAR文件,骑在巨人部署龟在空间中的背面)在运行时,我们动态地加载嵌套的JAR文件执行以下操作:Java的类加载器与罐中的罐子

// 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 onethis one。我们目前已有的代码工程...

...主要是。我真的很想找到一些方法来避免临时文件的创建和复制(并最终进行清理,因为我们都知道,deleteOnExit is evil)。 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-JAR内的情况?或者我需要对涉及的一个或多个路径(nestedURL或传递给loadClass的字符串)做些什么来使其工作?

+0

我可能会用它来构建一个单一的jar - http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html。 –

+0

您是否曾尝试将'addUrl'添加到主类加载器中,然后正常加载类? – assylias

+0

@PaulGrime不幸的是,授权允许我们只重新分配嵌套的jar文件,但不能解压缩/重新打包它们。 –

回答

0

AFAIK香草URLClassloader无法处理它。

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

除了您的解决方案有一些我所知道的其他两种可能性:

  1. (使用Maven阴影p.ex.)
  2. 创建一个定制的ClassLoader创建脂肪罐子,但是这是一种努力工作。