/project/art/
/project/dist/lib/
/project/dist/art/
/project/dist/project.jar
/project/lib/
/project/src/
我不想将艺术资源打包到jar文件中,因为我希望这些资源可以轻松交换。如果我将art文件夹添加到src文件夹中,NetBeans编译就没问题了,但是艺术资源最终会被打包到jar文件中。
将art文件夹添加到NetBeans项目库(属性->库->添加 JAR/文件夹)似乎不起作用,因为我遇到了一个错误“...\project\art是一个目录或无法读取。不复制库。”这又阻止了实际库文件夹的复制。
有什么想法吗?
最好的问候 Chris
根据gpeche的评论,提供两点观察: a) 在NetBeans中,将额外资源文件夹在项目属性 -> 库的“运行”选项卡中指定,而不是在“编译”选项卡中指定似乎没有太大差别。输出(因此错误)保持不变,即根本没有复制任何内容:
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文件吗?
将资源文件夹添加到库列表中确实会对MANIFEST.MF添加另一个条目。虽然问题较小,但classpath条目似乎始终期望资源文件夹是库文件夹的子文件夹(例如“lib/arts”),主要问题在于似乎缺少斜杠。如上所述,NB生成的MANIFEST.MF中的条目看起来像这样“lib/arts”(对我无效),而手动设置的“lib/arts /”呢?
我使用资源文件夹的方式类似于:
URL resource = getClass().getResource("/gui/refresh.png");
ImageIcon tmp = new ImageIcon(resource);
编辑:
根据Tushar的评论和这篇文章,我发现以下解决方案在功能和舒适性之间达到了可接受的平衡。
我覆盖了从Netbeans项目的基本'build.xml'文件中自动生成的'build-impl.xml'文件中创建MANIFEST.MF文件中的Class-Path的ANT目标。代码如下:
<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.
据我所知,这种行为是有意的(强制将所有内容捆绑在一个jar包中),尽管仍在进行讨论。要创建一个真正的分发包,我需要从NB中的库列表中删除资源文件夹并重新构建。
当然,欢迎任何没有任何折衷的简化设置的想法。 :)