2011-05-10 84 views
2

我想从运行时添加的Jar文件加载资源,但并没有变得很远。在运行时从Jar文件加载资源

这里是我的代码(常规):

URL url = new URL("jar:file:/out/resource.jar!/test.resource") 
def urlList = [] << url 
URL[] urls = urlList.toArray() 
URLClassLoader classLoader = new URLClassLoader(urls, this.class.getClassLoader()) 
InputStream stream = url.openStream() 

我得到这个错误: java.util.zip.ZipException:错误在java.util.zip.ZipFile.open打开zip文件 (本地方法)

问题:

1)我需要把 “test.resource” 在我的网址是什么? 2)我的URLClassLoader和我的当前类的类加载器之间有什么关系? 3)什么是正确的方式来流这个资源(显然我有什么不工作)?

感谢

回答

0

如果jar文件在类路径中已经那么你就应该能够做到Classloader.getResourceAsStream

是您当前classpath超出这个罐子?

+0

在我当前的classpath之外....在运行时添加。 – 2011-05-10 23:44:19

4

如果要将JAR文件添加到当前线程的ClassLoader中,您需要创建一个新的URLClassLoader,请使用当前类的ClassLoader作为父项并添加新的JAR URL。您不得在您的网址中放入test.resource。不要忘记将新的ClassLoader分配给当前线程。看下面的例子:

URL url = new URL("file:/out/resource.jar") 
def urlList = [] << url 
URL[] urls = urlList.toArray() 
URLClassLoader classLoader = new URLClassLoader(urls, getClass().classLoader) 
Thread.currentThread().setContextClassLoader(classLoader) 

现在,你应该能够通过Thread.currentThread().getContextClassLoader().getResourceAsStream来获取文件。

如果你真的只是想读取JAR文件而不将它添加到你的classpath,你可以采取以下方法:

JarFile jar = new JarFile(new File('/out/resource.jar')) 
JarEntry jarEntry = jar.getJarEntry('test.resource') 

if(jarEntry) { 
    File file = new File(new URL("jar:file:/out/resource.jar!/test.resource").toURI()) 
} 
+0

“不要忘记将新ClassLoader分配到当前线程中” - 如果你想访问资源非常重要,如果你不喜欢它,那么它就非常重要。感谢Ben,保存了一些问题 – Spedge 2013-10-17 10:43:43

0

我更熟悉Java比常规,但是这应该给你的InputStream你问:

JarFile jarFile = new JarFile(new File("/out/resource.jar")) 
JarEntry jarEntry = jarFile.getJarEntry("test.resource") 
InputStream inputStream = jarFile.getInputStream(jarEntry) 

没有必要担心的ClassLoader,除非:

  1. 呦你正试图加载类(例如作为插件),
  2. 你的资源都位于一些封装结构中,或
  3. 你OSGi环境与多个不同的类路径和类加载器中加载的资源(在这种情况下,你可以使用这样的org.eclipse.core.runtime.FileLocator#resolve(URL)