Apache Ant

Apache Ant

ダウンロード

プロジェクト参加

質問/Questions
このFAQについて/About this FAQ
一般的な質問/General
インストール/Installation
Ant を使って/Using Ant
Ant と IDEおよびエディタ/Ant and IDEs/Editors
上級者向けの問題/Advanced Issues
既知の問題/Known Problems
回答/Answers
このドキュメントの最新版はどこにありますか / Where do I find the latest version of this document?

The latest version can always be found at Ant's homepage http://ant.apache.org/ant/faq.html.

最新版はいつでも Ant のホームページ http://ant.apache.org/ant/faq.html で見つかります。

どうすれば、このFAQに協力できますか / How can I contribute to this FAQ?

The page you are looking it is generated from this document. If you want to add a new question, please submit a patch against this document to one of Ant's mailing lists; hopefully, the structure is self-explanatory.

ご覧のページはこのドキュメントから生成されています。 新しい質問を加えたい場合には、 このドキュメントに対するパッチを Ant メーリングリストに送ってください; できれば、構造が自明なもので

If you don't know how to create a patch, see the patches section of this page.

パッチの作り方を知らない場合には、このページのパッチの節をご覧ください。

このFAQのHTML版をどうやって生成しますか / How do you create the HTML version of this FAQ?

We use Anakia to render the HTML version from the original XML file.

オリジナルXMLファイルからHTML版をレンダリングするのに Anakia を使っています。

The Velocity stylesheets used to process the XML files can be found in the xdocs/stylesheets subdirectory of Ant's CVS repository - the build file docs.xml is used to drive Anakia. This file assumes that you have the jakarta-site2 module checked out from CVS as well, but if you follow the instruction from Anakia's homepage, you should get it to work without that. Just make sure all required jars are in the task's classpath.

XML ファイルを処理するのに使われる Velocity スタイルシートは Ant CVS リポジトリのxdocs/stylesheets サブディレクトリにあります。- ビルドファイル docs.xml は Anakia を動かすのに使われます。 このファイルでは、 CVS からチェックアウトされた jakarta-site2 モジュールも同様にあると仮定していますが、 Anakia のホームページの指示に従っている場合には、 そのモジュールが無くても動きます。 ただ、全ての必要な jar ファイルがそのタスクのクラスパスにあるかだけ確認してください。

Apache Ant って何ですか / What is Apache Ant?

Ant is a Java-based build tool. In theory, it is kind of like Make, without Make's wrinkles and with the full portability of pure Java code.

AntはJavaベースのビルドツールです。 理論的には、makeの持っているような問題点を持たない、 Pure Java コードの完全なポータビリティーを持つ makeの一種です。

なぜ、これを Ant と呼ぶのですか / Why do you call it Ant?

According to Ant's original author, James Duncan Davidson, the name is an acronym for "Another Neat Tool".

その名前は、 Ant のオリジナルの開発者である James Duncan Davidson によってつけられた、 "Another Neat Tool(別の素敵なツール)"の頭字語です。

Later explanations go along the lines of "ants do an extremely good job at building things", or "ants are very small and can carry a weight dozens of times their own" - describing what Ant is intended to be.

後の説明では、 "Ant は何かを作るときにとてもよく働く"とか、 "Ant はとても小さくて、自分の体重の何倍もの重さのものを運べる" のような説明になり、Ant が何を意図しているのかを説明しています。

Ant の歴史について少し教えてください / Tell us a little bit about Ant's history.

Initially, Ant was part of the Tomcat code base, when it was donated to the Apache Software Foundation. It was created by James Duncan Davidson, who is also the original author of Tomcat. Ant was there to build Tomcat, nothing else.

当初、Ant が Apache Software Foundation に寄贈された時は、 Tomcat のコードの一部でした。 Ant は、Tomcat のオリジナルの開発者でもある James Duncan Davidson によって作られました。 Ant は他のためではなく、Tomcat をビルドするために存在したのです。

Soon thereafter, several open source Java projects realized that Ant could solve the problems they had with Makefiles. Starting with the projects hosted at Jakarta and the old Java Apache project, Ant spread like a virus and is now the build tool of choice for a lot of projects.

それからすぐ後、幾つかのオープンソース Java プロジェクトにより、 Ant が Makefile にあった問題を解決できると気づいたのです。 Jakarta で行われたプロジェクトや古い Java Apache プロジェクトに始まり、 Ant はウィルスのように広がり、 今や、多くのプロジェクトのビルドツールに選ばれました。

In January 2000, Ant was moved to a separate CVS module and was promoted to a project of its own, independent of Tomcat, and became Apache Ant.

2000年1月に Ant は別の CVS モジュールとなり、 Tomcat から独立して、 Ant 単体のプロジェクトに昇進し、 Apache Ant となりました。

The first version of Ant that was exposed to a larger audience was the one that shipped with Tomcat's 3.1 release on 19 April 2000. This version has later been referred to as Ant 0.3.1.

大勢のプログラマに利用された Ant の最初のバージョンは 2000年 4 月 19 日の Tomcat 3.1 リリースで配布されたものでした。 このバージョンは後に Ant 0.3.1 として参照されています。

The first official release of Ant as a stand-alone product was Ant 1.1, released on 19 July 2000. The complete release history:

