Powered by SmartDoc

Ant

Ant の概要

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を動かすためには、適当なディレクトリにインストールした後に、次の手順が必要です。

AntをWindows上のc:\antにインストールするとします。その場合、次のように設定をする必要があります。

set ANT_HOME=c:\ant
set JAVA_HOME=c:\j2sdk1.4.2
set PATH=%PATH%;%ANT_HOME%\bin

build.xml の記述

Antでは、処理内容を記述したファイルをXMLで記述します。デフォルトでは"build.xml"というファイル名になります。

ここでは、jp.ac.wakhok.tomoharu.csvパッケージに属するCSVLine.javaとCSVTokenizer.javaという2つのファイルについて、次のような処理をAntで実行してみます。

まずは準備として、src/jp/ac/wakhok/tomoharu/csvディレクトリに2つのソースファイルを置いておきます。build.xmlを見てみましょう。

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が複数含まれています。

property

project要素の直下に、要素propertyが設定されています。propertyは名前と値のペアになっており、"srcDir"という名前のpropertyは、

 ${srcDir}

と記述することで名前を参照できます。

task

taskは、処理の最小単位です。Antでは、さまざまな種類のtaskが標準で組みこまれています。この例では、次のtaskが実行されています。

いずれも、Javaプログラマにとっては馴染み深いものですね。最後のtstampは、現在の日時の情報をDSTAMP, TSTAMP, TODAYといったプロパティに設定するためのタスクです。他にも、CVSリポジトリにアクセスしたり、メールを送信したりするようなtaskもあります。

例えば、javacというtaskは次のような構成になっています。

<javac srcdir="${srcDir}" destdir="${classDir}" />

javacはソースファイルのコンパイルを行うタスクです。srcdir属性がソースファイルのありかを示し、destdir属性がクラスファイルの生成先のディレクトリを示しています。

target と依存関係

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 を動かす

antを実行するには、build.xml (もしくは他の設定ファイル)があるディレクトリに移動して

C:\> ant

と実行するだけです。引数を指定せずにantコマンドを実行した場合、デフォルトのtargetが実行されます。デフォルトのtargetは、project要素のdefault属性で指定できます。この場合は、"all"というtargetになります。

<project name="csv" default="all" basedir=".">
  ...
</project>

特定のtargetのみ処理したい場合は

C:\> ant javadoc

のように、targetの名前を引数に取ります。

参考文献・URL

Apache Ant
Apache Ant 1.5マニュアル