ant 脚本不能支持嵌套的 If 语句



嗨,我正在尝试构建一个基于 if 条件复制某个库文件的 ant 脚本。 但是,当我收到此错误时,它似乎不起作用:

构建.xml:20:文件集不支持嵌套的"if"元素。

这是它失败的部分:

<target name="resolve">
        <delete dir="${lib.dir}">
            <include name="*" />
        </delete>
        <copy todir="${lib.dir}">
            <fileset dir="ext-libs" >
                <if name="${release}" value="true">
                    <include name="hello-client-[^DEBUG]*.jar" />
                </if>
                <else>
                    <include name="hello-client-*DEBUG.*.jar" />
                </else>
            </fileset>
        </copy>
    </target>

@JoseK是对的。ANT 文件集不支持嵌套的"if"语句。事实上,"if"语句不是核心ANT的一部分,推荐的方法是使用条件目标(参见示例(

@slipset走在正确的轨道上。常春藤配置可用于有选择地选择依赖项。

此示例旨在以以下两种方式之一

调用
$ ant clean build
$ tree
.
|-- build.xml
|-- ivy.xml
`-- lib
    |-- slf4j-api-1.6.4.jar
    `-- slf4j-simple-1.6.4.jar

$ ant -Drelease=1 clean build
$ tree
.
|-- build.xml
|-- ivy.xml
`-- lib
    |-- logback-classic-1.0.3.jar
    |-- logback-core-1.0.3.jar
    `-- slf4j-api-1.6.4.jar

构建.xml

<project name="demo" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">
    <target name="resolve">
        <ivy:resolve/>
    </target>
    <target name="retrieve-alt" depends="resolve" unless="release">
        <ivy:retrieve pattern="lib/[artifact]-[revision](-[classifier]).[ext]" conf="altruntime"/>
    </target>
    <target name="retrieve-release" depends="resolve" if="release">
        <ivy:retrieve pattern="lib/[artifact]-[revision](-[classifier]).[ext]" conf="runtime"/>
    </target>
    <target name="build" depends="retrieve-alt,retrieve-release"/>
    <target name="clean">
        <delete dir="lib"/>
    </target>
</project>

笔记:

  • 目标上的 ifexcept 子句对"release"属性的存在执行条件测试。
  • ivy 检索任务使用配置来决定应使用哪些 jar 来填充"lib"目录。
  • 检索模式包括一个"分类器"模式,以防万一你的 ivy 映射拉下其他 Maven 工件,如源或 javadoc jar。

常春藤.xml

<ivy-module version="2.0">
    <info organisation="com.myspotontheweb" module="demo"/>
    <configurations>
        <conf name="compile" description="Required to compile application"/>
        <conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
        <conf name="altruntime"   description="Alternative 'runtime' configuration" extends="compile"/>
        <conf name="test"    description="Required for test only" extends="altruntime"/>
    </configurations>
    <dependencies>
        <!-- compile dependencies -->
        <dependency org="org.slf4j" name="slf4j-api" rev="1.6.4" conf="compile->default"/>
        <!-- runtime dependencies -->
        <dependency org="ch.qos.logback" name="logback-classic" rev="1.0.3" conf="runtime->default"/>
        <!-- altruntime dependencies -->
        <dependency org="org.slf4j" name="slf4j-simple" rev="1.6.4" conf="altruntime->default"/>
        <!-- test dependencies -->
        <dependency org="junit" name="junit" rev="4.10" conf="test->default"/>
    </dependencies>
</ivy-module>

注意:

  • 我强烈建议始终为每个依赖项指定配置映射。然后,这将直接映射到您打算如何使用 jar,例如填充类路径。

附录

如何使用常春藤配置

常春藤配置

可用于模拟 Maven 作用域,但实际上常春藤配置可以表示任何依赖项的逻辑分组。

以下是任何 Java 构建中所需的 3 个标准类路径:

<configurations>
    <conf name="compile" description="Required to compile application"/>
    <conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
    <conf name="test"    description="Required for test only" extends="runtime"/>
</configurations>

请注意"extends"语法,它使您能够创建更大的集。例如,运行时 jar 集还包括编译代码所需的任何内容。

常春藤配置很难理解,直到您意识到它们可用于有选择地填充 ANT 路径:

<ivy:cachepath pathid="compile.path" conf="compile"/>
<javac ..... classpathref="compile.path"/>

或用于有选择地填充目录

<ivy:retrieve pattern="build/WEB-INF/lib/[artifact].[ext]" conf="runtime"/>

配置映射

映射用于确定项目中的 jar 组与其他项目中的 jar 组之间的关系。

这通常发生如下:

<dependency org="org.slf4j" name="slf4j-api" rev="1.6.4" conf="compile->default"/>

这里我们的编译配置由远程默认配置填充(通常其他模块编译依赖(

好吧,apache 文档很清楚,你不能在<fileset>中嵌套一个<if>

您可能已经看到一个 ant-contrib 文件集任务的示例,该任务确实if 作为条件参数

您可以下载并使用它。

我自己的做法有点不同。我有

<target name="internal-resolve" description="retrieve dependencies with ivy">
    <ivy:retrieve pattern = "${basedir}/lib/[conf]/[artifact].[ext]" conf = "${configuration}" />
</target>

这会将 jar 放在名为 lib/${configuration} 的目录中,其中配置作为参数传递

 <target name = "resolve-compile">
    <antcall target = "internal-resolve">
        <param name = "configuration" value = "compile"/>
    </antcall>
</target>

因此,每当调用解析编译时,jar 都会放入lib/compile。这给了我:

<path id = "compile.class.path">
    <fileset dir="${basedir}/lib/compile" includes="*.jar"/>
</path>

最后

    <target name="compile" 
          depends="init, resolve-compile"
          description="Compile all Java-classes">
    <javac deprecation="false"
           encoding="utf8"
           debug="true"
           srcdir="${java.src.dir}"
           destdir="${build.classes.dir}"
           classpathref="compile.class.path"/>
  </target>

鉴于此,您可以轻松创建自己的resolve-build这会将您的罐子放入lib/build

当然,您需要向常春藤添加build配置.xml如

  <configurations>
      <conf name="compile" visibility="public" description="Whatever"/>
      <conf name="build" visibility="public" description="Whatever"/>
  </configuration> 

相关内容

  • 没有找到相关文章

最新更新