Apache Ant site Apache Ant logo

Apache Ant サイト
ホーム
プロジェクト
 

よくある質問

質問

この FAQ について

一般

インストール

どのように…

期待通りに動作しません

Apache Ant と IDE/エディタ

高度な問題

既知の問題

回答

このドキュメントの最新版はどこにありますか?

最新版は常に Apache Ant のホームページ https://ant.dokyumento.jp/faq.html で確認できます。

この FAQ にどのように貢献できますか?

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

パッチは svn diff コマンドで作成できます。このページの「バグの修正」の段落も参照してください。

この FAQ の HTML 版はどのように作成されていますか?

元の XML ファイルから HTML バージョンをレンダリングするために、Anakia を使用しています。

XML ファイルを処理するために使用される Velocity スタイルシートは、Ant のサイトの SVN リポジトリの sources/stylesheets サブディレクトリにあります。ant サイトの SVN モジュールの最上位レベルにあるビルドファイル build.xml は、Anakia を駆動するために使用されます。

Apache Ant とは何ですか?

Ant は Java ベースのビルドツールです。理論的には、Make のようなものですが、Make の複雑さがなく、純粋な Java コードの完全な移植性があります。

なぜ Ant と呼ぶのですか?

Ant のオリジナルの作者である James Duncan Davidson によると、その名前は「Another Neat Tool」の頭字語です。

後の説明では、「アリは物事を構築する上で非常に優れた仕事をします」や「アリは非常に小さく、自重の何十倍もの重さを運ぶことができます」というように、Ant の意図されている機能を表しています。

Ant の歴史について少し教えてください。

当初、Ant は Tomcat コードベースの一部であり、Apache Software Foundation に寄贈されました。Tomcat のオリジナルの作者でもある James Duncan Davidson によって作成されました。Ant は Tomcat を構築するためだけに存在していました。

その後すぐに、いくつかのオープンソース Java プロジェクトが、Ant が Makefiles で抱えていた問題を解決できることに気づきました。Jakarta と旧 Java Apache プロジェクトでホストされているプロジェクトから始まり、Ant はウイルスのように広がり、今では多くのプロジェクトで選択されているビルドツールとなっています。

2000 年 1 月、Ant は個別の CVS モジュールに移され、Tomcat から独立した独自のプロジェクトに昇格し、Apache Ant となりました。

より多くのユーザーに公開された Ant の最初のバージョンは、2000 年 4 月 19 日に Tomcat 3.1 リリースと共に提供されたものでした。このバージョンは後に Ant 0.3.1 と呼ばれています。

スタンドアロン製品としての Ant の最初の公式リリースは、2000 年 7 月 19 日にリリースされた Ant 1.1 です。完全なリリース履歴

Ant バージョン リリース日
1.1 2000 年 7 月 19 日
1.2 2000 年 10 月 24 日
1.3 2001 年 3 月 3 日
1.4 2001 年 9 月 3 日
1.4.1 2001 年 10 月 11 日
1.5 2002 年 7 月 10 日
1.5.1 2002 年 10 月 3 日
1.5.2 2003 年 3 月 3 日
1.5.3 2003 年 4 月 9 日
1.5.4 2003 年 8 月 12 日
1.6.0 2003 年 12 月 18 日
1.6.1 2004 年 2 月 12 日
1.6.2 2004 年 7 月 16 日
1.6.3 2005 年 4 月 28 日
1.6.4 2005 年 5 月 19 日
1.6.5 2005 年 6 月 2 日
1.7.0 2006 年 12 月 19 日
1.7.1 2008 年 6 月 27 日
1.8.0 2010 年 2 月 8 日
1.8.1 2010 年 5 月 7 日
1.8.2 2010 年 12 月 27 日
1.8.3 2012 年 2 月 29 日
1.8.4 2012 年 5 月 23 日
1.9.0 2013 年 3 月 7 日
1.9.1 2013 年 5 月 21 日
1.9.2 2013 年 7 月 12 日
1.9.3 2013 年 12 月 29 日
1.9.4 2014 年 5 月 5 日
1.9.5 2015 年 6 月 3 日
1.9.6 2015 年 7 月 2 日
1.9.7 2016 年 4 月 12 日
1.9.8 2016 年 12 月 31 日
1.9.9 2017 年 2 月 6 日
1.9.10 2018 年 2 月 6 日
1.9.11 2018 年 3 月 27 日
1.9.12 2018 年 6 月 22 日
1.9.13 2018 年 7 月 13 日
1.9.14 2019 年 3 月 17 日
1.9.15 2020 年 5 月 13 日
1.9.16 2021 年 7 月 13 日
1.10.0 2016 年 12 月 31 日
1.10.1 2017 年 2 月 6 日
1.10.2 2018 年 2 月 6 日
1.10.3 2018 年 3 月 27 日
1.10.4 2018 年 6 月 22 日
1.10.6 2019 年 5 月 8 日
1.10.7 2019 年 9 月 5 日
1.10.8 2020 年 5 月 13 日
1.10.9 2020 年 9 月 30 日
1.10.10 2021 年 4 月 17 日
1.10.11 2021 年 7 月 13 日
1.10.12 2021 年 10 月 19 日
1.10.13 2023 年 1 月 10 日
1.10.14 2023 年 8 月 20 日

Apache Ant を実行するために必要な Java のバージョンはどれですか?

システムに Java がインストールされている必要があります。バージョン 1.8 以降が必要です。Java のバージョンが新しいほど、利用できる Ant タスクが増えます。

git ブランチ 1.9.x は、Java 1.5 でビルドおよび実行できる Ant 1.9.x バージョンの長期サポートに使用されます。

JRE のみが存在し、フル JDK が存在しない場合、多くのタスクは機能しません。