単体の製品としての Ant の最初の公式リリースは、 2000 年 6 月 19 日にリリースされた Ant 1.1 です。 全リリース履歴は次の通りです:

Ant Version Release Date
1.1 19 July 2000
1.2 24 October 2000
1.3 3 March 2001
1.4 3 September 2001
1.4.1 11 October 2001
Ant バージョン リリース日
1.1 2000 年 6 月 19 日
1.2 2000年10月24日
1.3 2001年3月3日
1.4 2001年9月3日
1.4.1 2001年10月11日
tar.gz配布ファイルから取り出そうとしたら、 チェックサムエラーが出ました。どうしてですか。 / I get checksum errors when I try to extract the tar.gz distribution file. Why?

Ant's distribution contains file names that are longer than 100 characters, which is not supported by the standard tar file format. Several different implementations of tar use different and incompatible ways to work around this restriction.

Ant の配布物には、標準の tar ファイルフォーマットでは サポートされていない 100 文字以上の長さのファイル名が含まれています。 tar の幾つかの異なる実装では、 この制限の扱うために異なる互換性の無い方法を用いています。

Ant's <tar> task can create tar archives that use the GNU tar extension, and this has been used when putting together the distribution. If you are using a different version of tar (for example, the one shipping with Solaris), you cannot use it to extract the archive.

Ant の <tar> タスクは GNU tar の拡張を用いて tar アーカイブを作ることができ、 これは配布物を一まとめにするのに使われています。 違うバージョンの tar (例えば、Solaris で配布される物)を 使っている場合、それはアーカイブを解凍するには使えません。

The solution is to either install GNU tar, which can be found here, or use the zip archive instead (you can extract it using jar xf).

解決策はここにある GNU tar をインストールするか、代わりに zip アーカイブ (jar xfを使って取り出せます)を使うかです。

なぜ Ant は常に自分の Java ファイルを再コンパイルするのですか / Why does Ant always recompile all my Java files?

In order to find out which files should be compiled, Ant compares the timestamps of the source files to those of the resulting .class files. Opening all source files to find out which package they belong to would be very inefficient. Instead, Ant expects you to place your source files in a directory hierarchy that mirrors your package hierarchy and to point Ant to the root of this directory tree with the srcdir attribute.

どのファイルをコンパイルすべきか調べるするために、 Ant はソースファイルとその結果となる.class ファイルのタイムスタンプを比較します。 ソースがどのパッケージに属しているか調べるために全てのソースファイルを開くことは大変非効率です。 その代わりに、Ant では、 自分のソースファイルをパッケージ階層を反映したディレクトリ階層に置き、 Ant がこのディレクトリツリーのルートを srcdir属性により参照することを想定しています。

Say you have <javac srcdir="src" destdir="dest"/>. If Ant finds a file src/a/b/C.java, it expects it to be in package a.b so that the resulting .class file is going to be dest/a/b/C.class.

<javac srcdir="src" destdir="dest"/> があるとしましょう。 Ant はファイル src/a/b/C.java を見つけ、 そのファイルはパッケージa.bにあると仮定し、 結果となる .class ファイルは、 dest/a/b/C.class に置かれるでしょう。

If your source-tree directory structure does not match your package structure, Ant's heuristic won't work, and it will recompile classes that are up-to-date. Ant is not the only tool that expects a source-tree layout like this.

ソースツリーディレクトリ構造がパッケージの構造にマッチしない場合、 Ant のヒューリステックは動作せず、 最新であるクラスでも再コンパイルしてしまいます。 Ant はこのようなソースツリーの配置を想定する唯一のツールではありません。

If you have Java source files that aren't declared to be part of any package, you can still use the <javac> task to compile these files correctly - just set the srcdir and destdir attributes to the actual directory the source files live in and the directory the class files should go into, respectively.

どのパッケージにも属すると宣言されていない Java ソースファイルがある場合でも、 これらのファイルを正しくコンパイルするために <javac>タスクが使えます。- srcdir および destdir属性を ソースファイルのある場所とクラスファイルが出力される場所にそれぞれ設定するだけでよいのです。

自分のビルドファイルにコマンドラインからパラメータを渡すにはどうすればいいですか / How do I pass parameters from the command line to my build file?

Use properties. Using ant -Dname=value lets you define values for properties on the Ant command line. These properties can then be used within your build file as any normal property: ${name} will put in value.

プロパティを使います。 ant -Dname=value を使えば、 Ant のコマンドラインでプロパティの値を定義できます。 これらのプロパティは自分のビルドファイル中で通常のプロパティのように使われます: ${name} は、 valueを登録します。

どうすれば Jikes 固有のコマンドラインスイッチを使えますか / How can I use Jikes-specific command-line switches?

A couple of switches are supported via "magic" properties:

"魔法の"プロパティにより幾つかのスイッチがサポートされています:

switch property default
+E build.compiler.emacs false == not set
+P build.compiler.pedantic false == not set
+F build.compiler.fulldepend false == not set
(Only for Ant < 1.4; replaced by the nowarn attribute of the <javac> task after that.)
-nowarn
build.compiler.warnings true == not set
スイッチ プロパティ デフォルト
+E build.compiler.emacs 設定されない場合false
+P build.compiler.pedantic 設定されない場合false
+F build.compiler.fulldepend 設定されない場合false
(Ant 1.4 より前のみ; それ以降、 <javac>タスクの nowarn属性に置き換えられました。)
-nowarn
build.compiler.warnings 設定されない場合true
コマンドライン引数で < 文字を入れるにはどうすればいいですか / How do I include a < character in my command-line arguments?

