Apache BSFまたはJSR 223でサポートされている言語でスクリプトを実行します。
注記: このタスクは、Apache Ant配布物に含まれていない外部ライブラリに依存しています。詳細については、ライブラリ依存関係を参照してください。
このタスクは、BSFスクリプティングマネージャーまたはJDKに含まれるJSR 223マネージャーを使用できます。これは、manager属性によって制御されます。JSR 223スクリプティングマネージャーはjavax
で示されます。
実行中のプロジェクトのすべてのアイテム(タスク、ターゲットなど)は、それらのname属性またはid属性を使用してスクリプトからアクセスできます(それらの名前が有効なJava識別子と見なされる限り)。これは、タスクのsetbeans属性によって制御されます。名前projectはプロジェクトへの事前に定義された参照であり、プロジェクト名の代わりに使用できます。名前selfは実際の<script>タスクインスタンスへの事前に定義された参照です。
これらのオブジェクトから、Ant Java APIにアクセスできます。JavaDoc(特にProjectとScript)を参照して詳細を確認してください。
BSFでJavaScriptを使用している場合、https://www.mozilla.org/rhino/doc.htmlは、それらのJavaScriptインタープリターを使用しているので良いリソースです。
スクリプトは、Javaで記述されたタスクが実行できるほぼすべての操作を実行できます。
Rhinoは、特別な構成要素であるJavaAdapterを提供します。これを使用して、複数のインターフェースを実装し、クラスを拡張し、メソッドをオーバーライドできるオブジェクトを作成できます。これはまだ文書化されていない機能であるため、説明へのリンクを次に示します。Googleグループ:「Rhino、enum.js、JavaAdapter?」(ニュースグループ *netscape.public.mozilla.jseng* のNorris Boydによる)。
ターゲットをプログラムで作成する場合は、場所を有効な値に設定してください。特に、すべてのターゲットは異なる場所の値を持つ必要があります。
| 属性 | 説明 | 必須 |
|---|---|---|
| language | スクリプトが記述されているプログラミング言語。サポートされているApache BSFまたはJSR 223言語である必要があります。 | はい |
| manager |
Ant 1.7以降。使用するスクリプトエンジンマネージャー。これはauto、 bsf、 javaxの3つの値のいずれかになります。
|
いいえ。デフォルトはauto |
| src | インラインではない場合、ファイルとしてのスクリプトの場所。 | いいえ |
| encoding | ファイルとしてのスクリプトのエンコーディング。Ant 1.10.2以降。 | いいえ。デフォルトはJVMのデフォルト文字エンコーディング。 |
| setbeans | この属性は、実行中のスクリプト内のすべてのプロパティ、参照、ターゲットの変数を設定するかどうかを制御します。この属性がfalseの場合、 projectおよびself変数のみが設定されます。この属性がtrueの場合、すべての変数が設定されます。Ant 1.7以降 |
いいえ。デフォルトはtrue |
| classpath | スクリプトに渡すクラスパス。Ant 1.7以降 | いいえ |
| classpathref | 別の場所で定義されたパスへの参照として指定された、使用するクラスパス。Ant 1.7以降 | いいえ |
Ant 1.7以降
Scriptのclasspath属性はパスのような構造であり、ネストされた<classpath>要素でも設定できます。
クラスパスが設定されている場合、それは現在のスレッドコンテキストクラスローダーとして、そしてBSFマネージャーに渡されるクラスローダーとして使用されます。これは、BSFまたはJSR 223マネージャーの言語実装を含むクラスパスを指定するために使用できることを意味します。これは、${user.home}/.ant/libに多くのスクリプト言語固有のjarファイルを置かないようにしたい場合に役立ちます。
注記:(Ant 1.7.1以降)このクラスパスは、BSF jarファイルの場所、およびBSF jarファイルにエンジンを持つ言語を指定するために使用できます。これには、javascript
、jython
、netrexx
、jacl
言語が含まれます。
次のスニペットは、5つの異なる言語の使用を示しています。
<property name="message" value="Hello world"/>
<script language="groovy">
println("message is " + message)
</script>
<script language="beanshell">
System.out.println("message is " + message);
</script>
<script language="judoscript">
println 'message is ', message
</script>
<script language="ruby">
print 'message is ', $message, "\n"
</script>
<script language="jython">
print "message is %s" % message
</script>
jython
の例では、スクリプトの内容は必ず最初の列から始める必要があります。
ruby
の例では、設定された変数の名前には$
が接頭辞として付加されます。
次のスクリプトは、もう少し複雑なJRubyの例を示しています。
<script language="ruby">
xmlfiles = Dir.new(".").entries.delete_if { |i| ! (i =~ /\.xml$/) }
xmlfiles.sort.each { |i| $self.log(i) }
</script>
Groovyでの同じ例は次のとおりです。
<script language="groovy">
xmlfiles = new java.io.File(".").listFiles().findAll{ it =~ "\.xml$"}
xmlfiles.sort().each { self.log(it.toString()) }
</script>
次の例は、クラスパスを使用してbeanshell jarファイルの場所を指定する方法を示しています。
<script language="beanshell" setbeans="true">
<classpath>
<fileset dir="${user.home}/lang/beanshell" includes="*.jar"/>
</classpath>
System.out.println("Hello world");
</script>
次のスクリプトは、JavaScriptを使用して複数のechoタスクを作成し、実行します。
<project name="squares" default="main" basedir=".">
<target name="main">
<script language="javascript"> <![CDATA[
for (i = 1; i <= 10; i++) {
echo = squares.createTask("echo");
echo.setMessage(i*i);
echo.perform();
}
]]> </script>
</target>
</project>
生成します
main: 1 4 9 16 25 36 49 64 81 100 BUILD SUCCESSFUL
次に、Java APIとAnt APIを使用したより複雑な例を示します。目標は、<fileset/>が検出したすべてのファイルのファイルサイズを一覧表示することです。
<?xml version="1.0" encoding="UTF-8"?> <project name="MyProject" basedir="." default="main"> <property name="fs.dir" value="src"/> <property name="fs.includes" value="**/*.txt"/> <property name="fs.excludes" value="**/*.tmp"/> <target name="main"> <script language="javascript"> <![CDATA[ // import statements // importPackage(java.io); importClass(java.io.File); // Nashorn syntax // load("nashorn:mozilla_compat.js"); // or // var File = Java.type('java.io.File'); // Access to Ant-Properties by their names dir = project.getProperty("fs.dir"); includes = MyProject.getProperty("fs.includes"); excludes = self.getProject().getProperty("fs.excludes"); // Create a <fileset dir="" includes=""/> fs = project.createDataType("fileset"); fs.setDir(new File(dir)); fs.setIncludes(includes); fs.setExcludes(excludes); // Get the files (array) of that fileset ds = fs.getDirectoryScanner(project); srcFiles = ds.getIncludedFiles(); // iterate over that array for (i = 0; i < srcFiles.length; i++) { // get the values via Java API var basedir = fs.getDir(project); var filename = srcFiles[i]; var file = new File(basedir, filename); var size = file.length(); // create and use a Task via Ant API echo = MyProject.createTask("echo"); echo.setMessage(filename + ": " + size + " byte"); echo.perform(); } ]]></script> </target> </project>
Java APIを使用したいと考えています。パッケージのシグネチャを常に入力したくないため、インポートを行います。Rhinoはインポートステートメントに2つの異なるメソッドを知っています。1つはパッケージ用、もう1つは単一のクラス用です。デフォルトでは、javaパッケージのみが使用可能であるため、java.lang.SystemはimportClass/importPackageで直接インポートできます。他のパッケージの場合は、完全な分類名にPackagesを接頭辞として付ける必要があります。たとえば、AntのFileUtilsクラスはimportClass(Packages.org.apache.tools.ant.util.FileUtils)でインポートできます。
Java 8からJava 14までは、Rhino(Java 7ランタイムで使用可能)ではなく、ビルトインのNashorn JavaScriptエンジンを使用できます。その後、任意のJavaクラスまたは互換性のあるスクリプトのインポートステートメントとしてJava.typeを使用します。load("nashorn:mozilla_compat.js");。
Java 15以降、Nashornは削除され、外部JavaScriptエンジンを提供する必要があります。おそらく最適な選択肢はGraalVM JavaScriptですが、多くの追加のjarを追加する必要があります。GraalVM JavaScript 20.1では、org.graalvm.js:js、org.graalvm.js:js-engineが必要であり、これにはorg.graalvm.regex:regex、org.graalvm.truffle:truffle-api、org.graalvm.sdk:graal-sdk、com.ibm.icu:icu4jが必要です。GraalVM JavaScriptはNashornの直接的な代替品ではなく、GraalのNashorn移行ガイドで詳細を確認してください。
GraalVM JavaScriptを使用する場合、AntはスクリプトがAntオブジェクトを使用できるように、機能polyglot.js.allowAllAccessを有効にします。デフォルトでは、Nashorn互換モードも有効になりますが、マジックAntプロパティant.disable.graal.nashorn.compatをtrueに設定して無効にすることができます。
<script>タスクは、projectという名前でProjectインスタンスを生成するため、その参照を使用できます。別の方法は、指定された名前を使用するか、タスク自体から参照を取得することです。Projectは、プロパティへのアクセスと設定、DataTypeとTaskの作成など、多くのメソッドを提供します。
FileSetオブジェクトを作成した後、setメソッドを呼び出して初期化します。その後、通常のAntタスク(たとえば<copy>)のようにそのオブジェクトを使用できます。
ファイルのサイズを取得するには、java.io.Fileをインスタンス化します。ここでは通常のJava APIを使用しています。
最後に、<echo>タスクを使用して出力を生成します。タスクはexecute()メソッドによって実行されません。これは、perform()メソッド(Task自体で実装)がexecute()を呼び出す前後に適切なログ記録を行うためです。
次に、beanshellを使用してAntタスクを作成する例を示します。このタスクは、参照されたパスにfilesetとパスを追加します。パスが存在しない場合は、作成されます。
<!--
Define addtopath task
-->
<script language="beanshell">
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.FileSet;
public class AddToPath extends Task {
private Path path;
public void setRefId(String id) {
path = getProject().getReference(id);
if (path == null) {
path = new Path(getProject());
getProject().addReference(id, path);
}
}
public void add(Path c) {
path.add(c);
}
public void add(FileSet c) {
path.add(c);
}
public void execute() {
// Do nothing
}
}
project.addTaskDefinition("addtopath", AddToPath.class);
</script>
ディレクトリのリストからパスを作成するためにこのタスクを使用する例(Ant-Contribの<for>タスクを使用)を次に示します。
<path id="main.path">
<fileset dir="build/classes"/>
</path>
<ac:for param="ref" list="commons,fw,lps"
xmlns:ac="antlib:net.sf.antcontrib">
<sequential>
<addtopath refid="main.path">
<fileset dir="${dist.dir}/@{ref}/main"
includes="**/*.jar"/>
</addtopath>
</sequential>
</ac:for>