次の表は、Ant をコンパイルおよび実行するために必要な最小 Java バージョンを示しています。ほとんどのコミッタはより新しいバージョンの JDK を使用しており、Ant は古いバージョンではほとんどテストされていないことに注意してください。

Ant バージョン 最小 Java バージョン
1.1~1.5.4 1.1
1.6.0~1.6.5 1.2
1.7.0~1.7.1 1.3
1.8.0~1.8.3 1.4
任意の 1.9.x リリースと git ブランチ 1.9.x 1.5
任意の 1.10.x リリースと現在の git master ブランチ 1.8

tar.gz 配布ファイルの解凍を試行すると、チェックサムエラーが発生します。なぜですか?

Ant の配布ファイルには、標準の tar ファイル形式ではサポートされていない 100 文字を超えるファイル名が含まれています。tar のいくつかの異なる実装では、この制限に対処するために異なる非互換な方法が使用されています。

Ant の <tar> タスクは、GNU tar 拡張機能を使用する tar アーカイブを作成できます。これは、配布ファイルを作成する際に使用されています。異なるバージョンの tar(たとえば、Solaris に付属のもの)を使用している場合、アーカイブを解凍するために使用できません。

解決策としては、こちらにある GNU tar をインストールするか、代わりに zip アーカイブを使用することです(jar xf を使用して解凍できます)。

RedHat ES 3 で ant-1.6.x(または 1.5.2 より後のバージョン)を動作させるにはどうすればよいですか?

Redhat ES 3.0 には ant 1.5.2 がインストールされています。PATH と ANT_HOME 変数をより新しいバージョンの ant に正しく設定していても、常にプリインストールされたバージョンを使用するように強制されます。

この OS でより新しいバージョンの ant を使用するには、次の操作を行うことができます。

$ ant -version
Apache Ant version 1.5.2-23 compiled on November 12 2003
$ su -
# rpm -e ant ant-libs
# exit
$ hash -r
$ ant -version
Apache Ant version 1.6.2 compiled on July 16 2004

Java Server Pages(JSP)をプリコンパイルするにはどうすればよいですか?

Apache Antには、その目的のために設計された、組み込みのオプションタスク<jspc>があります。しかし、このタスクは非推奨です。マニュアルで提案されている代替手段を以下に示します。

コンテナ固有のJSPコンパイラに依存する代わりに、生のファイル(*.jsp)をデプロイし、コンテナの組み込み関数を使用することをお勧めします。デプロイ後、デプロイされたWebアプリケーションに対してテストスイートを実行します(例:CactusまたはHttpUnitを使用)。これにより、テスト結果とコンパイル済みのJSPが得られます。

OS固有の設定をどのように実現しますか?

基本的な考え方は、OS名に対応する名前のプロパティファイルを使用することです。その後、組み込みのプロパティを使用します。os.name.

より良い使用方法のためには、デフォルト値を含むファイルも提供する必要があります。ただし、正しいOS名に注意してください。テストとして、すべてのマシンで${os.name}をするだけで、正しいファイル名を使用していることを確認できます。

          <property file="${os.name}.properties"/>
          <property file="default.properties"/>

作成した外部タスクを「外部ツールとタスク」ページに追加するにはどうすればよいですか?

devまたはユーザーのメーリングリスト(どちらか一方のリストで十分です)に参加してメッセージを投稿し、次の情報を含めてください。

この情報の推奨形式は、このドキュメントへのパッチです。

「単純なプラグイン」よりも大きなものをAntに追加した場合は、projects.htmlへのリンクを追加することをお勧めします。追加手順は同じです。パッチを適用するファイルはこのドキュメントです。このファイルの構文は同じです。

新しいタスクを作成するにはどうすればよいですか?

Antの使用方法に関する多くの情報に加えて、マニュアルには、新しいタスクでAntを拡張する方法に関する情報も含まれています。「Antを使った開発」でこの情報を見つけることができます。

おそらく、すでにあなたが作成したいタスクを作成した人がいる可能性があります。まず外部ツールとタスク関連プロジェクトを確認することをお勧めします。

コマンドラインからビルドファイルにパラメータを渡すにはどうすればよいですか?

プロパティを使用します。`ant -Dname=value`を使用すると、Antコマンドラインでプロパティの値を定義できます。これらのプロパティは、通常のプロパティと同様にビルドファイル内で使用できます。`${name}`は`value`に置き換えられます。

Jikes固有のコマンドラインスイッチをどのように使用できますか?

いくつかのスイッチは、「マジック」プロパティを介してサポートされています。

スイッチ プロパティ デフォルト
+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 == 設定なし

Ant 1.5以降では、<javac>タスクでネストされた<compilerarg>要素を使用することもできます。

コマンドライン引数に<文字を含めるにはどうすればよいですか?

簡単な答えは「&lt;を使用する」です。

詳しい答えは、それでもあなたが望む動作にならない可能性があるということです(次のセクションを参照)。

<exec>タスクで標準入力または標準出力をリダイレクトするにはどうすればよいですか?

たとえば、`m4`コマンドの標準出力ストリームをファイルに書き込むようにリダイレクトする場合、次のようなものになります。

shell-prompt> m4 foo.m4 > foo

そして、それを次のように翻訳しようとします。

<exec executable="m4">
  <arg value="foo.m4"/>
  <arg value="&gt;"/>
  <arg value="foo"/>
</exec>

これは期待する動作になりません。出力リダイレクトはコマンド自体ではなくシェルによって実行されるため、次のように読む必要があります。

<exec executable="/bin/sh">
  <arg value="-c" />
  <arg value="m4 foo.m4 &gt; foo" />
</exec>

コマンドを単一の引用符で囲まれた引数として渡すには、最後の要素で<arg>の`value`属性を使用する必要があります。または、次を使用することもできます。

<exec executable="/bin/sh">
  <arg line='-c "m4 foo.m4 &gt; foo"'/>
