|
7.1. Executing Java CodeThe java task is part of Ant's core functionality; it executes a Java class in the current JVM, or forks another JVM and runs the class in the new JVM. You can recover the exit code of the Java class and stop the build if the build results you're testing create an error. Here's an example using this task. Say you have this code, Project.java, which reads what the user enters on the command line and displays it: public class Project { public static void main(String args[]) { System.out.println("You said: " + args[0]); System.exit(0); } } After compiling this code you can run it with the java task by setting up the classpath with a classpath element and passing a command-line argument, "OK", in a nested arg element. The build file appears in Example 7-1. Example 7-1. Using the java task (ch07/java/build.xml)<?xml version="1.0" ?> <project default="main"> <property name="src" location="source" /> <property name="output" location="bin" /> <property environment="env" /> <target name="main" depends="init, compile, run"> <echo> Building and running.... </echo> </target> <target name="init"> <mkdir dir="${output}" /> </target> <target name="compile"> <javac srcdir="${src}" destdir="${output}" /> </target> <target name="run" failonerror="true"> <java classname="Project" fork="true" > <classpath> <pathelement location="${output}"/> </classpath> <arg value="OK" /> </java> </target> </project> Here's what you see when you run this build file; the code ran without problem and recovered the command-line argument passed to it: %ant Buildfile: build.xml init: [mkdir] Created dir: /home/steven/ch07/bin compile: [javac] Compiling 1 source file to /home/steven/ch07/bin run: [java] You said: OK main: [echo] [echo] Building and running.... [echo] BUILD SUCCESSFUL Total time: 4 seconds The many attributes for this task appear in Table 7-1.
The java task supports a number of nested elements, many of which are the same as the javac task. You can use arg elements to pass arguments to Java and jvmarg elements to specify arguments to a forked JVM. Nested sysproperty elements specify system properties required by the class you're running. As of Ant 1.6, you can use syspropertyset elements, which specify a set of properties to be used as system properties. The java task supports nested classpath elements, which you can use to specify a classpath to use when Java runs, and supports as bootclasspath elements (since Ant 1.6) to set the location of bootstrap class files. You can use env elements (see Table 7-3) to specify environment variables to pass to the forked JVM and nested permissions elements. As with the javac task, permissions represents a set of security permissions granted to the code in the JVM where Ant is running. Since Ant 1.6, you can use nested assertions elements to support Java 1.4 assertions. 7.1.1. Handling Errors and Return CodesBy default, the return code of the java task is ignored. If you want to check the return code, you can set the resultproperty attribute to the name of a property and have the result code assigned to it. For example, say your code returned a non-zero value: public class Project { public static void main(String args[]) { System.out.println("You said: " + args[0]); System.exit(1); } } You can test the return code from a forked JVM and explicitly fail unless it's 0 this way: <target name="run"> <java classname="Project" fork="true" resultproperty="return.code"> <classpath> <pathelement location="${output}"/> </classpath> <arg value="OK" /> </java> <condition property="problem"> <not> <equals arg1="${return.code}" arg2="0"/> </not> </condition> <fail if="problem" message="Failed: ${return.code}" /> </target> Here's the result. The java task indicates a nonzero return code and the build was terminated by the fail task: %ant build.xml Buildfile: build.xml init: [mkdir] Created dir: /home/steven/ch07/bin compile: [javac] Compiling 1 source file to /home/steven/ch07/bin run: [java] You said: OK [java] Java Result: 1 BUILD FAILED /home/steven/ch07/build2.xml:35: Failed: 1 Total time: 4 seconds You can set failonerror="true" in the java task, in which case the only possible value for resultproperty is 0, or the build will terminate. That's how the example in the previous topic was written: <target name="run" failonerror="true"> <java classname="Project" fork="true" > <classpath> <pathelement location="${output}"/> </classpath> <arg value="OK" /> </java> </target>
Making a build fail if there's an error when you run the build's output is a perfect way to test the results of a build; if the output doesn't run as it should, there's no sense in deploying it. Setting failonerror to true in the java task ensures your build will halt before deployment if the results don't work. Here's another example using the java task, which forks a JVM and runs a .jar file in 512 Megabytes of memory, using the entry point indicated by the manifest: <java jar="${bin}/connect.jar" fork="true" failonerror="true" maxmemory="512m" > <arg value="-q"/> <classpath> <pathelement location="${bin}/connect.jar"/> <pathelement path="${java.class.path}"/> </classpath> </java> This example passes on a system property and an argument to the JVM: <java classname="Project.main" fork="true" > <sysproperty key="DEBUG" value="true"/> <arg value="-z"/> <jvmarg value="-enableassertions"/> <classpath> <pathelement location="${bin}/**"/> </classpath> </java> As you can see, there are a great many options when running Java code. |
|