简体   繁体   English

在Ant脚本中使Java步骤失败

[英]Making Java step in Ant script fail the build

Please excuse if the question is dumb, I'm only 2nd day on Ant and Java hacking together some CI solution with next to no knowledge of Ant or Java. 如果问题是愚蠢的,请原谅,我只是第二天在Ant上和Java一起攻击一些CI解决方案,而不知道Ant或Java。

So I wish a build to fail if (my) java program run as a step within the build decides that the build must fail. 所以我希望构建失败如果(我的)java程序作为构建中的一个步骤运行,则决定构建必须失败。

I thought of just throwing an unhandled exception in the Java program or using System.exit() to shut down the JVM but they seem quite nasty. 我想过只是在Java程序中抛出一个未处理的异常,或者使用System.exit()来关闭JVM,但它们看起来非常讨厌。

Is there a nice way of ant failing the build if a java step decides it should? 如果一个java步骤决定它应该有一个很好的方式蚂蚁失败的构建?

For the <java> task, there is an attribute failonerror . 对于<java>任务,有一个属性failonerror If you set it to yes (or true ), the build will fail if the process returned anything else than 0. 如果将其设置为yes (或true ),则如果进程返回0以外的任何内容,则构建将失败。

The problem is that for returning some value from a java call, this call must System.exit(value) . 问题是,为了从java调用返回一些值,这个调用必须是System.exit(value) For it to not kill your ant, you also need to provide fork=true to run in a new JVM. 为了不杀死你的蚂蚁,你还需要提供fork=true来在新的JVM中运行。

So, the java call could look like this: 所以,java调用可能如下所示:

<java jar="..."
      fork="yes"
      failonerror="yes">
</java>

Of course, you could also have your Java program implement the Ant Task API and load/call it as a proper ant task. 当然,您也可以让Java程序实现Ant Task API并将其作为正确的ant任务加载/调用。 Then it can itself decide what to do (and will be more configurable, too). 然后它可以自己决定做什么(并且也将更加可配置)。

The Ant manual shows a built-in task named Fail which you can configure with specific conditions to make the build fail. Ant手册显示了一个名为Fail的内置任务,您可以使用特定条件配置该任务以使构建失败。

<fail message="Files are missing.">
    <condition>
        <not>
            <resourcecount count="2">
                <fileset id="fs" dir="." includes="one.txt,two.txt"/>
            </resourcecount>
        </not>
    </condition>
</fail>

You might want to look into that one. 你可能想看一下那个。

Ant ought to be straightforward. Ant应该是直截了当的。 It does fail a build if a particular step does not succeed. 如果特定步骤不成功,它确实会失败。 I think the behavior you want is already built-in. 我认为你想要的行为已经内置了。

As for your custom step, my advice would be to find a way to do that outside of Ant for now while you get the rest of the CI flow working. 至于你的自定义步骤,我的建议是找到一种方法在Ant之外执行此操作,同时让其他CI流程正常工作。 Better to make that much progress rather than falling into a hole over one detail. 最好是取得这么大的进步,而不是陷入一个细节之中。

It might help if you describe what your program is doing. 如果您描述您的程序正在做什么,它可能会有所帮助。 Perhaps there's a better way to accomplish what you need. 也许有更好的方法来完成你所需要的。

UPDATE: I don't think you should head down this path. 更新:我认为你不应该走这条路。 The tests you run with CC should be unit tests. 使用CC运行的测试应该是单元测试。 If you have to package and deploy the application to test, I'd call those integration tests. 如果必须打包并部署应用程序进行测试,我会调用这些集成测试。 Run those separately as part of your QA step, not the build. 作为QA步骤的一部分单独运行,而不是构建。

You're doing the right thing with Selenium; 你正在用Selenium做正确的事; I like your rigor and effort. 我喜欢你的严谨和努力。 But I'd recommend running just the unit tests with CC, package and deploy the app to a QA server, then run your Selenium tests as JUnits. 但我建议只使用CC运行单元测试,打包并将应用程序部署到QA服务器,然后将您的Selenium测试作为JUnit运行。 They're scripted and fast. 它们的脚本编写速度很快。

I also wonder about the wisdom of using Selenium to check for widget placements in the UI. 我也想知道使用Selenium在UI中检查小部件位置的智慧。 That seems brittle to me; 这对我来说似乎很脆弱; best left to a human. 最好留给人类。

Here's a generic Ant build that I re-use often. 这是我经常重复使用的通用Ant构建。 Feel free to use it as reference. 随意使用它作为参考。 Keep telling yourself "This ought to be simple." 继续告诉自己“这应该很简单。” IF it gets too hard, you're doing it wrong. 如果它变得太难了,你做错了。

