如何在使用Ant的jar任务将文件打包到一个jar中时重命名文件?

13

我想把一组看起来像这样的文件放入一个jar包中:

yay/my.jar
boo/my.jar
foo/my.jar
bar/my.jar
在此过程中,我希望它们都按如下方式更名:
yay_my.jar
boo_my.jar
foo_my.jar
bar_my.jar
我希望使用一个映射器来实现这个目标,但我正在使用的文件集元素和jar任务似乎没有任何支持它的地方。
我该如何在构建jar时应用映射器,或者如何执行类似于此的转换?我想避免将所有文件复制到我想要的目录结构中并且在各处制作副本,这就是我们现在的构建系统的工作方式。
3个回答

17

你可以使用带有fullpath属性的zipfileset来在JAR文件中重命名文件名:

<jar destfile="newjar.jar">
    <zipfileset dir="yay" includes="my.jar" fullpath="yay_my.jar"/>
    <zipfileset dir="boo" includes="my.jar" fullpath="boo_my.jar"/>
    <!-- etc. -->
</jar>

但是你不能使用映射器(mapper)来执行此技术,你必须明确列出每个JAR文件。如果你可以假设每个文件都命名为my.jar,并且它们都在一个直接子目录中,那么你可以使用subant目标将它们全部打包起来:

<target name="glom">
    <subant genericantfile="${ant.file}" target="update-jar">
        <dirset dir="." includes="*"/>
    </subant>
</target>

<target name="update-jar">
    <basename file="${basedir}" property="dirname"/>
    <property name="path" value="${dirname}_my.jar"/>
    <jar destfile="../newjar.jar" update="yes">
        <zipfileset dir="." includes="my.jar" fullpath="${path}"/>
    </jar>
</target> 

+1 不错的重命名文件的方法,在 jar 任务中十分便捷。谢谢。 - Damo

2
如果您不想(或无法轻松)逐个列出每个文件,则可以使用Zip任务的解决方案,它允许嵌套<mappedresources>(Ant 1.8.0+)。一旦Zip任务完成,您可以使用Jar任务添加/更新清单和/或添加索引。
例如,假设除了希望在输出JAR中包含yay_my.jar、boo_my.jar、foo_my.jar和bar_my.jar之外,您还有一个名为stuff/的目录,其中包含一些文件和子目录。如果您希望将stuff/的内容包含在JAR中,但是您希望将stuff/subdir/*添加为other_subdir/*,请考虑以下内容:
<zip destfile="newjar.jar">
    <zipfileset dir="yay" includes="my.jar" fullpath="yay_my.jar"/>
    <zipfileset dir="boo" includes="my.jar" fullpath="boo_my.jar"/>
    <!-- etc. -->

    <mappedresources>
        <fileset dir="stuff"/>
        <compositemapper>
            <globmapper from="subdir/*" to="other_subdir/*"/>
            <identitymapper/>
        </compositemapper>
    </mappedresources>
</zip>
<!-- Update the newly-created ZIP in-place to add a basic manifest -->
<jar destfile="newjar.jar" update="true"/>

我测试了这个构建文件,它可以与Ant 1.8.2一起使用。然而,如果在更改后Ant开始抛出一个NullPointerException,请参阅Bug 54026

2
更新:您可能实际上想要使用复制任务而不是移动,但正则表达式映射器对于复制和移动都是相同的。

以下正则表达式将把jars目录中的所有jar文件复制到jars_out目录,将[folder]/[file].jar映射为[folder]_[file].jar。

<copy todir="./jars_out">
  <fileset dir="jars"/>
  <mapper type="regexp" from="([^/\\]*)[/\\](.*)\.jar$$" to="\1_\2.jar"/>
</copy>

正则表达式映射器需要在类路径上拥有一个合适的正则表达式实现Jar才能工作。有多种实现可供选择:

这很好,但并没有达到我的目标,即在不创建额外文件的情况下构建jar包。使用Move操作可以避免复制,但这样每次构建时都会重新构建jar包,而不仅仅在它们的源文件发生更改时才进行。 - skiphoppy
然而,你所构建的映射器标签非常棒,我将借用它,而不是自己想出一个。 :) 我还没有进展到实际构建所需的映射器,因为我无法让任何映射器与文件集和JAR一起工作。 - skiphoppy
抱歉,我误读了问题。我会考虑如何完成这个任务,但现在有人叫我去酒吧了。 - Rich Seller
你的帮助非常棒,Rich。这是一个很长的问题,我认为你错过了其中的一部分可以被原谅。:) 谢谢你。 - skiphoppy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接