【问题标题】:load resource from Jar file at runtime在运行时从 Jar 文件加载资源
【发布时间】:2013-05-07 13:41:02
【问题描述】:

我正在尝试从运行时添加的 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:打开 zip 文件时出错 在 java.util.zip.ZipFile.open(本机方法)

问题:

1) 我需要在我的网址中添加“test.resource”吗? 2) 我的 URLClassLoader 和我当前类的类加载器有什么关系? 3) 在此资源中流式传输的正确方法是什么(显然我所拥有的不起作用)?

谢谢

【问题讨论】:

    标签: java groovy jar


    【解决方案1】:

    如果您想将 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 中读取文件而不将其添加到类路径中,您可以采用以下方法:

    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())
    }
    

    【讨论】:

    • “不要忘记将新的 ClassLoader 分配给您当前的线程”——如果您想访问资源,这一点非常重要,如果您不这样做,它似乎无法获取它们。谢谢 Ben,解决了一些问题
    【解决方案2】:

    如果 jar 文件已经在你的类路径中,那么你应该可以这样做 Classloader.getResourceAsStream

    这个 jar 在你当前的类路径之外吗?

    【讨论】:

      【解决方案3】:

      我对 java 比对 groovy 更熟悉,但这应该会给你你要求的 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. 您正在使用多个不同的 ClassPath 和 ClassLoader 加载 OSGi 环境中的资源(在这种情况下,您可能会使用 org.eclipse.core.runtime.FileLocator#resolve(URL) 之类的东西)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-10
        • 1970-01-01
        • 2014-10-11
        • 2015-05-03
        • 1970-01-01
        • 1970-01-01
        • 2015-08-03
        • 2015-11-16
        相关资源
        最近更新 更多