</exec>

単一引用符の中に二重引用符を入れ子にしていることに注意してください。

Antからバッチファイルまたはシェルスクリプトを実行するにはどうすればよいですか?

ネイティブのUnixシステムでは、シェルスクリプトを直接実行できるはずです。Unixタイプのシェルを実行しているシステム(例:Windows上のCygwin)では、(コマンド)シェル、バッチファイルの場合は`cmd`、シェルスクリプトの場合は`sh`を実行し、バッチファイルまたはシェルスクリプト(スクリプトへの引数を含む)を単一のコマンドとして、それぞれ` /c`または`-c`スイッチを使用して渡します。`sh`を実行する例については上記のセクションを参照してください。バッチファイルの場合、次のようなものを使用します。

<exec dir="." executable="cmd" os="Windows NT">
  <arg line="/c test.bat"/>
</exec>

複数の条件がtrueの場合にのみ特定のターゲットを実行したい。

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

テストする設定済みプロパティと未設定プロパティが1つしかない場合は、ターゲットに`if`属性と`unless`属性の両方を指定でき、これらは「AND」として動作します。

Ant 1.3以前のバージョンを使用している場合、他のすべてのケースで動作させる方法は、ターゲットをチェーンしてテストする特定の状態を決定することです。

これがどのように機能するかを確認するために、`prop1`、`prop2`、`prop3`の3つのプロパティがあると仮定します。`prop1`と`prop2`が設定されていて、`prop3`が設定されていないことをテストしたいと考えています。条件が真の場合、「yes」とエコーしたいと考えています。

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>

注:<antcall>タスクはプロパティの変更を呼び出し元の環境に戻しません。たとえば、`cond-if-3`ターゲットで`result`プロパティを設定し、`cond`ターゲットで`<echo message="result is ${result}"/>`を実行することはできません。

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>

このバージョンは2つのことを利用しています。

リテラルの`${property}`文字列のテストは、読みやすさや理解しやすさとはほど遠いので、1.4.1以降のAntでは、<isset>要素が<condition>タスクに追加されています。

<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>

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

ドイツ語のウムラウトのような特殊文字をビルドファイルに含めるにはどうすればよいですか?

ビルドファイルで使用している文字エンコーディングをXMLパーサーに伝える必要があります。これはXML宣言内で行われます。

デフォルトでは、パーサーはプラットフォームのデフォルトではなくUTF-8エンコーディングを使用していると想定しています。ほとんどの西ヨーロッパ諸国では、エンコーディングを`ISO-8859-1`に設定する必要があります。そのためには、ビルドファイルの最初の行を次のようにします。

<?xml version="1.0" encoding="ISO-8859-1" ?>

`jar`の`M`スイッチをどのように使用すればよいですか?MANIFESTは必要ありません。

JARアーカイブはZIPファイルであるため、MANIFESTが必要ない場合は、単純に<zip>を使用できます。

ファイル名に特殊文字が含まれている場合は、Sunの`jar`ユーティリティとAntの`<jar>`は名前のエンコードにUTF-8を使用するのに対し、`<zip>`はプラットフォームのデフォルトエンコーディングを使用することに注意してください。必要に応じて、`<zip>`のencoding属性を使用してください。

<property name="prop" value="${${anotherprop}}"/>のようなこと(プロパティを二重に展開すること)をどのように行うことができますか?

外部の助けなしでは困難です。

外部ライブラリを必要とする<script/>を使用すると、次のようにできます。

<script language="javascript">
    propname = project.getProperty("anotherprop");
    project.setNewProperty("prop", propname);
</script>

AntContrib(外部タスクライブラリ)を使用すると、` <propertycopy name="prop" from="${anotherprop}"/>`を実行できます。

Ant 1.6では、AntContribsの<propertycopy>をシミュレートし、外部ライブラリを必要としなくなります。

<macrodef name="propertycopy">
  <attribute name="name"/>
  <attribute name="from"/>
  <sequential>
    <property name="@{name}" value="${@{from}}"/>
  </sequential>
</macrodef>

'props' antlib(外部ですが、Antからも提供されています)を使用すると、必要なプロパティヘルパーを登録した後、ビルドファイル全体で`${${anotherprop}`を使用してデリファレンシングを行うことができます(プロパティタスク内だけではありません)。

<propertyhelper>
  <props:nested />
</propertyhelper>
<property name="foo" value="foo.value" />
<property name="var" value="foo" />
<echo> ${${var}} = foo.value </echo>

Flaka(外部Antプラグイン)を使用すると、flakaタスク内だけでなく、flakaのプロパティハンドラーをインストールした後のすべてのタスクで`#{${anotherprop}}`を使用してデリファレンシングを行うことができます。

<project xmlns:fl="antlib:it.haefelinger.flaka">
  <fl:install-property-handler/>
  <property name="foo" value="foo.value"/>
  <property name="var" value="foo" />
  <property name="buildtype" value="test"/>
  <property name="appserv_test" value="//testserver"/>
  <echo>
    #{${var}} = foo.value
    <!-- nested property -->
    #{appserv_${buildtype}}
  </echo>
</project>

特定のディレクトリの下にあるすべてのものを削除し、ディレクトリ自体は保持するにはどうすればよいですか?

この方法を試みるほとんどのユーザーは、`<delete includeemptydirs="true" />`が役立つことを理解するのに問題ありません。一見難しい部分は、ベースディレクトリ自体を保持することです。Antはこれをディレクトリスキャンに含めます。幸いにも、答えは簡単です。

<delete includeemptydirs="true">
  <fileset dir="dirtokeep" includes="**/*" />
</delete>

特定のディレクトリが空の場合にのみ削除するにはどうすればよいですか?