The short answer is "Use: &lt;".

手短かな回答は "&lt; を使う"ということです。

The long answer is that this probably won't do what you want anyway (see the next section).

長い回答は、このプロパティではあなたのやりたい事はできないでしょう。 (次の節をご覧ください。)

<exec>タスクの標準入力や標準出力をリダイレクトするにはどうすればいいですか / How do I redirect standard input or standard output in the <exec> task?

Say you want to redirect the standard input stream of the cat command to read from a file, something like:

catコマンドの標準入力を、 あるファイルを読み込むように、次のようにリダイレクトしたいとしましょう::

shell-prompt> cat < foo

and try to translate it into

そしてこれを次のように書き換えたとします。

<exec executable="cat">
  <arg value="&lt;" />
  <arg value="foo" />
</exec>

This will not do what you expect. The input redirection is performed by your shell, not the command itself, so this should read:

これでは、期待したような動作は行われません。 入力のリダイレクトはシェルが行い、 コマンド自身が行うわけではないからです。 ですから、これは次のように読み込まなければなりません:

<exec executable="/bin/sh">
  <arg value="-c" />
  <arg value="cat &lt; foo" />
</exec>

Note that you must use the value attribute of <arg> in the last element, in order to have the command passed as a single, quoted argument. Alternatively, you can use:

シングルクォートされた引数としてコマンドに渡すために、 最後の要素において、 <arg>value属性を使わなければならないことに注意してください。 別の方法として、次のようにすることもできます:

<exec executable="/bin/sh">
  <arg line='-c "cat &lt; foo"'/>
</exec>

Note the double-quotes nested inside the single-quotes.

シングルクォート中で、ネストされたダブルクォートに注意してください。

Ant からバッチファイルやシェルスクリプトを実行するにはどうすればいいですか How do I execute a batch file or shell script from Ant? / How do I execute a batch file or shell script from Ant?

On native Unix systems, you should be able to run shell scripts directly. On systems running a Unix-type shell (for example, Cygwin on Windows) execute the (command) shell instead - cmd for batch files, sh for shell scripts - then pass the batch file or shell script (plus any arguments to the script) as a single command, using the /c or -c switch, respectively. See the above section for example <exec> tasks executing sh. For batch files, use something like:

固有の Unix システム上では、 直接シェルスクリプトを実行できます。 Unix形式のシェルを実行するシステム上 (例えば Windows 上の Cygwin など)では、 (コマンド)シェルを代わりに実行します。- バッチファイルの場合はcmdを実行し、 シェルスクリプトの場合にはshを実行します。 そして、/c あるいは -c スイッチを各々用いて一つのコマンドとして、 バッチファイルやシェルスクリプト (およびスクリプトの引数)を渡すのです。 shを実行する <exec>タスクの例として 上の節をご覧ください。 バッチファイルの場合、次のように使います:

<exec dir="." executable="cmd" os="Windows NT">
  <arg line="/c test.bat"/>
</exec>
不必要な SourceSafe コントロールファイル (CVSファイル、エディタのバックアップファイルなど)を削除するために <delete>タスクを使いましたが、 動作しないようです; ファイルは削除されません。何が悪いのでしょう。 / I've used a <delete> task to delete unwanted SourceSafe control files (CVS files, editor backup files, etc.), but it doesn't seem to work; the files never get deleted. What's wrong?

This is probably happening because, by default, Ant excludes SourceSafe control files (vssver.scc) and certain other files from FileSets.

これはおそらく、Ant がデフォルトで SourceSafe の制御ファイル (vssver.scc) や他のあるファイルをファイルセットから除外してしまうために起こります。

Here's what you probably did:

おそらく、あなたはこのようにしたのでしょう:

n
<delete>
  <fileset dir="${build.src}" includes="**/vssver.scc"/>
</delete>

You need to switch off the default exclusions, and it will work:

デフォルト除外集合のスイッチをオフにすれば、動くでしょう:

<delete>
  <fileset dir="${build.src}" includes="**/vssver.scc"
           defaultexcludes="no"/>
</delete>

For a complete listing of the patterns that are excluded by default, see the user manual.

デフォルトで除外されるパターンの全一覧は、 ユーザマニュアルをご覧ください。

複数の条件が true になった時のみ、 特定のターゲットを実行したいのです。 / I want to execute a particular target only if multiple conditions are true.

There are actually several answers to this question.

この質問には実際に幾つかの答えがあります。

If you have only one set and one unset property to test, you can specify both an if and an unless attribute for the target, and they will act as if they are "anded" together.

条件判定で真の時実行されるプロパティと偽の時実行されるプロパティが それぞれ一つしかない場合、 ターゲットに対し、 if および unless のプロパティの双方を指定することができます。 そして、それらの条件の "AND" がとられます。

If you are using a version of Ant 1.3 or earlier, the way to work with all other cases is to chain targets together to determine the specific state you want to test for.

使用している Ant のバージョンが 1.3 以前ならば、 全てのほかのケースで動作させる方法は、 条件判定したい特定の状態を決定するターゲットを繋げることです。

