Apache Antを使う

Apache Antは、 オープンソースで開発されているビルドツールです。 身もふたもない言い方をすれば「makeのJava版」ということになりますが、

  • 純粋Javaで書かれているので、動作がプラットフォームに依存しない
  • Makefileの代わりに「build.xml」という、XML形式のビルドファイルを書く
という特徴があります。

インストール

  1. バイナリ配布を入手して、展開します。 「apache-ant-1.5.3-bin」のような名前のディレクトリができるので、 これをUNIXの場合は/usr/localなどに、Windowsの場合は好きな場所に移動します。 antという名前に変えたり、シンボリックリンクを張ってもよいでしょう。 binサブディレクトリに、Windows用にはant.batというバッチファイルがあるので、これを使います。 実行時にant.batのフルパスを打つのでよければ、 このディレクトリ(bin)にPATHを通しておく必要は、必ずしもありません。
  2. 使うユーザのログインシェルで、 環境変数JAVA_HOME に、Java VMのインストールディレクトリを指定する必要があります。
以下にUNIXの場合のコマンドラインの例を示します。

cd /usr/local
tar xozf /install/temp/directory/of/apache-ant-1.5.3-bin.tar.gz
ln -s apache-ant-1.5.3-bin ant

export JAVA_HOME=/usr/local/j2sdk1.4.1_02

最初のサンプル
 最初は次のようなディレクトリ構成を考えます。

/top --- /src --- /ushi --- A.java
      |                  +- B.java
      |                  +- C.java
      +- /ushi -- A.class
      |        +- B.class
      |        +- C.class
      +- build.xml

 ここで、A,B,Cはそれぞれushi.A、ushi.B、ushi.Cというクラスのソースファイルです。 この上の図の位置に、次のようにビルドファイルbuild.xmlを作ります。

<project name="HelloWorldBuild" default="compile" basedir=".">
  <property name="src" value="./src" />
  <property name="classes" value="." />
  <property name="classpath" value="." />

  <target name="compile">
  <javac srcdir="${src}" destdir="${classes}">
  <classpath>
    <pathelement path="${classpath}" />
    <pathelement location="c:/wintools/j2ee131/lib/j2ee.jar" />
  </classpath>
  </javac>
  </target>
</project>

 これだけの指定で、src/ushiディレクトリの下にあるA.java、B.java、C.javaをコンパイルして、 直下のushiディレクトリにclassファイルを作成してくれます。便利、便利。 なお、classパスタグのpath=はパス(ディレクトリ)を、 location=特定のファイル(JARファイル)を指定するのに使うのが普通とのことです。

 ちなみに、ビルドファイルの中には<!-- 〜 -->タグで囲んでコメントを書くことができますが、 日本語のコメントを書く場合には文字コードをUTF-8にしなくてはいけません。 UTF-8で保存できるテキストエディタを用意するとよいでしょう。 私はWindows環境ではどちらもフリーウェアの、TeraPadやxyzzyを使っています。

 ではこのbuild.xmlを使って、早速ビルドしてみます。

DOS> C:\wintools\ant\bin\ant

UNIXの場合も

% /usr/local/ant/bin/ant

 引数を何も指定しないと、カレントディレクトリにあるbuild.xml をビルドファイルとして読み、その最初のターゲットを構築しようとします。 ビルドファイルの名前がbuild.xml以外の場合は、 「-f buildfile」オプションをつけます。 また、ビルド対象のターゲットを指定したい場合には、 その名前(targetタグの属性nameの値)をコマンドラインで指定します。
また、バッチ処理で実行するなどの目的で、実行ログを残したい場合には、 「-logfile ログファイル名」とすればOKです。

デバッグオプション
ところで、Antを利用してjavacすると、デフォルトで最適化モードでコンパイルが実行されます。 これによって、デバッグ情報がカットされてしまうので、 例えば例外が発生した際にException#printStackTrace()で出力できるスタックトレースで、 どの行で例外が発生したかが分かりません (「Unknown Source」と表示される)。 普通のモード、つまりどの行で例外が発生したかが分かるようにするには、 「debug="on" optimize="off"」をつけます。

<target name="compile">
<javac srcdir="${src}" destdir="${classes}" debug="on" optimize="off">
<classpath>
...

