ant1.8の挙動について


antのバージョンが1.5ぐらいの頃に書いたantのビルドファイルが1.8では動かなくなっていたので調査しました。
以下のビルドファイルで再現します。

<?xml version="1.0" encoding="UTF-8" ?>
<project name="test" default="t2" basedir=".">
  <target name="t1">
    <echo message="t1..." />
    <filterset id="filters">
      <filter token="test.greeting" value="こんにちは"/>
    </filterset>
  </target>
  <target name="t2">
    <antcall target="t1" />
    <copy file="sample.txt" tofile="filtered2.sample.txt" filtering="yes">
      <filterset refid="filters"/>
    </copy>
  </target>
</project>
@test.greeting@ を置換します。

実行結果(バージョン1.8)

t2:

t1:
     [echo] t1...
     [copy] Copying 1 file to C:\00projects\ant

BUILD FAILED
C:\00projects\ant\build.xml:11: Reference filters not found.

このように、filtersetのrefidが解決出来ていません。一方、バージョン1.7では成功しますが、警告が出ます。

t2:

t1:
     [echo] t1...
     [copy] Copying 1 file to C:\00projects\ant
Warning: Reference filters has not been set at runtime, but was found during
build file parsing, attempting to resolve. Future versions of Ant may support
 referencing ids defined in non-executed targets.

BUILD SUCCESSFUL

さらに言うと、バージョン1.7では

    <antcall target="t1" />

が無くてもコピーと置換は行われます。つまり、build.xmlに書いてありさえすればfiltersetのrefidを解決出来ています。

この挙動の違いは、1.8.0のリリースノートに書いてある、

  * Remove fall-back mechanism for references that are not resolved
   during normal runtime execution.

が原因のようです。

ところで、normal runtime executionとは何でしょう?例示したビルドファイルでもt1を実行しているのでfiltersetは定義されているようにも思えます。
私が試した範囲では結局のところ以下の二通りが該当するようです。

  1. ターゲットの外で定義する
    <?xml version="1.0" encoding="UTF-8" ?>
    <project name="test" default="t3" basedir=".">
      <filterset id="global.filters">
        <filter token="test.greeting" value="こんばんは"/>
      </filterset>
      <target name="t3">
        <copy file="sample.txt" tofile="filtered3.sample.txt" filtering="yes">
          <filterset refid="global.filters"/>
        </copy>
      </target>
    </project>
    
  2. 依存関係のあるターゲットで定義する
      <target name="t2" depends="t1">
        <copy file="sample.txt" tofile="filtered2.sample.txt" filtering="yes">
          <filterset refid="filters"/>
        </copy>
      </target>
    

二つ目が少し意外だったのでエントリしてみた次第です。


This entry was posted in 技術. Bookmark the permalink.