この方法を試みるほとんどのユーザーは、`<delete includeemptydirs="true" />`が役立つことを理解するのに問題ありません。一見難しい部分は、Antがディレクトリスキャンに含める非空ディレクトリを保持することです。幸いにも、答えは簡単です。

<delete includeemptydirs="true">
  <fileset dir="dirtokeepifnotempty" excludes="**/*" />
</delete>

一般的なアドバイス

Apache Antが期待通りに動作しない理由はたくさんあり、すべてがAntのバグによるわけではありません。問題の原因を特定するのに役立つヒントについては、問題が発生していますか?ページを参照してください。

Antは常にすべてのJavaファイルを再コンパイルするのはなぜですか?

どのファイルをコンパイルする必要があるかを判断するために、Antはソースファイルのタイムスタンプと結果の`.class`ファイルのタイムスタンプを比較します。どのパッケージに属しているかを知るためにすべてのソースファイルを開くのは非常に非効率的です。代わりに、Antは、パッケージ階層を反映するディレクトリ階層にソースファイルを配置し、このディレクトリツリーのルートを`srcdir`属性でAntに指定することを想定しています。

`<javac srcdir="src" destdir="dest"/>`があるとします。Antが`src/a/b/C.java`ファイルを見つけると、パッケージ`a.b`にあると想定されるため、結果の`.class`ファイルは`dest/a/b/C.class`になります。

ソースツリーのディレクトリ構造がパッケージ構造と一致しない場合、Antのヒューリスティックは機能せず、最新の状態にあるクラスを再コンパイルします。Antは、このようなソースツリーのレイアウトを想定している唯一のツールではありません。

パッケージの一部として宣言されていないJavaソースファイルがある場合でも、<javac>タスクを使用してこれらのファイルを正しくコンパイルできます。srcdir属性とdestdir属性に、ソースファイルが存在する実際のディレクトリと、クラスファイルを出力するディレクトリをそれぞれ設定するだけです。

不要なSourceSafeコントロールファイル(CVSファイル、エディターのバックアップファイルなど)を削除するために<delete>タスクを使用しましたが、機能しません。ファイルが削除されません。何が問題ですか?

これは、デフォルトでAntがSourceSafeコントロールファイル(vssver.scc)およびその他の特定のファイルをFileSetから除外するためである可能性が高いです。

おそらく、次のような操作を行ったのでしょう。

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

デフォルトの除外を無効にすると機能します。

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

デフォルトで除外されるパターンの完全なリストについては、ユーザーマニュアルを参照してください。

プロパティが設定されている場合にスキップするターゲットがあり、ターゲットの属性としてunless="property"を設定していますが、このターゲットに依存するすべてのターゲットが実行されます。なぜですか?

依存関係のリストは、ターゲットが実行される前にAntによって生成されます。これにより、initターゲットなどの依存ターゲットは、依存関係グラフの上位にあるターゲットの実行を制御できるプロパティを設定できます。これは良いことです。

ただし、依存関係によって上位のタスクがいくつかの小さなステップに分割されると、この動作は直感的ではなくなります。いくつかの解決策があります。

  1. 依存する各ターゲットに同じ条件を設定します。
  2. depends属性内で指定する代わりに、<antcall>を使用してステップを実行します。

私の<fileset>では、すべてのファイルを<exclude>で除外した後、必要なファイルのみを<include>で含めていますが、ファイルがまったく取得されません。何が問題ですか?

<fileset>内の<include>タグと<exclude>タグの順序は、FileSetが作成されるときに無視されます。代わりに、すべての<include>要素がまとめて処理され、その後、すべての<exclude>要素が処理されます。つまり、<exclude>要素は、<include>要素によって生成されたファイルリストにのみ適用されます。

必要なファイルを取得するには、それらを取得するために必要な<include>パターンに焦点を当てます。<include>要素によって生成されたリストをトリミングする必要がある場合は、<exclude>要素を使用します。

外部のbuild.propertiesファイルに必要なjarを含め、pathelementまたはclasspath refidで参照しても、antはjavacを使用してプログラムをビルドできませんでした。

antが外部ファイルからプロパティを読み込むとき、プロパティの値は変更されません。たとえば、末尾の空白はトリミングされません。

値がファイルパス(コンパイルに必要なjarなど)を表す場合、javacなど、値を必要とするタスクは、末尾のスペースのためにファイルが見つからないため、コンパイルに失敗します。

Antは、小文字のweb-infディレクトリを持つWARファイル、または小文字のmeta-infディレクトリを持つJARファイルを作成します。

いいえ、そうではありません。

WinZIPでこれらの小文字のディレクトリ名を見たことがあるかもしれませんが、WinZIPは役立つようにしようとして失敗しています。WinZIPは大文字のみのファイル名に遭遇すると、古いDOSボックスから来たものと仮定し、すべて小文字に変更します。

jarを使用してアーカイブを解凍(または確認)すると、名前が正しい大文字と小文字で表示されます。

WinZIP(少なくともバージョン8.1)では、構成でこれを修正できます。[オプション] / [構成]メニューの[表示]タブの[一般]セクションで、「すべて大文字のファイル名を許可する」ボックスをオンにします。META-INFとWEB-INFが正しく表示されます。

Ant 1.6.xをインストールしましたが、Exception in thread "main" java.lang.NoClassDefFoundError: が表示されるようになりました。

これは、クラスパスまたは構成のどこかに古いバージョンのantがあることが原因です。

この問題のバリエーションは、埋め込まれたantクラスのコピーを含むクラスパスにあるjarでも発生します。その例として、weblogic.jarの一部のバージョンがあります。

これが当てはまるかどうかを確認するには、(unix / shで)次の操作を行います。

        unset CLASSPATH
        ant -version
        

Ant 1.6.xをインストールしましたが、java.lang.InstantiationException: org.apache.tools.ant.Mainが表示されるようになりました。

これは、クラスパスまたは構成のどこかに古いバージョンのantがあることが原因です。

この問題のバリエーションは、一部のLinuxシステムで発生する可能性があります。一部のLinuxシステム(たとえば、Fedora Core 2)には、事前にインストールされたバージョンのantが付属しています。/etc/ant.confという構成ファイルがあり、存在する場合は、antシェルスクリプトが「ドット」を含みます。Fedora Core 2では、/etc/ant.confファイルはANT_HOME環境変数を/usr/share/antにリセットします。これにより、古いバージョンのant(この場合1.5.x)が新しいバージョンのantスクリプトファイルで使用されるという問題が発生します。

これが当てはまるかどうかを確認するには、ant --noconfig -versionを実行します。

Antのjarまたはmanifest関連のタスクを使用するたびに、manifestの長い行が70文字で折り返され、結果のjarがアプリケーションサーバーで機能しません。Antはなぜこれを行うのですか?

AntはJavaのJarファイル仕様を実装しています。許容される最大行長と継続文字の概念について説明している「注記」セクションを参照してください。

Antによって生成されたjarファイルがアプリケーションサーバーで機能せず、その失敗が折り返されたmanifestによるものである場合、アプリケーションサーバーの提供元に問い合わせる必要があります。これはアプリケーションサーバーのバグです。ただし、はるかに可能性が高いのは、クラスパスの指定に問題があることです。問題は、Antによるクラスパスの折り返しではありません。

問題がクラスパスの指定によるものでないことを確認するまで、この問題に関するバグを報告しないでください。

Windowsで<exec>"Cannot run program "...":CreateProcess error=2"で失敗します。

よくある問題は、PATHに実行可能ファイルがないことです。エラーメッセージCannot run program "...":CreateProcess error=2. The system cannot find the path specified.が表示された場合は、PATH変数を確認してください。

コマンドをコマンドラインで直接入力してください。Windowsが見つければ、Antも実行できるはずです。(そうでない場合は、ユーザーメーリングリストでヘルプを依頼してください。)Windowsがプログラムを実行できない場合は、プログラムのディレクトリをPATHに追加するか(set PATH=%PATH%;dirOfProgram)、ビルドファイルのexecutable属性に絶対パスを指定します。

私の<junit>レポートに、エラーメッセージを含む最初の行がありません。

Ant 1.8.0以降、filtertrace属性が設定されている場合、スタックトレースからフィルタリングされる行のセットに「more」というテキストが追加されました。目的は、トレースの下部にある「24 more ...」行を抑制することです。

エラーメッセージに「more」という単語が含まれている場合、メッセージを含む行も削除されます。これは、リリースされたAnt 1.8.3で修正される予定です。

唯一の既存の回避策は、filtertraceを無効にするか、エラーメッセージに「more」という単語を含めないように変更することです。

私のmacrodefedタスクでプロパティが2回展開されます。

macrodefedタスクに属性が含まれている場合、プロパティ参照は2回展開されます。たとえば

  <macrodef name="echotest">
    <attribute name="message" />
    <sequential>
      <echo message="@{message}" />
    </sequential>
  </macrodef>
  <echotest message="$${basedir}" />

は、期待されるテキスト${basedir}ではなく、basedirプロパティの値を出力します。

これは、${}シーケンスが@{}シーケンスを展開する前に1回展開され、その後1回展開されるためです。このFAQのマクロ定義のようなものを機能させるために必要です。これは可能にします。

<property name="choice" value="2"/>
<property name="thing.1" value="one"/>
<property name="thing.2" value="two"/>
<property name="thing.3" value="three"/>
<propertycopy to="thing" from="thing.${choice}"/>

プロパティが2回展開されない場合、これは不可能です。

Ant 1.8.3以降、二重展開を回避するには、明示的にオフにすることができます。

  <macrodef name="echotest">
    <attribute name="message" doubleexpanding="false" />
    <sequential>
      <echo message="@{message}" />
    </sequential>
  </macrodef>
  <echotest message="$${basedir}" />

Apache Antは私のIDE /エディターでサポートされていますか?

外部ツールとタスクページのIDE統合に関するセクションを参照してください。

なぜ(X)Emacs/vi/MacOS Xのプロジェクトビルダーは、Antによって生成されたエラーメッセージを正しく解析しないのですか?

Antは、すべてのログメッセージの前に現在のタスクの名前を含む「バナー」を追加します。エディターには、これに対応する組み込みの正規表現はありません。

-emacsスイッチを使用してAntを呼び出すことで、このバナーを無効にできます。AntにEmacsのコンパイルモードを自動検出させるには、これを.antrcに入力します(Ville Skyttä提供)。

# Detect (X)Emacs compile mode
if [ "$EMACS" = "t" ] ; then
  ANT_ARGS="$ANT_ARGS -emacs"
  ANT_OPTS="$ANT_OPTS -Dbuild.compiler.emacs=true"
fi

あるいは、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))

Antのフォーマットの大部分を維持する別の代替手段として、Dirk-Willem van Gulikによる次のPerlスクリプトを通してAntの出力をパイプすることができます。

#!/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はありますか?

<antstructure>タスクによって不完全なDTDを作成できますが、いくつかの問題があります。

ビルドファイルにXMLスニペットを含めるにはどうすればよいですか?

外部ファイルのインクルードにXMLの方式を使用し、Antにパーサーの処理を任せることができます。

<?xml version="1.0"?>

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

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

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

  &common;

  ...

</project>

これにより、`&common;` エンティティが配置されている場所に存在する`common.xml` の内容が文字通りインクルードされます。

(この例におけるファイル名`common.xml` は、XMLパーサーによって、それを含むXMLファイルからの相対パスで解決されます。絶対的な`file:`プロトコルURIを使用することもできます。)

DTDと組み合わせると、次のようになります。

<!DOCTYPE project PUBLIC "-//ANT//DTD project//EN" "ant.dtd" [
   <!ENTITY include SYSTEM "header.xml">
]>

Ant 1.6以降では、ビルドファイルの断片をインクルードするために使用できる新しい`<import>`タスクがあります。(エンティティインクルードで使用されるスニペットとは異なり、参照されるファイルは完全なAntビルドファイルである必要があります。)

上記の例は、次のようになります。

<?xml version="1.0"?>
<project name="test" default="test" basedir=".">

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

  <import file="./common.xml"/>

  ...

</project>

エンティティインクルードとは異なり、`<import>`ではファイル名にAntのプロパティを使用できます。

ビルドプロセスの結果をメールで送信するにはどうすればよいですか?

2001年12月14日以降のAnt 1.5のナイトリービルドを使用している場合は、ビルトインのMailLoggerを使用できます。

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

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

Antの古いバージョンでは、`buildFinished()`メソッドでメールを送信するカスタムBuildListenerを使用できます。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 status.
     */
    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) {
    }
}

次のような`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`は、コンパイルされた`BuildMonitor.class`のすぐ隣に配置する必要があります。使用する場合は、次のようにAntを呼び出します。

ant -listener BuildMonitor -logfile build.log

JavaMailの`mail.jar`と、Java Beans Activation Frameworkの`activation.jar`が`CLASSPATH`にあることを確認してください。

BuildListener内から、Antが実行していたプロパティにアクセスするにはどうすればよいですか?

BuildEventパラメーターを介して、Antが使用していたすべてプロパティを含むハッシュテーブルにアクセスできます。たとえば

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

これは、プロジェクトが同じプロパティファイルを読み取るだけよりも正確です。なぜなら、Antコマンドラインで指定されたプロパティに対して正しい結果が得られるからです。

`<exec>`により、他のタスクがハングするか、`<input>`タスクの動作がおかしくなります。

Apache Antが`<exec>`、`<apply>`、`<java>`タスクなどを使用して新しいプロセスをフォークする場合、標準入力から読み取り、読み取ったすべてをそのプロセスに送信する新しいスレッドも開始します。

残念ながら、Antはフォークされたプロセスがいつ入力を読み取るのかを知る方法がないため、プロセスがスレッドを必要としなくても、そのようなスレッドを開始します。

この動作により、Unix系システムで新しいプロセスをフォークするビルドがバックグラウンドプロセスとして実行された場合にAntプロセスが中断される、または`<exec>`タスクの後に`<input>`タスクが追加の入力を要求するなど、奇妙な副作用が発生します。

幸いなことに、この問題に対する回避策があります。フォークされたプロセスが入力を消費しないことがわかっている場合は、すべての`<exec>`タスク(またはその兄弟タスクのいずれか)に`inputstring=""`を常に指定します。

`<javac>`によってStackOverflowErrorが発生します。

一部のJavaソースファイルでは、Sunのjavacコンパイラ内でStackOverlowErrorが発生する可能性があります。私たちの知る限り、これはAntのバグによってトリガーされるものではありません。

`<javac>`の`fork`属性を`true`に設定することで、この問題を回避できます。

Ant 1.7.0は、JUnitなしではソースからビルドできません。

junit.jarなしでAnt 1.7.0をソースリリースからビルドしようとすると、「JUnitがないとテストjarをビルドできません」というメッセージが表示されてビルドが失敗します。

Ant 1.7.0では、ant-testutil.jarを配布の一部として追加するようになりました。これにより、少なくともバージョン1.7.0では、JUnitへのハード依存関係が生じます。残念ながら、インストールドキュメントにはその旨が記載されていません。

2つの回避策があります。

  1. Antをビルドするときに、junit.jarをCLASSPATHに追加します。
  2. Antのビルドファイルを変更し、dist-liteターゲットのdependsリストからtest-jarを削除します。

Unix上のAnt 1.3では、<chmod>または<exec>が機能しません。

`ANT_HOME/bin`にある`antRun`スクリプトは、Unixの改行ではなくDOSの改行を使用しています。このファイルからキャリッジリターン文字を削除する必要があります。これは、Antの`<fixcrlf>`タスクまたは次のようなものを使用して実行できます。

tr -d '\r' < $ANT_HOME/bin/antRun > /tmp/foo
mv /tmp/foo $ANT_HOME/bin/antRun

<style>または<junit>が私の<classpath>を無視します。

Ant 1.7.0以降、<junit>はネストされた<classpath>を尊重します。

これらのタスクは、あなたのclasspath設定を無視しません。あなたは、委任クラスローダーに関する一般的な問題に直面しています。

この質問は、一般的な問題の種類を集約しています。タスクは外部ライブラリを必要とし、ネストされたclasspath要素を使用してこの外部ライブラリを指定できますが、外部ライブラリを`CLASSPATH`に配置するか、`ANT_HOME/lib`に配置しない限り、これは機能しません。

Ant 1.5.xAnt 1.6.xの解決策について説明する前に、いくつかの背景が必要です。

Antでネストされた`<classpath>`を指定すると、Antは指定したパスを使用する新しいクラスローダーを作成します。その後、このクラスローダーから追加のクラスのロードを試みます。

ほとんどの場合(たとえば、<style>または<junit>を使用する場合)、Antは外部ライブラリを直接ロードしません。ロードされたクラスがそうします。

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

Ant 1.7以降、`ant-junit.jar`が存在する場合でも、`<junit>`はAntのスタートアップclasspathに`junit.jar`が存在することを必要としません。

Antのクラスローダーの実装はJavaの委任モデルを使用しています。https://download.oracle.com/javase/6/docs/api/java/lang/ClassLoader.htmlの段落を参照してください。

`ClassLoader`クラスは、クラスとリソースを検索するために委任モデルを使用します。`ClassLoader`の各インスタンスには、関連付けられた親クラスローダーがあります。クラスまたはリソースを見つけるように求められた場合、`ClassLoader`インスタンスは、クラスまたはリソース自体を見つける前に、親クラスローダーにクラスまたはリソースの検索を委任します。ブートストラップクラスローダーと呼ばれる仮想マシンのビルトインクラスローダーには親がありませんが、`ClassLoader`インスタンスの親として機能する場合があります。

可能な解決策は、使用するAntのバージョンによって異なります。次のセクションを参照してください。

<style>または<junit>が私の<classpath>を無視します - Ant 1.5.xバージョン

先に進む前に前のエントリをお読みください。

まず、Antのラッパースクリプト(`ant`または`ant.bat`)は`ANT_HOME/lib`からすべての`.jar`ファイルを`CLASSPATH`に追加するため、「`CLASSPATH`内」とは、この回答の残りの部分では「`CLASSPATH`環境変数または`ANT_HOME/lib`のいずれか」を意味することにします。

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

<junit>タスクをロードする場合に何が起こるかを見てみましょう。Antのクラスローダーは最初にブートストラップクラスローダーに問い合わせ、`CLASSPATH`からクラスのロードを試みます。ブートストラップクラスローダーは、Antのクラスローダーや指定したパスについて何も知りません。

ブートストラップクラスローダーがAntがロードするように要求したクラスをロードできる場合(`optional.jar`が`CLASSPATH`の一部であればできます)、このクラスは`CLASSPATH`からも外部ライブラリのロードを試みます(他に何も知りません)。ライブラリも`CLASSPATH`にある場合を除き、見つかりません。

これを解決するには、2つの主要なオプションがあります。

  1. 必要なすべての外部ライブラリを`CLASSPATH`にも配置します。これはあなたが望むものではないでしょう。そうでなければ、このFAQエントリを見つけることはなかったでしょう。
  2. 外部ライブラリをロードするクラスを`CLASSPATH`から削除します。

これを行う最も簡単な方法は、`ANT_HOME/lib`から`optional.jar`を削除することです。そうすると、すべてのオプションタスクを`<taskdef>`する必要があり、`optional.jar`の新しい場所に指す`<taskdef>`タスクにネストされた`<classpath>`要素を使用する必要があります。また、`<style>`または`<junit>`タスクの`<classpath>`に`optional.jar`の新しい場所を追加することを忘れないでください。

すべてのオプションタスクを`<taskdef>`することを避けたい場合は、ブートストラップクラスローダーを介してロードすべきではないクラスを`optional.jar`から削除し、別のアーカイブに配置する必要があります。この別のアーカイブを`<style>`または`<junit>`タスクの`<classpath>`に追加します。そして、別のアーカイブが`CLASSPATH`にないことを確認してください。

<junit>の場合、`org/apache/tools/ant/taskdefs/optional/junit`ディレクトリにあるすべてのクラスを削除する必要があります。<style>の場合、`org/apache/tools/ant/taskdefs/optional`にある`*Liaison`クラスの1つです。

<junit>のために`optional.jar`を分割するオプションを使用するか、`ant-junit.jar`を削除する場合でも、ネストされた`<classpath>`を使用して`<taskdef>`を使用してjunitタスクを定義する必要があります。

<style>または<junit>が私の<classpath>を無視します - Ant 1.6.xバージョン

先に進む前に一般的なエントリをお読みください。

Ant 1.6.xのラッパースクリプトは、`ANT_HOME/lib`の内容を`CLASSPATH`に追加しなくなりました。代わりに、Antはブートストラップクラスローダーの上にクラスローダーを作成します(この回答の残りの部分ではこれをcoreloaderと呼びます)。これには`ANT_HOME/lib`の内容が含まれています。Antのコアとそのタスクは、このクラスローダーを介してロードされ、ブートストラップクラスローダーを介してロードされません。

これにより、Ant 1.5.xと1.6.xの間にいくつかの小さなが注目すべき違いが生じます。最も重要なのは、`CLASSPATH`の一部であるサードパーティータスクは、Ant 1.6.xでは機能しなくなります。なぜなら、タスクはAntのクラスを見つけることができなくなったからです。ある意味では、これはこのエントリに関するのと同じ問題であり、`ant.jar`が問題の外部ライブラリになっただけです。

このcoreloaderには、`~/.ant/lib`の内容と、Antの`-lib`コマンドライン引数を使用して指定されたファイルまたはディレクトリも含まれています。

<junit>タスクをロードする場合に何が起こるかを見てみましょう。Antのクラスローダーは最初にブートストラップクラスローダーに問い合わせ、`CLASSPATH`からクラスのロードを試みます。ブートストラップクラスローダーは、Antのクラスローダーや指定したパスについて何も知りません。ブートストラップクラスローダーを使用してクラスが見つからない場合、次にcoreloaderを試みます。繰り返しますが、coreloaderはあなたのパスについて何も知りません。

coreloaderがAntがロードするように要求したクラスをロードできる場合(`ant-junit.jar`が`ANT_HOME/lib`にある場合にできます)、このクラスはcoreloaderからも外部ライブラリのロードを試みます(他に何も知りません)。ライブラリも`CLASSPATH`またはcoreloaderにある場合を除き、見つかりません。

これを解決するには、次の主要なオプションがあります。

  1. 必要なすべての外部ライブラリを`CLASSPATH`にも配置します。これはあなたが望むものではないでしょう。そうでなければ、このFAQエントリを見つけることはなかったでしょう。
  2. 必要なすべての外部ライブラリを`ANT_HOME/lib`または`.ant/lib`に配置します。おそらくこれはまだあなたが望むものではないでしょうが、`.ant/lib`オプションを再考するかもしれません。
  3. `-lib`コマンドラインスイッチを使用してAntを常に開始し、外部ライブラリ(またはそれらを保持するディレクトリ)を指定します。
  4. 外部ライブラリをロードするクラスをcoreloaderから削除します。

Ant 1.6では、optional.jarが複数のjarファイルに分割されました。それぞれが外部ライブラリに対する同じ依存関係を持つクラスを含んでいます。「問題のある」jarファイルをANT_HOME/libから移動できます。<junit>タスクの場合、それはant-junit.jarになります。

そうした場合、外部ライブラリを必要とするすべてのオプションタスクに対して<taskdef>を行う必要があり、ant-*.jarの新しい場所に指すネストされた<classpath>要素を<taskdef>タスクで使用します。また、<style>または<junit>タスクの<classpath>ant-*.jarの新しい場所を追加することを忘れないでください。

例:

    <taskdef name="junit"
            class="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask">
      <classpath>
        <pathelement location="HOME-OF/junit.jar"/>
        <pathelement location="NEW-HOME-OF/ant-junit.jar"/>
      </classpath>
    </taskdef>

Ant 1.6でカスタムタスクコンテナがUnknown Elementsを認識するようになったのはなぜですか?Ant 1.5では動作していました。

TaskContainer.addTask(Task task)に追加されたオブジェクトは、TaskからUnknownElementsに変更されました。

この変更には多くの正当な理由がありました。しかし、後方互換性の問題は、Ant 1.6.0がリリースされた後まで気づかれませんでした。

TaskがUnknownElementかどうかを確認し、performを呼び出してTaskに変換して実行するために、コンテナクラスを変更する必要があります。(apache.tools.ant.taskdefs.Sequentialを参照)

タスクでより多くの処理を行いたい場合は、apache.tools.ant.taskdefs.Antlib#execute()の手法を使用する必要があります。これは1つの1.6メソッド呼び出し(UE#getRealObject())を使用しますが、UE#getTask()を使用する必要があります。これは、タスク以外のもの(fileset id=xのような型)に対してnullを返します。

そのため、タスクを反復処理し、UEの場合は、UE#maybeConfigureとUE#getTask()を使用してタスクに変換します。

        for (Iterator i = tasks.iterator(); i.hasNext();) {
           Task t = (Task) i.next();
           if (t instanceof UnknownElement) {
              ((UnknownElement) t).maybeConfigure();
              t = ((UnknownElement) t).getTask();
              if (t == null) {
                  continue;
              }
           }
           // .... original Custom code
        }
        

このアプローチは、ant1.5とant1.6の両方で動作するはずです。

Mac OS Xでプロジェクトをコンパイルすると、Antが無限ループに陥るか、OutOfMemoryErrorをスローします。

AppleのJava VMは/System/Library/Frameworks/JavaVM.framework/Versions/X.Y.Zにあり、JAVA_HOMEは通常/System/Library/Frameworks/JavaVM.framework/Versions/X.Y.Z/Homeのようになります。

このホームディレクトリ内には、3レベル上(つまり、/System/Library/Frameworks/JavaVM.framework)を指すシンボリックリンクshared_bundleがあります。

ビルドファイルに次のようなfilesetが含まれている場合:

<fileset dir="${java.home}" includes="**/*.jar"/>

Antはshared_bundleシンボリックリンクに従い、インストールされているすべてのVMに再帰的にアクセスします。さらに悪いことに、/System/Library/Frameworks/JavaVM.framework/Versions/X.Y.Z/Homeに入り、同じシンボリックリンクを再び追跡します。

Ant 1.7.1以降のバージョンでは、無限ループを検出しますが、結果のfilesetは特に多くの異なるVMバージョンがインストールされている場合、処理するには大きすぎる可能性があります。この問題は、インストールされている各バージョンにshared_bundleシンボリックリンクが含まれているという事実によって悪化します。

1つの解決策は、次のようにfilesetがシンボリックリンクをまったく追跡しないようにすることです。

<fileset dir="${java.home}" includes="**/*.jar" followsymlinks="false"/>

もう1つは、shared_bundleディレクトリを除外することです。

<fileset dir="${java.home}" includes="**/*.jar" excludes="**/shared_bundle/**"/>

Ant 1.7.1以前では、shared_bundleを除外しても十分ではない場合があります。Homeディレクトリを指す別のシンボリックリンクbundleがあり、これも無限再帰を引き起こす可能性があるためです。

ドキュメントに記載されているように、extension-pointimportと動作しません。

はい、Ant 1.8.0のバグがあります。

次のような2つのビルドファイルを使用する場合:

importing.xml:
<project>
   ...
   <import file="imported.xml"/>
   <target name="bar" extensionOf="foo"/>
</project>
imported.xml:
<project>
   <extension-point name="foo"/>
</project>

Ant 1.8.0は、「foo」という名前の拡張ポイントがないと主張して失敗します。

このバグはAnt 1.8.1で修正されました。Ant 1.8.0には、回避策があります。次のようにインポートの追加レイヤーを追加します。

importing.xml:
<project>
   <target name="bar" extensionOf="foo"/>
</project>
imported.xml:
<project>
   <extension-point name="foo"/>
</project>
build.xml:
<project>
   <import file="imported.xml"/>
   <import file="importing.xml"/>
</project>

javadocの脆弱性CVE-2013-1571をどのように処理しますか?

Java 7 update 25より前のすべてのOracle JDKのjavadocツールによって生成されたJavadocに、フレームインジェクションのバグがあります。

JDKをアップグレードできない場合は、Oracleが提供するpatchtoolを使用できます。あるいは、Issue 55132の一部として提供されるmacrodefをビルドプロセスの 一部として使用できます。

Ant 1.9.2は、javadocタスクの一部として生成されたjavadocを後処理します。