Antとバッチファイル
Windowsではantコマンド自身もバッチファイルなので、 バッチファイルの中でantコマンドを呼ぶと、その時点で呼び出し元のバッチファイルも終了してしまいます。 call文で呼び出すのがポイントです。

@echo off
call C:\wintools\ant\bin\ant -logfile runant.log compile
call C:\wintools\ant\bin\ant -logfile runantjar.log jar

もうちょっと便利な環境を作ってみよう
 今度は、ディレクトリのクリアー(make cleanみたいなもの) と、ビルドしたクラスファイルをjarアーカイブに圧縮する作業もAntで自動化してみます。
 ディレクトリ構成ですが、今度は前と少し変えて、 Borland JBuilderのプロジェクトのデフォルト設定と同じく、 ソースファイルがプロジェクトディレクトリ直下にあって、 ビルドしたクラスファイルがサブディレクトリclassesの下に置かれる、 というツリーにしてみます。フリップをもちいて説明すると、下のよーになります。

/top --- /ushi ------ A.java
      |            +- B.java
      |            +- C.java
      +- /classes --- /ushi --- A.class
      |                      +- B.class
      |                      +- C.class
      +- build.xml

<project name="HelloWorldBuild" default="compile" basedir=".">
  <property name="src" value="." />
  <property name="classes" value="classes" />
  <property name="classpath" value="." />
  <property name="jar" value="ushitag.jar" />

  <target name="prepare">
    <mkdir dir="${classes}"/>
  </target>

  <target name="compile" depends="prepare">
  <javac srcdir="${src}" destdir="${classes}">
  <classpath>
    <pathelement path="${classpath}" />
  </classpath>
  </javac>
  </target>

  <target name="jar" depends="compile">
    <jar jarfile="${jar}" basedir="${classes}" />
  </target>

  <target name="clean">
    <delete dir="${classes}" />
  </target>
</project>

 今度はターゲットの数が4つに増えています。 が、今回もビルドの中心になるコンパイルはターゲット「compile」 で行っています。targetタグのdepends依存関係を表すもので、 この例だと、ターゲットjarはcompileに、compileはprepareに依存していますから、 jarをターゲットにビルドがかかると、 自動的に依存関係が逆向きに辿られ、prepare、compile、jar がこの順番にビルドされることになります。 jarタグはbasedir=で指定したディレクトリ以下に含まれる .classファイルをjarfile=で指定した名前のJARアーカイブに圧縮する命令です。 deleteタグはdir=を指定するとそのディレクトリを削除します。 delete dir=を使うと中に含まれるファイルだけでなく、 このディレクトリ自体も削除される点に注意してください。 このため、一度cleanした後、再度ビルドを行うには、 まずコンパイルするより先にclassesディレクトリを作っておかなければいけません。 これが、prepareターゲットでmkdirタグでディレクトリを作っている理由、 というわけです。

Javadocを使う
 J2SE SDKについているドキュメント生成ツール、 javadocを呼び出すことも簡単にできます。

<target name="javadoc">
  <delete dir="${javadoc}" />
  <mkdir dir="${javadoc}" />
  <javadoc sourcepath="${source}" packagenames="${PACKAGE}" destdir="${javadoc}" />
</target>

CLASSPATHの設定もできます。

<target name="ushidoc">
  <!--
  <delete dir="${docdir}" />
  <mkdir dir="${docdir}" />
  -->
  <javadoc sourcepath="." destdir="./ushidoc"
   packagenames="ushi.jdbc, ushi.jdbc.loader, ushi.jdbc.config, ushi.ldap,
                 ushi.svf, ushi.svt, ushi.ui, ushi.util, ushi.wui, ushi.xmlparser">
  <classpath>
    <pathelement path="${classpath}" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/commons-fileupload.jar" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/commons-logging.jar" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/commons-collections.jar" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/commons-dbcp.jar" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/commons-pool.jar" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/commons-beanutils.jar" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/mail.jar" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/smtp.jar" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/activation.jar" />
    <pathelement location="c:/jdk1.4/jre/lib/ext-sleep/pop3.jar" />
    <pathelement location="c:/Wintools/Tomcat4.1/common/lib/servlet.jar" />
  </classpath>
  </javadoc>
</target>

