【问题标题】:How to add resources to classpath如何将资源添加到类路径
【发布时间】:2010-09-15 13:43:01
【问题描述】:

如何将文件夹(例如包含艺术的资源文件夹)添加到 netbeans 项目的类路径?我设法通过编辑项目的 NB 生成的 jar 文件(即它的 MANIFEST.MF 文件 + 手动复制资源)手动做到这一点,但是应该有一种方法来告诉 netbeans 以及注意资源,不是吗?

文件夹结构如下:

/project/art/
/project/dist/lib/
/project/dist/art/
/project/dist/project.jar
/project/lib/
/project/src/

我不想将艺术品打包到罐子中,因为我希望艺术品可以轻松更换。如果我将 art 文件夹添加到 src 文件夹中,那么 NB 可以正常编译,但 art 资源最终会在 jar 中。

将 art 文件夹添加到 netbeans 项目库(属性 -> 库 -> 添加 JAR/文件夹)似乎不起作用,因为我最终得到一个错误'...\project\art is a directory or can不被阅读。不复制库。这反过来甚至阻止了真正的库文件夹被复制。

有什么想法吗?

最好的问候 克里斯

2 基于 gpeche 的 cmets 的观察结果: a)而不是在“运行”选项卡中指定附加资源文件夹而不是在项目属性的“编译”选项卡中 - >库似乎在Netbeans中没有太大区别(我目前使用的是6.9.1) .输出(因此错误)保持不变,即根本没有复制任何内容:

Created dir: C:\Users\Chrisi\Desktop\vocabulary\VocabularyTrainer\dist
C:\Users\Chrisi\Desktop\vocabulary\VocabularyTrainer\art is a directory or can't be read. Not copying the libraries.
Not copying the libraries.
Building jar: C:\Users\Chrisi\Desktop\vocabulary\VocabularyTrainer\dist\VocabularyTrainer.jar

另一个有趣的方面是,在“库”面板的帮助菜单中,没有明确提及将文件夹作为库。是否有可能,Netbeans 中的按钮被错误命名,即只允许使用真正的 jar?

b) 将资源文件夹添加到库列表确实会产生影响,将另一个条目添加到 MANIFEST.MF。虽然 - 这是较小的问题 - 类路径条目似乎总是期望资源文件夹是库文件夹的子文件夹(例如“lib/arts”),主要问题是似乎缺少斜线。 如前所述,在 MANIFEST.MF 中 NB 生成的条目看起来像这样“lib/arts”(这对我不起作用),而(手动设置)“lib/arts/”呢?!

我使用文件夹中资源的方式是这样的:

URL resource = getClass().getResource("/gui/refresh.png");
ImageIcon tmp = new ImageIcon(resource);

编辑:

根据 Tushars 的评论和 this posting,我发现以下解决方案是功能性和舒适性之间可接受的折衷方案。

我从自动生成的“build-impl.xml”文件中覆盖了 ANT 目标,该文件在 Netbeans 项目的基本“build.xml”文件中的 MANIFEST.MF 文件中创建了类路径。转到“build.xml”文件的代码如下所示:

  <property name="art.classpath" value="art/" />

  <target name="-post-jar">
    <mkdir dir="${dist.dir}/art"/>
    <copy todir="${dist.dir}/art">
      <fileset dir="${basedir}/art">
        <!-- <exclude name="**/!source/**"/> if you want to exclude something... -->
      </fileset>
    </copy>
  </target>

  <target name="-init-macrodef-copylibs">
    <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
      <element name="customize" optional="true"/>
      <sequential>
        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
        <pathconvert property="run.classpath.without.build.classes.dir">
          <path path="${run.classpath}"/>
          <map from="${build.classes.dir.resolved}" to=""/>
        </pathconvert>
        <pathconvert pathsep=" " property="jar.classpath">
          <path path="${run.classpath.without.build.classes.dir}"/>
          <chainedmapper>
            <flattenmapper/>
            <globmapper from="*" to="lib/*"/>
          </chainedmapper>
        </pathconvert>
        <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
        <copylibs compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
          <fileset dir="${build.classes.dir}"/>
          <manifest>
            <attribute name="Class-Path" value="${jar.classpath} ${art.classpath}"/>
            <customize/>
          </manifest>
        </copylibs>
      </sequential>
    </macrodef>
  </target>

