【问题标题】:Simple way to use a jar as a resource archive使用 jar 作为资源存档的简单方法
【发布时间】:2012-06-18 03:36:48
【问题描述】:

所以,我正在开发一个 Java 应用程序,我想将资源打包到 jar 文件中,以使它们更便于移植。这些 jar 文件将与应用程序分开,并且仅包含资产(图像、声音、保存文件等)。

从像这样的 jar 文件中访问任意资源的最简单方法是什么?我环顾四周,但找不到任何简单的教程。我知道我可以使用 ClassLoader 从 Jar 文件中检索输入流,但是如何获得引用正确 Jar 的 ClassLoader?

另外,我如何以编程方式将一堆资源捆绑到这样的 jar 文件中?如果我能以我想要的方式让它工作,我想将它用于一堆东西,并希望能够动态创建任何需要的档案。

【问题讨论】:

  • “正确的罐子”?您将获得具有完全相同包装和名称的资源?
  • 出于各种原因,我推荐getResource("/path/to/the.resource") 而不是getResourceAsStream。见info. page on embedded resources(我在其中列出了替代方案,没有解释)。
  • @DaveNewton - 不,当然不是,我只是在引用一个事实,即我想针对特定的外部 jar。
  • @AndrewThompson - 好的,我明白为什么这可能是个好主意。感谢您的提示。
  • @CodeBunny 为什么?如果资源具有唯一限定符,则无需指定 jar。

标签: java resources jar classloader embedded-resource


【解决方案1】:

要读取资源,请使用您要从中加载的 JAR 的 URL 构造一个新的 URLClassLoader

File jarFile1 = new File("myjar.jar");
File jarFile2 = new File("myjar2.jar");
ClassLoader myJarLoader = URLClassLoader.newInstance(new URL[] {jarFile1.toURI().toURL(), 
                                                                jarFile2.toURI().toURL()});

要创建 JAR 文件,您可以使用 JarOutputStream 类。

【讨论】:

  • 很好,谢谢。我不知道您可以即时创建 ClassLoaders。
  • 实际上,我认为您选择了一个过于复杂的解决方案。获取资源的最简单方法是将 Jar 添加到应用程序的运行时类路径中。做到这一点的最佳方式取决于如何 部署它。 -- OTOH 建立URLClassLoader 在特定情况下非常方便,但在这种情况下不是必需的。无法在沙盒代码中建立ClassLoader,而getResource(String) 方法适用于沙盒代码或受信任代码。
【解决方案2】:

我的 jar 文件在类路径中 Thread.currentThread().getContextClassLoader().getResourceAsStream(path/file.ext) 将按名称加载资源。

jar -cvf jarname.jar 资源

将所有资源添加到 jarname.jar,尝试使用 ZipOutputStream 以编程方式实现。

【讨论】:

    【解决方案3】:

    getResourceAsStream与资源包路径一起使用应该不会有问题,前提是带有资源的jar位于应用程序的类路径中

    从二进制文件自动创建 resource.jar 的一种方法是使用 apache ant 进行构建,使用如下目标,您将获取每个 res 包资源并将其复制到目标 jar 中

    <property name="binDir" value="bin" />
    ...
    
    <target name="resources-jar">
        <echo message="Generating resources.jar" />
        <jar compress="true" destfile="resources.jar" filesetmanifest="mergewithoutmain">
            <fileset defaultexcludes="true" dir="${binDir}"> 
                <include name="**/res/**" />              
            </fileset>
        </jar>
    </target>  
    

    例如,由于以下包

     com/myapp/logic 
     com/myapp/logic/res
     com/myapp/menu
     com/myapp/menu/res 
     com/myapp/actions
     com/myapp/actions/res
    

    resource.jar 文件将包含以下包:

     com/myapp/logic/res
     com/myapp/menu/res 
     com/myapp/actions/res
    

    您也可以将res 更改为assets

    【讨论】:

      猜你喜欢
      • 2013-04-16
      • 1970-01-01
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-04
      • 2012-04-09
      相关资源
      最近更新 更多