<?xml version="1.0" encoding="UTF-8"?>
<project name="xslt-converter" basedir="." default="package">

    <property name="version" value="1.6"/>
    <property name="haltonfailure" value="no"/>

    <property name="out" value="out"/>

    <property name="production.src" value="src"/>
    <property name="production.lib" value="lib"/>
    <property name="production.resources" value="config"/>
    <property name="production.classes" value="${out}/production/${ant.project.name}"/>

    <property name="test.src" value="test"/>
    <property name="test.lib" value="lib"/>
    <property name="test.resources" value="config"/>
    <property name="test.classes" value="${out}/test/${ant.project.name}"/>

    <property name="exploded" value="out/exploded/${ant.project.name}"/>
    <property name="exploded.classes" value="${exploded}/WEB-INF/classes"/>
    <property name="exploded.lib" value="${exploded}/WEB-INF/lib"/>

    <property name="reports.out" value="${out}/reports"/>
    <property name="junit.out" value="${reports.out}/junit"/>
    <property name="testng.out" value="${reports.out}/testng"/>

    <path id="production.class.path">
        <pathelement location="${production.classes}"/>
        <pathelement location="${production.resources}"/>
        <fileset dir="${production.lib}">
            <include name="**/*.jar"/>
            <exclude name="**/junit*.jar"/>
            <exclude name="**/*test*.jar"/>
        </fileset>
    </path>

    <path id="test.class.path">                            
        <path refid="production.class.path"/>
        <pathelement location="${test.classes}"/>
        <pathelement location="${test.resources}"/>
        <fileset dir="${test.lib}">
            <include name="**/junit*.jar"/>
            <include name="**/*test*.jar"/>
        </fileset>
    </path>

    <path id="testng.class.path">
        <fileset dir="${test.lib}">
            <include name="**/testng*.jar"/>
        </fileset>
    </path>

    <available file="${out}" property="outputExists"/>

    <target name="clean" description="remove all generated artifacts" if="outputExists">
        <delete dir="${out}" includeEmptyDirs="true"/>
        <delete dir="${reports.out}" includeEmptyDirs="true"/>
    </target>

    <target name="create" description="create the output directories" unless="outputExists">
        <mkdir dir="${production.classes}"/>
        <mkdir dir="${test.classes}"/>
        <mkdir dir="${reports.out}"/>
        <mkdir dir="${junit.out}"/>
        <mkdir dir="${testng.out}"/>
        <mkdir dir="${exploded.classes}"/>
        <mkdir dir="${exploded.lib}"/>
    </target>

    <target name="compile" description="compile all .java source files" depends="create">
        <!-- Debug output
                <property name="production.class.path" refid="production.class.path"/>
                <echo message="${production.class.path}"/>
        -->
        <javac srcdir="src" destdir="${out}/production/${ant.project.name}" debug="on" source="${version}">
            <classpath refid="production.class.path"/>
            <include name="**/*.java"/>
            <exclude name="**/*Test.java"/>
        </javac>
        <javac srcdir="${test.src}" destdir="${out}/test/${ant.project.name}" debug="on" source="${version}">
            <classpath refid="test.class.path"/>
            <include name="**/*Test.java"/>
        </javac>
    </target>

    <target name="junit-test" description="run all junit tests" depends="compile">
        <!-- Debug output
                <property name="test.class.path" refid="test.class.path"/>
                <echo message="${test.class.path}"/>
        -->
        <junit printsummary="yes" haltonfailure="${haltonfailure}">
            <classpath refid="test.class.path"/>
            <formatter type="xml"/>
            <batchtest fork="yes" todir="${junit.out}">
                <fileset dir="${test.src}">
                    <include name="**/*Test.java"/>
                </fileset>
            </batchtest>
        </junit>
        <junitreport todir="${junit.out}">
            <fileset dir="${junit.out}">
                <include name="TEST-*.xml"/>
            </fileset>
            <report todir="${junit.out}" format="frames"/>
        </junitreport>
    </target>

    <taskdef resource="testngtasks" classpathref="testng.class.path"/>
    <target name="testng-test" description="run all testng tests" depends="compile">
        <!-- Debug output
                <property name="test.class.path" refid="test.class.path"/>
                <echo message="${test.class.path}"/>
        -->
        <testng classpathref="test.class.path" outputDir="${testng.out}" haltOnFailure="${haltonfailure}" verbose="2" parallel="methods" threadcount="50">
            <classfileset dir="${out}/test/${ant.project.name}" includes="**/*.class"/>
        </testng>
    </target>

    <target name="exploded" description="create exploded deployment" depends="testng-test">
        <copy todir="${exploded.classes}">
            <fileset dir="${production.classes}"/>
        </copy>
        <copy todir="${exploded.lib}">
            <fileset dir="${production.lib}"/>
        </copy>
    </target>

    <target name="package" description="create package file" depends="exploded">
        <jar destfile="${out}/${ant.project.name}.jar" basedir="${production.classes}" includes="**/*.class"/>
    </target>

</project>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM