Developing with Ant

Antでの開発

Writing Your Own Task

独自タスクの記述

It is very easy to write your own task:

独自のタスクを記述することは、以下に示すように非常に簡単です。

  1. Create a Java class that extends org.apache.tools.ant.Task or another class that was desgined to be extended.
  2. For each attribute, write a setter method. The setter method must be a public void method that takes a single argument. The name of the method must begin with set, followed by the attribute name, with the first character of the name in uppercase, and the rest in lowercase. That is, to support an attribute named file you create a method setFile. Depending on the type of the argument, Ant will perform some conversions for you, see below.
  3. If your task shall contain other tasks as nested elements (like parallel), your class must implement the interface org.apache.tools.ant.TaskContainer. If you do so, your task can not support any other nested elements. See below.
  4. If the task should support character data (text nested between the start end end tags), write a public void addText(String) method. Note that Ant does not expand properties on the text it passes to the task.
  5. For each nested element, write a create, add or addConfigured method. A create method must be a public method that takes no arguments and returns an Object type. The name of the create method must begin with create, followed by the element name. An add (or addConfigured) method must be a public void method that takes a single argument of an Object type with a no-argument constructor. The name of the add (addConfigured) method must begin with add (addConfigured), followed by the element name. For a more complete discussion see below.
  6. Write a public void execute method, with no arguments, that throws a BuildException. This method implements the task itself.
  1. org.apache.tools.ant.Taskクラスか 拡張可能に設計された他のクラスを 継承してJavaクラスを作成します。
  2. 各属性に対して、setterメソッドを記述します。 setterメソッドは、単一の引数を持つpublic voidメソッドでなくてはなりません。 メソッドの名前はsetで始まり、その後の最初の一文字を大文字に、残りを小文字にした属性名が来なくてはなりません。 すなわち、fileという名前の属性をサポートするためには、 setFileメソッドを作成します。 引数の型に依存して、Antは以下のようないくつかの変換を行います。
  3. タスクが(parallelのような)ネストした要素として他のタスクを含む場合は、 インターフェイスorg.apache.tools.ant.TaskContainerを 実装しなければなりません。 そうすれば、作成したタスクは他のネストした要素をサポートする必要がなくなります。以下を見てください。
  4. テキストデータ(startとendタグで囲まれたテキスト)をサポートすべきタスクは、 public void addText(String)メソッドを記述します。 Antはタスクに渡されたテキストのプロパティーを展開しないことに注意してください。
  5. ネストした要素それぞれに対しては、createaddaddConfiguredメソッドを記述します。 createメソッドは、引数を持たずにObject型を返すpublicメソッドでなければなりません。 createメソッドの名前は、createで始まり、その後に要素名が来なくてはなりません。 add(または、addConfigured)メソッドは、引数なしのコンストラクターを持つObject型の単一の引数をとる、public voidでなければなりません。 add(または、addConfigured)メソッドの名前は、add (addConfigured)ではじまり、その後に要素名が来なくてはなりません。 詳細な記述は、以下を見てください。
  6. 引数を持たず、BuildExceptionをthrowする、public void executeメソッドを記述します。このメソッドはタスク自身を実装します。

The Life-cycle of a Task

タスクのライフサイクル

  1. The task gets instantiated using a no-argument constructor, at parser time. This means even tasks that are never executed get instantiated.
  2. The task gets references to its project and location inside the buildfile via its inherited project and location variables.
  3. If the user specified an id attribute to this task, the project registers a reference to this newly created task, at parser time.
  4. The task gets a reference to the target it belongs to via its inherited target variable.
  5. init() is called at parser time.
  6. All child elements of the XML element corresponding to this task are created via this task's createXXX() methods or instantiated and added to this task via its addXXX() methods, at parser time.
  7. All attributes of this task get set via their corresponding setXXX methods, at runtime.
  8. The content character data sections inside the XML element corresponding to this task is added to the task via its addText method, at runtime.
  9. All attributes of all child elements get set via their corresponding setXXX methods, at runtime.
  10. execute() is called at runtime. While the above initialization steps only occur once, the execute() method may be called more than once, if the task is invoked more than once. For example, if target1 and target2 both depend on target3, then running 'ant target1 target2' will run all tasks in target3 twice.
  1. タスクは、解析時に引数を持たないコンストラクタを使ってインスタンス化されます。 これは、決して実行されないタスクであっても、インスタンス化されることを意味しています。
  2. タスクは継承したprojectlocation変数によって、そのプロジェクトに対する参照とビルドファイル内の位置を取得します。
  3. ユーザーが、タスクにid属性を指定した場合には、プロジェクトは解析時にこの新しく作成したタスクに対する参照を登録します。
  4. タスクは継承したtarget変数によって、属しているターゲットへの参照を取得します。
  5. 解析時にinit()が呼ばれます。
  6. 解析時に、このタスクに対応するすべてのXML要素の子要素は、createXXX()メソッドによって作成されるか、addXXX()メソッドによって、インスタンス化され追加されます。
  7. 実行時に、このタスクのすべての属性は、対応するsetXXXメソッドによってセットされます。
  8. 実行時に、このタスクに対応するXML要素内の、内容のテキストデータ部分は、 addTextメソッドによってタスクに追加されます。
  9. 実行時に、すべての子要素のすべての属性は、setXXXメソッドによってセットされます。
  10. 実行時に、execute()が呼び出されます。 上の中で、初期化ステップは1度だけ行われ、 タスクが 2回以上実行される場合は、execute()メソッドは 2回以上呼ばれます 例えば、target1target2の両方がtarget3に依存している場合、'ant target1 target2'を実行すると、target3のすべてのタスクは2回実行されます。

Conversions Ant will perform for attributes

Antが行う属性の変換

Ant will always expand properties before it passes the value of an attribute to the corresponding setter method.

Antは常に、属性の値を対応するセッタメソッドで渡す前に、プロパティーを展開します。

The most common way to write an attribute setter is to use a java.lang.String argument. In this case Ant will pass the literal value (after property expansion) to your task. But there is more! If the argument of you setter method is

属性のセッタを記述する最も一般的な方法は、java.lang.String引数を使うことです。この場合、Antはあなたのタスクに(プロパティーを展開した後に)リテラルの値を渡します。しかし、あなたのセッタメソッドで渡すことのできる引数は、以下のようにもっとあります!

What happens if more than one setter method is present for a given attribute? A method taking a String argument will always lose against the more specific methods. If there are still more setters Ant could chose from, only one of them will be called, but we don't know which, this depends on the implementation of your Java virtual machine.

与えられた属性のための、2つ以上のセッタメソッドが提供されている場合、どうなるでしょうか?String引数をとるメソッドは、もっと明確な引数のメソッドに、常に負けます。Antが選択できるメソッドが、他にもあった場合、そのうちの1つだけが呼ばれます。しかし、私たちはどのメソッドが呼ばれるかは分かりません。これは、あなたのJava仮想マシンの実装に依存しています。

Supporting nested elements

ネストした要素のサポート

Let's assume your task shall support nested elements with the name inner. First of all, you need a class that represents this nested element. Often you simply want to use one of Ant's classes like org.apache.tools.ant.types.FileSet to support nested fileset elements.

innerという名前のネストした要素をサポートする場合を考えてみましょう。 まず最初に、このネストした要素を表すクラスが必要です。 多くの場合、単にネストしたfileset要素をサポートするために org.apache.tools.ant.types.FileSetのような、Antのクラスの一つを使いたいだけでしょう。

Attributes of the nested elements or nested child elements of them will be handled using the same mechanism used for tasks (i.e. setter methods for attributes, addText for nested text and create/add/addConfigured methods for child elements).

ネストした要素の属性やネストした子要素は、タスクに使われるのと同じ機構を 使って操作されます (例えば、属性のセッタメソッド、ネストしたテキストのためのaddText、や子要素のためのcreate/add/addConfiguredメソッドなど)。

Now you have a class NestedElement that is supposed to be used for your nested <inner> elements, you have three options:

現在、ネストした<inner>要素をサポートする NestedElementを作る場合、次の3つの選択肢があります。

  1. public NestedElement createInner()
  2. public void addInner(NestedElement anInner)
  3. public void addConfiguredInner(NestedElement anInner)

What is the difference?

違いは何でしょう?

Option 1 makes the task create the instance of NestedElement, there are no restrictions on the type. For the options 2 and 3, Ant has to create an instance of NestedInner before it can pass it to the task, this means, NestedInner must have a public no-arg constructor. This is the only difference between options 1 and 2.

選択肢1はNestedElementのインスタンスを作成するタスクを作ります。この型に制限はありません。 選択肢2と3では、タスクに渡される前に AntはNestedInnerのインスタンスを作らなければなりません。 つまり、NestedInnerは、publicで引数のない コンストラクタを持たなければなりません。 これが選択肢1と2の唯一の違いです。

The difference between 2 and 3 is what Ant has done to the object before it passes it to the method. addInner will receive an object directly after the constructor has been called, while addConfiguredInner gets the object after the attributes and nested children for this new object have been handled.

2と3の違いは、メソッドにオブジェクトが渡される前に、Antがオブジェクトに対して何を行うかです。 addInnerは、コンストラクタが呼ばれた後、オブジェクトを直接受け取ります。 addConfiguredInnerは、この新しいオブジェクトの 属性や子要素が操作されたに、オブジェクトを取得します。

What happens if you use more than one of the options? Only one of the methods will be called, but we don't know which, this depends on the implementation of your Java virtual machine.

この選択肢のうちの2つ以上を使った場合、どうなるでしょう? メソッドのうちの1つが呼ばれます。 しかし、どれが呼ばれるかはわかりません。 これは、あなたが使用するJava仮想マシンに依存します。

TaskContainer

The TaskContainer consists of a single method, addTask that basically is the same as an add method for nested elements. The task instances will be configured (their attributes and nested elements have been handled) when your task's execute method gets invoked, but not before that.

TaskContainerは、ネストした要素のためのadd methodと基本的に同じ、addTaskという単一のメソッドから成ります。あなたのタスクのexecuteメソッドが実行された時に、タスクのインスタンスは設定されます(属性やネストした要素が操作されます)。executeが実行される前ではありません。

When we said execute would be called, we lied ;-). In fact, Ant will call the perform method in org.apache.tools.ant.Task, which in turn calls execute. This method makes sure that Build Events will be triggered. If you execute the task instances nested into your task, you should also invoke perform on these instances instead of execute.

executeが呼ばれたときと言いましたが、 うそをつきました;-)。 実際は、executeのあとに、 Antはorg.apache.tools.ant.Taskperformメソッドを呼ぶでしょう。 このメソッドは必ず、Build Eventsをトリガーとします。 あなたのタスクの中でネストしたタスクを実行するとき、 executeメソッドの代わりに、インスタンスの performも実行しなければなりません。

Example

Let's write our own task, which prints a message on the System.out stream. The task has one attribute, called message.

System.outストリームに、メッセージを出力する 独自のタスクを書いてみましょう。 このタスクはmessageという一つの属性を持ちます。

package com.mydomain;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

public class MyVeryOwnTask extends Task {
    private String msg;

    // The method executing the task
    public void execute() throws BuildException {
        System.out.println(msg);
    }

    // The setter for the "message" attribute
    public void setMessage(String msg) {
        this.msg = msg;
    }
}

It's really this simple ;-)

これは本当に簡単です ;-)

Adding your task to the system is rather simple too:

システムにあなたのタスクを追加することも、もっと簡単です。

  1. Make sure the class that implements your task is in the classpath when starting Ant.
  2. Add a <taskdef> element to your project. This actually adds your task to the system.
  3. Use your task in the rest of the buildfile.
  1. Antを開始するときに、あなたのタスクを実装したクラスが、クラスパスに含まれているか確認してください。
  2. <taskdef>要素をあなたのプロジェクトに追加してください。 これは実際、システムにあなたのタスクを追加します。
  3. ビルドファイルの残りの場所で、あなたのタスクを使ってください。

Example

<?xml version="1.0"?>

<project name="OwnTaskExample" default="main" basedir=".">
  <taskdef name="mytask" classname="com.mydomain.MyVeryOwnTask"/>

  <target name="main">
    <mytask message="Hello World! MyVeryOwnTask works!"/>
  </target>
</project>

Example 2

例 2

To use a task directly from the buildfile which created it, place the <taskdef> declaration inside a target after the compilation. Use the classpath attribute of <taskdef> to point to where the code has just been compiled.

タスクを作ったビルドファイルから、直接タスクを使うには、 コンパイルより後のターゲットの内側に <taskdef>宣言をします。 コードがコンパイルされた場所を示すために <taskdef>classpath属性を使ってください。

<?xml version="1.0"?>

<project name="OwnTaskExample2" default="main" basedir=".">

  <target name="build" >
    <mkdir dir="build"/>
    <javac srcdir="source" destdir="build"/>
  </target>

  <target name="declare" depends="build">
    <taskdef name="mytask"
        classname="com.mydomain.MyVeryOwnTask"
        classpath="build"/>
  </target>

  <target name="main" depends="declare">
    <mytask message="Hello World! MyVeryOwnTask works!"/>
  </target>
</project>

Another way to add a task (more permanently), is to add the task name and implementing class name to the default.properties file in the org.apache.tools.ant.taskdefs package. Then you can use it as if it were a built-in task.

タスクを追加するもう1つの(もっと永続的な)方法は、 タスクの名前と実装クラスの名前を org.apache.tools.ant.taskdefsパッケージの default.propertiesファイルに追加することです。 そうすれば、組み込みタスクのように、独自タスクを使うことができます。


Build Events

ビルドイベント

Ant is capable of generating build events as it performs the tasks necessary to build a project. Listeners can be attached to Ant to receive these events. This capability could be used, for example, to connect Ant to a GUI or to integrate Ant with an IDE.

Antは、プロジェクトのビルドに必要なタスクの実行のための、ビルドイベントを生成することができます。 イベントを受け取るリスナーをAntに取り付けることができます。 この機能は、例えば、AntをGUIに接続したり、AntをIDEに統合するときに使うことができます。

To use build events you need to create an ant Project object. You can then call the addBuildListener method to add your listener to the project. Your listener must implement the org.apache.tools.antBuildListener interface. The listener will receive BuildEvents for the following events

ビルドイベントを使うためには、AntのProjectオブジェクトを作成する必要があります。 そして、プロジェクトにあなたのリスナーを追加するために addBuildListenerを呼びます。 リスナーはorg.apache.tools.antBuildListenerインターフェイスを実装しなければなりません。 リスナーは次のようなビルドイベントを受け取ります。

If you wish to attach a listener from the command line you may use the -listener option. For example:

コマンドラインから、リスナーを追加したい場合、 -listenerオプションを使うことができます。 例えば:

ant -listener org.apache.tools.ant.XmlLogger

will run Ant with a listener that generates an XML representation of the build progress. This listener is included with Ant, as is the default listener, which generates the logging to standard output.

これは、ビルドの進行を表示するXMLを生成するリスナーをつけて、Antを実行します。このリスナーはAntに含まれるデフォルトのリスナーで、標準出力へのログを生成します。


Source code integration

ソースコードの統合

The other way to extend Ant through Java is to make changes to existing tasks, which is positively encouraged. Both changes to the existing source and new tasks can be incorporated back into the Ant codebase, which benefits all users and spreads the maintenance load around.

JavaでAntを拡張する他の方法は、既存のタスクを変更することで、それはとても推奨されます。 既存のソースに対する各変更や、新しいタスクは、Antのコードベースに組み入れることができます。それはすべてのユーザーの利益になり、全体の負担の量を拡散させます。

Please consult the Getting Involved pages on the Jakarta web site for details on how to fetch the latest source and how to submit changes for reincorporation into the source tree.

どうぞ、JakarataウェブサイトのGetting Involvedページを調べてみてください。 共同で利用されるソースツリーに対して、どのように最新のソースを取得するか、どのように変更を提出するかの詳細が書かれています。

Ant also has some task guidelines which provides some advice to people developing and testing tasks. Even if you intend to keep your tasks to yourself, you should still read this as it should be informative.

Antはまた、いくつかのタスクのガイドラインをもっています。 ガイドラインは、タスクを開発、テストする人々にアドバイスを提供します。 あなたが、独自のタスクを自分だけで使おうとする場合でも、有益な情報が書かれているので、ガイドラインを是非読むべきです。


Copyright © 2000-2002 Apache Software Foundation. All rights Reserved.

[訳注:これは風間一洋、宮本信二が翻訳しました。日本語訳に対するコメントがあれば report@jajakarta.orgに送ってください]