Javaアプリケーションを実行する
 また、javaコマンドを使って、JavaアプリケーションをAntから実行させることもできます。 これは下の例のように、 CLASSPATHを大量に設定する必要があるJavaアプリケーションを実行したいときに便利です。

  <property name="JAVALIBDIR" value="C:/usr/java/lib" />
  <property name="classpath" value="." />

  <target name="call.WSDL2java">
  <java classname="org.apache.axis.wsdl.WSDL2Java" fork="yes">
  <classpath>
    <pathelement path="${classpath}" />
    <pathelement location="${JAVALIBDIR}/axis.jar" />
    <pathelement location="${JAVALIBDIR}/commons-discovery.jar" />
    <pathelement location="${JAVALIBDIR}/commons-logging.jar" />
    <pathelement location="${JAVALIBDIR}/jaxrpc.jar" />
    <pathelement location="${JAVALIBDIR}/saaj.jar" />
    <pathelement location="${JAVALIBDIR}/wsdl4j.jar" />
  </classpath>
  <arg value="-o" />
  <arg value="src" />
  <arg value="-p" />
  <arg value="ushiws.shiten" />
  <arg value="-s" />
  <arg value="-d" />
  <arg value="Application" />
  <arg value="ShitenFinder.wsdl" />
  </java>
  </target>

この例では、org.apache.axis.wsdl.WSDL2Java というクラスのmainメソッドを実行しています。 fork="yes"はAntとは別プロセスで実行させる指示です。 それで、argタグで、コマンドライン引数を1つずつ指定します。 つまりこの例では、 「java org.apache.axis.wsdl.WSDL2Java -o src -p ushiws.shiten -s -d Application ShitenFinder.wsdl」 というコマンドラインで実行される、というわけです。

なお、さらに大量のJARファイルをCLASSPATHに設定したい場合には、 以下のようにfileset要素を使うと、ディレクトリ内のJARを全て登録することができます。 ディレクトリもたくさんある、という極道な場合には、dirsetという要素もあるので、 組み合わせることで短い記述で大量のCLASSPATHを生み出すことができます。

  <target name="call.groovy">
  <java classname="groovy.ui.GroovyMain" fork="yes">
  <classpath>
    <pathelement path="${classpath}" />
    <pathelement location="${GROOVY_HOME}/groovy-1.0.jar" />
    <fileset dir="${GROOVY_HOME}/lib">
      <include name="**/*.jar" />
    </fileset>
    <pathelement location="${HSQLDBLIBDIR}/hsqldb.jar" />
    <pathelement location="${TOMCATLIBDIR}/ushi.jar" />
  </classpath>
  <arg value="asserttool.gv" />
  </java>
  </target>

ファイル・ディレクトリをコピーする
 開発環境から実行ディレクトリへファイルをインストールするなどの目的で、 Antタスクとしてファイルやディレクトリをコピーすることができます。

  <target name="install-jar" depends="jar">
    <copy file="./example.jar" todir="C:/usr/javadeploy/app11/WEB-INF/lib"/>
  </target>

  <target name="install" depends="jar">
    <copy todir="C:/usr/javadeploy/app11/WEB-INF/classes">
      <fileset dir="./classes" />
    </copy>
  </target>

 上の「install-jar」ターゲットがファイルをコピーする例、 下の「install」ターゲットがディレクトリをコピーする例です。 todirはファイルやディレクトリをコピーする先のディレクトリです。 上の例では C:/usr/javadeploy/app11/WEB-INF/lib/example.jar というファイルが作られます。 下の例で、コピー元を./classesとしていますが、 これはこのディレクトリの中に入っているファイルやディレクトリ がコピー対象という意味です。 このディレクトリがtodirの下にコピーされるわけではないので、注意が必要です。
 なお、fileset要素の属性includeやexcludeで、 コピー対象のファイルを限定したり、除外したりすることができます。

プロパティをコマンドラインからセットする
 Java VMでAntにJavaアプリケーションを実行するなどの場合に、 build.xml中のプロパティをAntコマンドラインから動的に指定するには、 -Dオプションを使用します。

~/java/ant/bin/ant -f build-dev.xml MyApp -DfileName=test.dat

このように指定すると、build.xml中のプロパティ"fileName"に、値"test.dat"がセットされます。

Java kowaza Top

(first uploaded 2003/01/13 last updated 2007/05/02, URANO398)

テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル