Antは、Javaのプログラムのコンパイルや実行を手助けをしてくれるツールです。Antを使うことによって、コンパイルや実行のときに必要なJarファイルやオプションの指定が楽にできます。
こうしたツールは「ビルドツール」と呼ばれます。AntはJavaでできているビルドツールです。UNIXの世界では、代表的なビルドツールとしてmakeがあり、Antも同様の機能を持っています。
makeのようなビルドツールは、そもそもOSなどの環境に依存しているところがあります。makeはUNIXのシェルがベースとなっているので、なおさらです。「Write Once, Run Anywhere」を標榜するJavaとしては、こうした環境依存のツールを使うと、不便な点が多く出てきます。
Antは、Javaで書かれているので、こうした心配はありません。またmakeでのMakefileのような、処理内容を記述するファイルはXMLで書かれていますので、わかりやすくなっています。Makefileを編集した経験がある人なら、Makefileのタブや空白に悩まされた経験を持つ人も多いでしょう。
その反面、makeのようにシェルをベースとしていないので、できる処理に限りがあるという欠点もあります。
Antは、Tomcatを作っているJakarta Projectによって作成されています。(http://ant.apache.org/)
Antを動かすためには、適当なディレクトリにインストールした後に、次の手順が必要です。
AntをWindows上のc:\antにインストールするとします。その場合、次のように設定をする必要があります。
set ANT_HOME=c:\ant set JAVA_HOME=c:\j2sdk1.4.2 set PATH=%PATH%;%ANT_HOME%\bin
Antでは、処理内容を記述したファイルをXMLで記述します。デフォルトでは"build.xml"というファイル名になります。
ここでは、jp.ac.wakhok.tomoharu.csvパッケージに属するCSVLine.javaとCSVTokenizer.javaという2つのファイルについて、次のような処理をAntで実行してみます。
まずは準備として、src/jp/ac/wakhok/tomoharu/csvディレクトリに2つのソースファイルを置いておきます。build.xmlを見てみましょう。
<?xml version="1.0"?>
<project name="csv" default="all" basedir=".">
<property name="srcDir" value="src" />
<property name="classDir" value="classes" />
<property name="packageName"
value="jp.ac.wakhok.tomoharu.csv" />
<property name="apiDocsDir" value="docs/api" />
<target name="init">
<tstamp/>
</target>
<target name="compile" depends="init">
<mkdir dir="${classDir}" />
<javac srcdir="${srcDir}"
destdir="${classDir}" />
</target>
<target name="jar" depends="compile">
<jar jarfile="csv.jar"
basedir="${classDir}" />
</target>
<target name="javadoc" depends="init">
<mkdir dir="${apiDocsDir}" />
<javadoc packagenames="jp.ac.wakhok.tomoharu.csv"
sourcepath="${srcDir}"
destdir="${apiDocsDir}" />
</target>
<target name="all" depends="jar, javadoc">
<zip zipfile="../csv.zip" basedir=".."
includes="csv/**"
excludes="**/classes/**" />
</target>
</project>
build.xmlの中には、要素projectが1つだけ含まれています。要素projectの中には複数の要素targetが含まれています。targetの中には、処理の最小単位である要素taskが複数含まれています。
project要素の直下に、要素propertyが設定されています。propertyは名前と値のペアになっており、"srcDir"という名前のpropertyは、
${srcDir}
と記述することで名前を参照できます。
taskは、処理の最小単位です。Antでは、さまざまな種類のtaskが標準で組みこまれています。この例では、次のtaskが実行されています。
いずれも、Javaプログラマにとっては馴染み深いものですね。最後のtstampは、現在の日時の情報をDSTAMP, TSTAMP, TODAYといったプロパティに設定するためのタスクです。他にも、CVSリポジトリにアクセスしたり、メールを送信したりするようなtaskもあります。
例えば、javacというtaskは次のような構成になっています。
<javac srcdir="${srcDir}" destdir="${classDir}" />
javacはソースファイルのコンパイルを行うタスクです。srcdir属性がソースファイルのありかを示し、destdir属性がクラスファイルの生成先のディレクトリを示しています。
targetは複数のtaskをまとめてグループにしています。この例では、"compile"というname属性を持つtargetには、ディレクトリを作成するmkdirというtaskと、コンパイルを実行するjavacというtaskが含まれています。
targetは他のtargetに依存できます。ここでは、"compile"は"init"に依存しています。この場合、先に"init"の処理をしてから"compile"のtaskが実行されます。Antでは、targetを明示的に指定して実行できます。この場合、そのtargetの依存関係を順にたどり、もっとも優先される処理から実行されます。
Antでは、ファイルやディレクトリを指定するときに、WindowsやUnixでお馴染みのスタイルのパターンを利用できます。
*.java .java や a.java にマッチ。a.xml にはマッチしない。 ?.java b.java にマッチ。
"*"は、0個以上の文字にマッチします。また、"?"は、1個の文字にマッチします。
またこのサンプルには、次のような記述があります。
includes="csv/**"
"**"はすべての階層のファイル・ディレクトリにマッチします。この例では、csv以下のすべてのファイル・ディレクトリにマッチします。
build.xmlの例をもう一つ紹介しましょう。このbuild.xmlでは、環境変数で指定されたディレクトリにあるたくさんのjarファイルをクラスパスに設定し、プログラムのコンパイルと実行を行っています。
<?xml version="1.0"?>
<project name="Google Web API Sample" default="compile" basedir=".">
<property environment="env"/>
<property name="jaxrpc.home" value="${env.JWSDP_HOME}/jaxrpc"/>
<property name="jaxp.home" value="${env.JWSDP_HOME}/jaxp"/>
<property name="jaxr.home" value="${env.JWSDP_HOME}/jaxr"/>
<property name="saaj.home" value="${env.JWSDP_HOME}/saaj"/>
<property name="jaxb.home" value="${env.JWSDP_HOME}/jaxb"/>
<property name="shared.lib" value="${env.JWSDP_HOME}/jwsdp-shared/lib"/>
<property name="common.lib" value="${env.JWSDP_HOME}/common/lib"/>
<property name="common.endorsed" \
value="${env.JWSDP_HOME}/common/endorsed"/>
<path id="wspack.classpath">
<!-- JAXRPC jars -->
<pathelement location="${jaxrpc.home}/lib/jaxrpc-api.jar"/>
<pathelement location="${jaxrpc.home}/lib/jaxrpc-impl.jar"/>
<pathelement location="${jaxrpc.home}/lib/jaxrpc-spi.jar"/>
<!-- JAXP jars -->
<pathelement location="${jaxp.home}/lib/jaxp-api.jar"/>
<pathelement location="${jaxp.home}/lib/endorsed/xercesImpl.jar"/>
<pathelement location="${jaxp.home}/lib/endorsed/sax.jar"/>
<pathelement location="${jaxp.home}/lib/endorsed/dom.jar"/>
<pathelement location="${jaxp.home}/lib/endorsed/xalan.jar"/>
<!-- JAXR jars -->
<pathelement location="${jaxr.home}/lib/jaxr-api.jar"/>
<pathelement location="${jaxr.home}/lib/jaxr-impl.jar"/>
<!-- SAAJ jars -->
<pathelement location="${saaj.home}/lib/saaj-api.jar"/>
<pathelement location="${saaj.home}/lib/saaj-impl.jar"/>
<!-- JAXB jars -->
<pathelement location="${jaxb.home}/lib/jaxb-api.jar"/>
<pathelement location="${jaxb.home}/lib/jaxb-impl.jar"/>
<pathelement location="${jaxb.home}/lib/jaxb-xjc.jar"/>
<pathelement location="${jaxb.home}/lib/jaxb-libs.jar"/>
<!-- Common jars -->
<pathelement location="${shared.lib}/activation.jar"/>
<pathelement location="${shared.lib}/mail.jar"/>
<pathelement location="${shared.lib}/commons-logging.jar"/>
<pathelement location="${shared.lib}/jax-qname.jar"/>
<pathelement location="${shared.lib}/xsdlib.jar"/>
<pathelement location="${shared.lib}/relaxngDatatype.jar"/>
<pathelement location="${shared.lib}/namespace.jar"/>
<!-- Servlet jar -->
<pathelement location="${jwsdp.home}/common/lib/servlet-api.jar"/>
<!-- current directory -->
<pathelement location="."/>
</path>
<target name="init">
<tstamp/>
</target>
<target name="compile" depends="init">
<javac srcdir=".">
<include name="*.java" />
<classpath>
<path refid="wspack.classpath"/>
</classpath>
</javac>
</target>
<target name="run" depends="compile">
<java classname="GoogleSearch" >
<arg value="wakhok"/>
<classpath>
<path refid="wspack.classpath"/>
</classpath>
</java>
</target>
</project>
まず、次のproperty要素で、環境変数を読み込み、envという変数に格納しています。
<property environment="env"/>
次のproperty要素のvalue属性で、${env.JWSDP_HOME}という記述があります。これは、先に環境変数を読み込んだenvという変数を通じて、環境変数JWSDP_HOMEの値を取得しています。ここでは、JWSDP_HOMEの値に"/jaxrpc"という文字列をつけたものを、jaxrpc.homeプロパティの値として設定しています。
<property name="jaxrpc.home" value="${env.JWSDP_HOME}/jaxrpc"/>
次の部分では、たくさんのjarファイルをクラスパスに追加しています。このクラスパスには"wspack.classpath"というidが付けられています。
<path id="wspack.classpath">
<!-- JAXRPC jars -->
<pathelement location="${jaxrpc.home}/lib/jaxrpc-api.jar"/>
<pathelement location="${jaxrpc.home}/lib/jaxrpc-impl.jar"/>
......
</path>
コンパイルや実行のときには、path要素を用いて、クラスパスにwspack.classpathを指定しています。
<target name="compile" depends="init">
<javac srcdir=".">
<include name="*.java" />
<classpath>
<path refid="wspack.classpath"/>
</classpath>
</javac>
</target>
antを実行するには、build.xml (もしくは他の設定ファイル)があるディレクトリに移動して
C:\> ant
と実行するだけです。引数を指定せずにantコマンドを実行した場合、デフォルトのtargetが実行されます。デフォルトのtargetは、project要素のdefault属性で指定できます。この場合は、"all"というtargetになります。
<project name="csv" default="all" basedir="."> ... </project>
特定のtargetのみ処理したい場合は
C:\> ant javadoc
のように、targetの名前を引数に取ります。