权衡的是,为了在 Netbeans 中进行开发,我仍然必须将资源文件夹(例如“art”)添加到库列表中,以使项目在 Netbeans 中运行。这将导致在 MANIFEST.MF 文件 ('lib/art') 中增加一个条目,同时库不会自动复制到 'dist' 文件夹中,并显示消息

...\art is a directory or can't be read. Not copying the libraries.
Not copying the libraries.

这种行为是 - afaik - 旨在(强制将所有东西捆绑在一个罐子中),即使有关于它的讨论正在进行。要制作真正的分发包,我必须从 NB 的库列表中删除资源文件夹并重新构建。

当然,我们仍然欢迎有关更简化设置且无需任何权衡的想法。 :)

【问题讨论】:

    标签: java netbeans classpath


    【解决方案1】:
    1. 将资源文件夹添加到类路径:

      当您清理并构建基于 NetBeans Ant 的项目时,它会在项目的根目录中创建一个 manifest.mf 文件。该文件也包含在 JAR 文件中。修改此文件并添加如下条目:

      Manifest-Version: 1.0
      X-COMMENT: Main-Class will be added automatically by build
      Class-Path: arts/  
      

      在类路径中,斜线很重要。

    2. 在分发中包含艺术资源文件夹

      要么在构建后将此文件夹复制到 dist 文件夹中,要么添加一个 ANT 目标以将所需资源复制到 dist 文件夹中。

      在 build.xml 文件中添加如下目标:

      <target name="-post-jar">
           <mkdir dir="${dist.dir}/resources"/>
           <copy todir="${dist.dir}/resources">
               <fileset dir="${basedir}/resources" />
           </copy>
       </target>
      
    3. 访问此类资源的代码:

      访问此类资源文件所需的代码如下:(这在设计时不起作用,但肯定来自 JAR 文件)

      // pay attention to relative path
      URL resource = ClassLoader.getSystemResource("gui/refresh.png"); 
      ImageIcon tmp = new ImageIcon(resource);
      

      注意:位于项目根目录中的文件 manifest.mf 和 build.xml 可从 NetBeans IDE 中的文件面板访问

    【讨论】:

    • 1) 在 NB 项目 manifest.mf 文件中添加一些东西(在这种情况下是 Class-Path)似乎会覆盖其他任何东西(例如,添加到项目中的其他库)。知道如何恢复原始路径吗?例如,库本身将被复制。 3)对我来说,如果没有前导斜杠,它就不起作用 - 我必须添加那个斜杠,然后它才能工作。
    • 我建议首先从 NetBeans 构建中生成 manifest.mf,然后使用这些默认类路径值以及添加的其他目录路径。
    • 请同时添加如何排除文件夹资源的指南,这样它就不会包含在.jar中
    • 有没有办法在NB中自动自定义这个而不去构建文件?
    【解决方案2】:

    使用 NetBeans 8.0.2:

    1. 右键单击项目。
    2. 选择属性
    3. 选择来源
    4. 源包文件夹单击添加文件夹
    5. 选择资源所在的目录。
    6. 点击目录名称上的打开
    7. 点击确定关闭项目属性对话框。

    资源被添加到项目中。

    您还会在导航窗格中看到添加的目录

    在另一个项目中,资源现在可用。例如,读取图像:

    BufferedImage zero = ImageIO.read(OCR.class.getResourceAsStream("/0.bmp"));
    

    【讨论】:

      【解决方案3】:

      为了从 Class-Path 中删除 lib/art 而不是得到“是目录或无法读取”,需要从路径中删除 lib/art:

          <pathconvert property="run.classpath.without.build.classes.dir">
            <path path="${run.classpath}"/>
            <map from="${build.classes.dir.resolved}" to=""/>
            **<map from="${basedir}/art" to=""/> <!-- remove art from lib -->**
          </pathconvert>
      

      【讨论】:

        猜你喜欢
        • 2018-03-29
        • 1970-01-01
        • 1970-01-01
        • 2014-06-02
        • 1970-01-01
        • 2021-12-29
        • 2012-06-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多