To see how this works, assume you have three properties: prop1, prop2, and prop3. You want to test that prop1 and prop2 are set, and that prop3 is not. If the condition holds true you want to echo "yes".

これがどのように動作するのか示すために、 3つのプロパティを仮定します: prop1prop2prop3です。。 prop1 および prop2 が設定されており、 prop3 が設定されていないことを判定したいとします。 この条件が真である時、"yes"と出力したとします。

Here is the implementation in Ant 1.3 and earlier:

以下が Ant 1.3 以前での実装です:

<target name="cond" depends="cond-if"/>

<target name="cond-if" if="prop1">
  <antcall target="cond-if-2"/>
</target>

<target name="cond-if-2" if="prop2">
  <antcall target="cond-if-3"/>
</target>

<target name="cond-if-3" unless="prop3">
  <echo message="yes"/>
</target>

Note: <antcall> tasks do not pass property changes back up to the environment they were called from, so you would'nt be able to, for example, set a result property in the cond-if-3 target, then do <echo message="result is ${result}"/> in the cond target.

注意: <antcall> タスクは、 タスクが呼ばれた環境をバックアップして、 プロパティの変更を渡さないことに注意してください。 従って、例えば、 cond-if-3 ターゲットにおいて、 result プロパティを設定し、 それから、 cond ターゲットにおいて、 <echo message="result is ${result}"/> を行うといったことはできないでしょう。

Starting with Ant 1.4, you can use the <condition> task.

Ant 1.4 より、<condition> タスクが使えます。

<target name="cond" depends="cond-if,cond-else"/>

<target name="check-cond">
  <condition property="cond-is-true">
    <and>
      <not>
        <equals arg1="${prop1}" arg2="$${prop1}" />
      </not>
      <not>
        <equals arg1="${prop2}" arg2="$${prop2}" />
      </not>
      <equals arg1="${prop3}" arg2="$${prop3}" />
    </and>
  </condition>
</target>

<target name="cond-if" depends="check-cond" if="cond-is-true">
  <echo message="yes"/>
</target>

<target name="cond-else" depends="check-cond" unless="cond-is-true">
  <echo message="no"/>
</target>

This version takes advantage of two things:

この方法には2つの利点があります:

  • If a property a has not been set, ${a} will evaluate to ${a}.
  • プロパティ a が設定されなかった場合、 ${a}${a} を評価します。
  • To get a literal $ in Ant, you have to escape it with another $ - this will also break the special treatment of the ${ sequence.
  • Ant の $ リテラルを得るには、 もう一つ$ をつけてエスケープしなければなりません。- このエスケープは${ シーケンスの特別な扱いも無効にします。

Because testing for a literal ${property} string isn't all that readable or easy to understand, post-1.4.1 Ant introduces the <isset> element to the <condition> task.

リテラル ${property} の文字列は、 それほど読みやすくなく、理解しやすくないので、 Ant 1.4.1 の後では、 <condition>タスクにおいて、 <isset> 要素を使えるようにしました。

Here is the previous example done using <isset>:

これは、<isset>を使った前の例と同じものです:

<target name="check-cond">
  <condition property="cond-is-true">
    <and>
      <isset property="prop1"/>
      <isset property="prop2"/>
      <not>
        <isset property="prop3"/>
      </not>
    </and>
  </condition>
</target>

The last option is to use a scripting language to set the properties. This can be particularly handy when you need much finer control than the simple conditions shown here but, of course, comes with the overhead of adding JAR files to support the language, to say nothing of the added maintenance in requiring two languages to implement a single system. See the <script> task documentation for more details.

最後のオプションはプロパティを設定するためにスクリプト言語を使うためのものです。 これは、ここで示すような簡単な条件文よりも細かい制御が必要な場合に特に便利でしょう。 しかし、もちろん、 一つのシステムを実装するのに2つの言語が必要とする保守の問題は言うまでも無く、 スクリプト言語をサポートするには JAR ファイルを加えることによるオーバーヘッドが生じます。 詳しくは <script> タスクのドキュメントをご覧ください。

あるプロパティが設定された場合にスキップしたいターゲットがあります。 ターゲットの属性としてunless="property"を設定したのですが、 このターゲットが依存する全てのターゲットは、まだ実行されます。何故ですか / I have a target I want to skip if a property is set, so I have unless="property" as an attribute of the target, but all the targets this target depends on are still executed. Why?

The list of dependencies is generated by Ant before any of the targets are run. This allows dependent targets, such as an init target, to set properties that can control the execution of the targets higher in the dependency graph. This is a good thing.

全てのターゲットが実行される前に、 Ant により依存関係のリストが生成されます。 これにより、 init ターゲットのような依存されるターゲットが、 依存関係グラフの高いターゲットの実行を制御可能にするプロパティを設定できるようになります。 これはとても便利です。

However, when your dependencies break down the higher-level task into several smaller steps, this behaviour becomes counter-intuitive. There are a couple of solutions available:

しかしながら、自分の依存関係が高いレベルのタスクから、幾つか小さい段階に落ちたとき、この振舞いは反直感的になります。 幾つかの解決法があります:

  1. Put the same condition on each of the dependent targets.
  2. 同じ条件文を個々の依存されるターゲットに置く
  3. Execute the steps using <antcall>, instead of specifying them inside the depends attribute.
  4. depends属性の中でそれらを指定する代わりに、 <antcall>を使ってステップを実行する
自分の<fileset>において、 全てのファイルの <exclude>に続いて、 必要なファイルのみの <include>を設定しましたが、 ファイルは何も得られません。 何が悪いのでしょう。 / In my <fileset>, I've put in an <exclude> of all files followed by an <include> of just the files I want, but it isn't giving me any files at all. What's wrong?

The order of the <include> and <exclude> tags within a <fileset> is ignored when the FileSet is created. Instead, all of the <include> elements are processed together, followed by all of the <exclude> elements. This means that the <exclude> elements only apply to the file list produced by the <include> elements.

ファイルセットが生成されるとき、 <fileset>中の <include>および <exclude>タグの順序は 無視されます。 その代わりに、 全ての<include>要素は、 全ての<exclude>要素に続いて一緒に処理されます。 これは、 <exclude>要素は、 <include>要素により生成されたファイルリストにのみ適用されることを意味します。

To get the files you want, focus on just the <include> patterns that would be necessary to get them. If you find you need to trim the list that the <include> elements produce, then use <exclude> elements.

期待通りにファイルを得たい場合には、 得るのに必要となるであろう <include>パターンにのみ注目してください。 <include>要素が生成したリストの刈り取りが必要だとわかった場合には、 <exclude>要素を使ってください。

自分のビルドファイルにドイツ語のウムラウトのような 自国の文字を入れるにはどうすればいいですか。 / How can I include national characters like German umlauts in my build file?

You need to tell the XML parser which character encoding your build file uses, this is done inside the XML declaration.

自分のビルドファイルがどの文字エンコーディングを使っているか XML パーサーに教えなければなりません。 これは XML 宣言で行われます。

By default the parser assumes you are using the UTF-8 encoding instead of your platform's default. For most western european contries you should set the encoding to ISO-8859-1. To do so, make the very first line of you build file read like

デフォルトでは、パーサーは自分のプラットフォームのフォルトではなく、 UTF-8 エンコーディングを使っていると仮定しています。 多くの西欧諸国では、 エンコーディングをISO-8859-1に設定しなければならないでしょう。 そのように設定するには、 ビルドファイルの一番最初の行を以下のようにしなければなりません。

<?xml version="1.0" encoding="ISO-8859-1" ?>
自分の使っている IDE/エディタで Ant はサポートされてますか / Is Ant supported by my IDE/Editor?

See the section on IDE integration on our External Tools and Tasks page.

外部ツールおよびタスクのページの IDE との統合の節をご覧ください。

(X)Emacs/vi/MacOS X のプロジェクトビルダーは なぜ Ant により生成されたエラーメッセージを正しくパースしないのですか / Why doesn't (X)Emacs/vi/MacOS X's project builder correctly parse the error messages generated by Ant?

Ant adds a "banner" with the name of the current task in front of all logging messages - and there are no built-in regular expressions in your editor that would account for this.

Ant では、 全てのログメッセージの先頭にカレントタスク名をつけた"バナー"を出力します。 そして、これを考慮にいれるエディターに組み込みの正規表現式がありません。

You can disable this banner by invoking Ant with the -emacs switch. Alternatively, you can add the following snippet to your .emacs to make Emacs understand Ant's output.

-emacsスイッチをつけて Ant を起動することにより、 このバーナーを無効にすることができます。 また、その代わりに、 Emacs が Ant の出力を理解できるように、 次のコードを .emacsに加えることもできます。

(require 'compile)
(setq compilation-error-regexp-alist
  (append (list 
     ;; works for jikes
     '("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):\\([0-9]+\\):[0-9]+:[0-9]+:" 1 2 3)
     ;; works for javac 
     '("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):" 1 2))
  compilation-error-regexp-alist))

Yet another alternative that preserves most of Ant's formatting is to pipe Ant's output through the following Perl script by Dirk-Willem van Gulik:

さらにもう一つの方法として、 Ant のフォーマットの多くを保持するために、 Ant の出力を次の Dirk-Willem van Gulik氏の Perl スクリプトにパイプする方法があります:

#!/usr/bin/perl
#
# May 2001 dirkx@apache.org - remove any
# [foo] lines from the output; keeping
# spacing more or less there.
#
$|=1;
while(<STDIN>) {
	if (s/^(\s+)\[(\w+)\]//) {
		if ($2 ne $last) {
			print "$1\[$2\]";
			$s = ' ' x length($2);
		} else {
			print "$1 $s ";
		};
		$last = $2;
	};
	print;
};
自分のビルドファイルの有効性を検証するのに使える DTD はありますか / Is there a DTD that I can use to validate my build files?

An incomplete DTD can be created by the <antstructure> task - but this one has a few problems:

<antstructure>タスクにより不完全な DTD は作成可能です。- しかしながら、このDTDには幾つかの問題があります:

  • It doesn't know about required attributes. Only manual tweaking of this file can help here.
  • 必須の属性がわかりません。 このDTDファイルに対する手作業による微調整により解決可能です。
  • It is not complete - if you add new tasks via <taskdef> it won't know about it. See this page by Michel Casabianca for a solution to this problem. Note that the DTD you can download at this page is based on Ant 0.3.1.
  • これは不完全です。 - 新しいタスクを <taskdef> により追加した場合、 この DTD には記述されません。 この問題の解決法には、 Michel Casabianca 氏のこのページをご覧ください。 このページでダウンロードできる DTD は Ant 0.3.1 に基くものであることに注意してください。
  • It may even be an invalid DTD. As Ant allows tasks writers to define arbitrary elements, name collisions will happen quite frequently - if your version of Ant contains the optional <test> and <junit> tasks, there are two XML elements named test (the task and the nested child element of <junit>) with different attribute lists. This problem cannot be solved; DTDs don't give a syntax rich enough to support this.
  • 無効な DTD であることさえあります。 Ant はタスクの開発者に任意の要素を定義することを許可しているので、 名前の衝突はしばしば起こり得ます。- 使用しているバージョンの Ant に、 オプションの <test> と、 <junit> がある場合、 異なる属性リストを持つ test という名前の 2 つの XML 要素があることになります。 (そのタスクと、<junit>のネストされた子要素) この問題は解決不可能です; DTD は、このようなことをサポートするには文法が不十分です。
自分のビルドファイルに XML の一部をインクルードするにはどうすればいいですか / How do I include an XML snippet in my build file?

You can use XML's way of including external files and let the parser do the job for Ant:

外部ファイルをインクルードする XML の方法が使え、 パーサーが Ant のために処理してくれます:

<?xml version="1.0"?>

<!DOCTYPE project [
    <!ENTITY common SYSTEM "file:./common.xml">
]>

<project name="test" default="test" basedir=".">

  <target name="setup">
    ...
  </target>

  &common;

  ...

</project>

will literally include the contents of common.xml where you've placed the &common; entity.

これは、common.xmlの内容を、 &common;エンティティを置いた場所に、

In combination with a DTD, this would look like this:

DTD との組み合わせは次のようになります:

<!DOCTYPE project PUBLIC "-//ANT//DTD project//EN" "file:./ant.dtd" [
   <!ENTITY include SYSTEM "file:./header.xml">
]>
自分のビルド手続きの結果をメールで送るにはどうすればいいですか / How do I send an email with the result of my build process?

If you are using a nightly build of Ant 1.5 after 2001-12-14, you can use the built-in MailLogger:

2001年12月14日の Ant 1.5 のナイトビルド以降を使っている場合には、 組み込みのMailLoggerが使えます:

         ant -logger org.apache.tools.ant.listener.MailLogger

See the Listeners & Loggers documentation for details on the properties required.

必要なプロパティについての詳細は、 リスナーとロガー のドキュメントをご覧ください。

For older versions of Ant, you can use a custom BuildListener that sends out an email in the buildFinished() method. Will Glozer <will.glozer@jda.com> has written such a listener based on JavaMail. The source is:

古いバージョンの Ant では、 buildFinished() メソッド中でメールを送信するようなカスタム BuildListener を使う事ができます。 For older versions of Ant, you can use a custom Will Glozer 氏 <will.glozer@jda.com> が JavaMail に基づいたそのようなリスナーを開発してくれました。 ソースは次のとおりです:

import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import org.apache.tools.ant.*;

/**
 * A simple listener that waits for a build to finish and sends an email
 * of the results.  The settings are stored in "monitor.properties" and
 * are fairly self explanatory.
 *
 * @author      Will Glozer
 * @version     1.05a 09/06/2000
 */
public class BuildMonitor implements BuildListener {
    protected Properties props;

    /**
     * Create a new BuildMonitor.
     */
    public BuildMonitor() throws Exception {
        props = new Properties();
        InputStream is = getClass().getResourceAsStream("monitor.properties");
        props.load(is);
        is.close();
    }

    public void buildStarted(BuildEvent e) {
    }

    /**
     * Determine the status of the build and the actions to follow, now that
     * the build has completed.
     *
     * @param       e       Event describing the build tatus.
     */
    public void buildFinished(BuildEvent e) {
        Throwable th = e.getException();
        String status = (th != null) ? "failed" : "succeeded";
        
        try {
            String key = "build." + status;
            if (props.getProperty(key + ".notify").equalsIgnoreCase("false")) {
                    return;
            }
            
            Session session = Session.getDefaultInstance(props, null);

            MimeMessage message = new MimeMessage(session);
            message.addRecipients(Message.RecipientType.TO, parseAddresses(
                props.getProperty(key + ".email.to")));
            message.setSubject(props.getProperty(key + ".email.subject"));

            BufferedReader br = new BufferedReader(new FileReader(
                props.getProperty("build.log")));
            StringWriter sw = new StringWriter();
            
            String line = br.readLine();
            while (line != null) {
                sw.write(line);
                sw.write("\n");
                line = br.readLine();
            }
            br.close();
            
            message.setText(sw.toString(), "UTF-8");
            sw.close();
            
            Transport transport = session.getTransport();
            transport.connect();
            transport.send(message);
            transport.close();
        } catch (Exception ex) {
            System.out.println("BuildMonitor failed to send email!");
            ex.printStackTrace();
        }
    }

    /**
     * Parse a comma separated list of internet email addresses.
     *
     * @param       s       The list of addresses.
     * @return      Array of Addresses.
     */
    protected Address[] parseAddresses(String s) throws Exception {
        StringTokenizer st = new StringTokenizer(s, ",");
        Address[] addrs = new Address[st.countTokens()];

        for (int i = 0; i < addrs.length; i++) {
            addrs[i] = new InternetAddress(st.nextToken());
        }
        return addrs;
    }

    public void messageLogged(BuildEvent e) {
    }

    public void targetStarted(BuildEvent e) {
    }

    public void targetFinished(BuildEvent e) {
    }

    public void taskStarted(BuildEvent e) {        
    }

    public void taskFinished(BuildEvent e) {
    }
}

With a monitor.properties like this:

これに必要な monitor.properties ファイルは次のようになります:

# configuration for build monitor

mail.transport.protocol=smtp
mail.smtp.host=<host>
mail.from=Will Glozer <will.glozer@jda.com>

build.log=build.log

build.failed.notify=true
build.failed.email.to=will.glozer@jda.com
build.failed.email.subject=Nightly build failed!

build.succeeded.notify=true
build.succeeded.email.to=will.glozer@jda.com
build.succeeded.email.subject=Nightly build succeeded!

monitor.properties should be placed right next to your compiled BuildMonitor.class. To use it, invoke Ant like:

monitor.properties ファイルは 自分でコンパイルしたBuildMonitor.classと同じ場所に置かなければなりません。 これを使うには Ant を次のように起動します:

ant -listener BuildMonitor -logfile build.log

Make sure that mail.jar from JavaMail and activation.jar from the Java Beans Activation Framework are in your CLASSPATH.

JavaMail の mail.jar および Java Beans Activation Frameworkactivation.jar が 自分のCLASSPATHにあることを確認してください。

Ant が実行していた時の プロパティを BuildListener 中から得るにはどうすればいいですか / How do I get at the properties that Ant was running with from inside BuildListener?

You can get at a hashtable with all the properties that Ant has been using through the BuildEvent parameter. For example:

BuildEvent パラメータを通じて Ant が使用している全てのプロパティがあるハッシュテーブルが見つかります。たとえば:

public void buildFinished(BuildEvent e) {
    Hashtable table = e.getProject().getProperties();
    String buildpath = (String)table.get("build.path");
    ...
}

This is more accurate than just reading the same property files that your project does, since it will give the correct results for properties that were specified on the Ant command line.

この方法は、自分のプロジェクトが読んだプロパティファイルと同じファイルを単に読み込むよりも正確です。 なぜなら、Ant のコマンドラインで指定されたプロパティの正しい結果が与えられているからです。

Unix 上の Ant 1.3 で<chmod> や <exec>が動きません。 / <chmod> or <exec> doesn't work in Ant 1.3 on Unix

The antRun script in ANT_HOME/bin has DOS instead of Unix line endings; you must remove the carriage-return characters from this file. This can be done by using Ant's <fixcrlf> task or something like:

ANT_HOME/binにある antRunスクリプトは Unix ではなく DOS の行末文字になっています; このファイルから改行文字(CR)を取り除かなければなりません。 この作業は Ant の<fixcrlf> タスクを使うか次のようにすることでできます:

tr -d '\r' < $ANT_HOME/bin/antRun > /tmp/foo
mv /tmp/foo $ANT_HOME/bin/antRun
JavaDoc が次のメッセージで失敗します: java.io.IOException: javadoc: cannot execute / JavaDoc failed: java.io.IOException: javadoc: cannot execute

There is a bug in the Solaris reference implementation of the JDK (see http://developer.java.sun.com/developer/bugParade/bugs/4230399.html). This also appears to be true under Linux. Moving the JDK to the front of the PATH fixes the problem.

JDKのSolaris 用リファレンス実装にバグがあります。 (http://developer.java.sun.com/developer/bugParade/bugs/4230399.htmlをご覧ください。) これは Linux 上でもおこります。 JDK を PATH の先頭に移動すれば、問題は解決します。

<style> や <junit> が自分の <classpath>設定を無視します / <style> or <junit> ignores my <classpath>

These tasks don't ignore your classpath setting, you are facing a common problem with delegating classloaders.

これらのタスクではクラスパスの設定を無視しません。 クラスローダーの委譲という共通の問題に直面しています。

First of all let's state that Ant adds all .jar files from ANT_HOME/lib to CLASSPATH, therefore "in CLASSPATH" shall mean "either in your CLASSPATH environment variable or ANT_HOME/lib" for the rest of this answer.

まず最初に、 Ant が全てのANT_HOME/libにある.jarCLASSPATHを定めます。 従って、 "CLASSPATH中に"とは、 この答えの残りの部分においては、 "CLASSPATH環境変数中、あるいは、 "ANT_HOME/lib中のいずれかに"を意味します。

This question collects a common type of problem: A task needs an external library and it has a nested classpath element so that you can point it to this external library, but that doesn't work unless you put the external library into the CLASSPATH.

この質問では、共通の種類の問題を集めています: タスクには外部ライブラリが必要で、 外部ライブラリの場所を指定するようネストされた classpath 要素がありますが、 外部ライブラリをCLASSPATHに置かない限り動作しないというものです。

The root of the problem is that the class that needs the external library is on the CLASSPATH.

問題の根本は、外部ライブラリを必要とするクラスがCLASSPATHにあるということです。

When you specify a nested <classpath> in Ant, Ant creates a new class loader that uses the path you have specified. It then tries to load additional classes from this classloader.

Ant でネストされた<classpath> 要素を指定する際に、 Ant はユーザが指定したパスを使用する新しいクラスローダーを生成します。 そして、このクラスローダーから追加のクラスをロードしようとするのです。

In most cases - for example the two cases above - Ant doesn't load the external library directly, it is the loaded class that does so.

ほとんどの場合 - 例えば上の 2 つのケースでは - Ant は外部ライブラリを直接ロードせずに、 ロードされたクラスなのです。

In the case of <junit> it is the task implementation itself and in the case of <style> it is the implementation of the org.apache.tools.ant.taskdefs.XSLTLiaison class.

<junit> の場合、 タスクの実装自身であり、 <style>の場合は、 それは、 org.apache.tools.ant.taskdefs.XSLTLiaison クラスの実装なのです。

Ant's class loader implementation uses Java's delegation model, see http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html the paragraph

Ant のクラスローダーの実装は Java のデリゲートモデルを使用しています。 http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.htmlの節をご覧ください。

The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When called upon to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine's built-in class loader, called the bootstrap class loader, does not itself have a parent but may serve as the parent of a ClassLoader instance.
ClassLoader クラスはクラスやリソースを検索するのにデリゲーションモデルを利用しています。 個々のClassLoaderインスタンスは親のクラスローダーと結びつけられています。 クラスやリソースを探すために呼ばれた場合、 ClassLoaderインスタンスは When called upon to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. ブートストラップクラスローダーと呼ばれる仮想マシンのビルトインクラスローダーは、それ自身、親を持ちませんが、 ClassLoaderインスタンスの親として振舞います。

This means, Ant's class loader will consult the bootstrap class loader first, which tries to load classes from CLASSPATH. The bootstrap class loader doesn't know anything about Ant's class loader or even the path you have specified.

Ant のクラスローダーは先にブートストラップローダーを評価し、 CLASSPATHよりクラスのロードを試みることを意味します。 ブートストラップクラスローダーは Ant のクラスローダーについては何もしらず、 指定したパスもわかりません。

If the bootstrap class loader can load the class Ant has asked it to load, this class will try to load the external library from CLASSPATH as well - it doesn't know anything else - and will not find it unless the library is in CLASSPATH as well.

ブートストラップクラスローダーがそのクラスをロードできる場合、 Ant はロードできるか問合せられます。 同様にこのクラスは、 CLASSPATHより、外部ライブラリがロードできるか試みます。- 他のことについては何も知りません - そのライブラリが CLASSPATH にある限りはそれを探しません。

To solve this, you have two major options:

これを解決するには2つの代表的な方法があります:

  1. put all external libaries you need in CLASSPATH as well this is not what you want, otherwise you wouldn't have found this FAQ entry.
  2. 必要な外部ライブラリを全てCLASSPATH に置く。これは、望んでいる方法ではないでしょう。 さもなければ、FAQ の項目にこれは載せないでしょう。
  3. remove the class that loads the external library from the CLASSPATH.
  4. CLASSPATHから外部ライブラリをロードするクラスを削除する。

The easiest way to do this is to remove optional.jar from ANT_HOME/lib. If you do so, you will have to <taskdef> all optional tasks and use nested <classpath> elements in the <taskdef> tasks that point to the new location of optional.jar. Also, don't forget to add the new location of optional.jar to the <classpath> of your <style> or <junit> task.

これを行う最も簡単な方法は ANT_HOME/libから optional.jarを削除することです。 そうした場合、 全てのオプションタスクに対し、 <taskdef> し、 <taskdef>タスク中で、 optional.jarの新しい場所を参照するネストされた<classpath> を使わなければなりません。 また、 optional.jarの新しい場所を <style> あるいは <junit><classpath>に加えるのを忘れないでください。

If you want to avoid to <taskdef> all optional tasks you need, the only other option is to remove the classes that should not be loaded via the bootstrap class loader from optional.jar and put them into a separate archive. Add this separate archive to the <classpath> of your <style> or <junit> task - and make sure the separate archive is not in CLASSPATH.

必要なオプションタスクの全てで <taskdef> したくない場合には、 唯一のもう一つの方法は、 optional.jar からブートストラップクラスローダーにより ロードされないクラスを削除し、 それらを別のアーカイブに入れることです。 この別のアーカイブを <style> または <junit> タスクの<classpath>に加えます。- そして、その別のアーカイブが CLASSPATH に無いことを確認します。

In the case of <junit> you'd have to remove all classes that are in the org/apache/tools/ant/taskdefs/optional/junit directory, in the <style> case it is one of the *Liaison classes in org/apache/tools/ant/taskdefs/optional.

<junit>の場合、 org/apache/tools/ant/taskdefs/optional/junit ディレクトリにある全てのクラスを削除する必要があり、 <style>の場合、 org/apache/tools/ant If you use the option to break up optional.jar for <junit>, you still have to use a <taskdef> with a nested <classpath> to define the junit task.

/taskdefs/optional にある *Liaison クラスのうちの一つを削除する必要があります。

If you use the option to break up optional.jar for <junit>, you still have to use a <taskdef> with a nested <classpath> to define the junit task.

<junit>のために optional.jarに変更を加えた代替方法を使っている場合、 junit タスクを定義するために ネストされた<classpath>を持つ <taskdef>を使わなければなりません。


Copyright © 2000-2002, Apache Software Foundation
[訳注:これは漆島賢二が翻訳しました。日本語訳に対するコメントがあれば こちらに送ってください]