3.5 Using Environment Variables

3.5.1 Problem

You want to obtain and use environment variables within Ant. This is a way to avoid hardcoding values in buildfiles.

3.5.2 Solution

Use a special form of the <property> task:[1]

[1] This technique only works with Ant 1.3 and later.

<?xml version="1.0"?>
<project name="envSample" default="deploy" basedir=".">
  <!-- Set up the 'env' prefix for environment variables -->
  <property environment="env"/>

  <!-- Abort the build if TOMCAT_HOME is not set -->
  <target name="checkTomcatHome" unless="env.TOMCAT_HOME">
    <fail message="TOMCAT_HOME must be set!"/>
  </target>

  <target name="compile">
    ... compile the code
  </target>

  <!-- Deploy the WAR file to TOMCAT_HOME/webapps -->
  <target name="deploy" depends="checkTomcatHome,compile">
    <echo>Deploying to ${env.TOMCAT_HOME}</echo>
    <copy file="myapp.war" todir="${env.TOMCAT_HOME}/webapps"/>
  </target>

</project>

3.5.3 Discussion

Although most operating systems support the concept of environment variables, not all do. As a result, Sun deprecated Java's System.getEnv( ) method, which used to return the values of environment variables. Undeterred by this restriction, Ant's programmers added the ability to obtain environment variables using the technique shown here.

Use the property task's environment attribute to define a prefix, conventionally "env". Then use this prefix when referencing environment variables in other parts of a buildfile, as if you are referencing any normal Ant property. Our example Ant buildfile uses the TOMCAT_HOME environment variable to deploy a Web Application Archive (WAR) file to the correct directory.

Our example takes this technique to the next level by verifying that TOMCAT_HOME is actually set before attempting to deploy the WAR file. This is done in the checkTomcatHome target:

<target name="checkTomcatHome" unless="env.TOMCAT_HOME">
  <fail message="TOMCAT_HOME must be set!"/>
</target>

Any other target requiring TOMCAT_HOME should list checkTomcatHome as a dependency:

<target name="deploy" depends="checkTomcatHome,compile">

Environment variables should be used sparingly, but are particularly valuable when deploying to servers like Tomcat that might be installed in different locations depending on who is running the buildfile.

Portability is the main limitation with this technique. Since the underlying Java libraries no longer support System.getEnv( ), Ant must rely on Runtime.exec( ) to execute platform-specific commands when obtaining environment variables. While this is supported for Unix, Windows, and several other operating systems, you should definitely test things out if your buildfiles must run on some other platform.

Properties Files

An alternative to both environment variables, and the system properties approach described in Recipe 3.6 is a properties file that each developer uses to tell the build process about their environment. You might want to name the file local.properties. Advantages include:

  • All developer-specific settings are in one placeit's a file you don't check in to source control.

  • It's cross-platform.

  • It's easy to edit, and the settings "stay put."

  • It's easy for two or more developers to diff their settings.

You load it with <property file="local.properties">.

3.5.4 See Also

See the Ant user manual for the property core task.