作成 2002/10/21
MavenついでにJellyも少しだけ触ってみました。
JellyはXMLベースのスクリプトエンジンです。スクリプト言語なんだけど、XMLで記述します。XMLによるスクリプトの記述という特性を生かして、JellyはAnt、JSTL、WebServieといった技術と連携できるようになっています。
バイナリ、ソースアーカイブも一応ありますが、ここでは、ソースリポジトリから最新版を取得してmavenでビルドすることにします。CVSクライアントとMavenが必要になります。
CVSでチェックアウト(方法)
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login Logging in to :pserver:anoncvs@cvs.apache.org:2401:/home/cvspublic CVS password: anoncvs cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic checkout jakarta-commons/jelly
maven test と入力すると単体テストが実行されます。
Jelly本体とタグライブラリはプロジェクトが別になっています。それに伴い、いくつかのサンプルは(jellyフォルダの下にある)jelly-tags以下のプロジェクトに移動しています。各タグライブラリのデモ、サンプルは、サブディレクトリに移動してから実行します。
最初に本体の方だけのデモの一つを実行してみましょう。jellyのディレクトリで、次のコマンドを入力します。
maven demo:cmdline
出力結果は次のようになります。
demo:cmdline:
[java] -a option = valueOfA
[java] -b option = valueOfB
[java] -c option = valueOfC
[java] -testsysprop = valueOfTestSystemProp
BUILD SUCCESSFUL
Total time: 4 seconds
Finished at: Wed Oct 22 00:39:22 JST 2003
maven.xmlのdemo:cmdlineゴールを見ると、org.apache.commons.jelly.Jellyクラスを、testCmdLineOptions.jellyというjellyのスクリプトファイル、およびその他の引数を渡して実行しているのがわかります。ふ〜んという感じです。
マニュアルのチュートリアルにもあるswingのデモは、jelly-tags/swingディレクトリから実行します。
maven demo:swing
実行すると、次のようなSwingアプリケーションが起動します。チュートリアルを読むと、Jellyのスクリプトを流し込んでSwingのコンポーネントを作成しているようです。こういうXMLの使い方もアリですね。微妙に感動しました。
swtのデモもあるようなので、試してみました。今度はjelly-tags/swtディレクトリに移動してdemoを実行します。※1
maven demo
※1なお、実行にはswtのdllが必要ですが、maven(gump)の自動ダウンロードだけでは現状dllまで解決出来できないようです。swt-win32-xxxx.dllをライブラリパスに通して(例えばjelly-tags/swtディレクトリにコピーして)、さらにdllの名前も求められているものに変更しておきます(例えば、現状では2128。mavenのリポジトリのswtのjarの中のversion.txtに書いてあるもののようですが、仕組みはよく分かりません)。
swingと似たようなもんですが、swtが動くのに多少感動します。
次はちょっとだけjellyのスクリプトを書いてみます。ちなみに外部JAR依存はここに書いているようにいろいろあるので(コアだけならもっと少ないと思われるが)、どれが必要か探すのも面倒なので、ここでは、実験には先ほどダウンロードしたjellyでなく、mavenのlibにあるjellyを使います。mavenのlib以下全てのjarにクラスパスを通して実験します。
次のJavaプログラムは、jellyスクリプトを記述したファイル(foo.xml)を読み込んで、スクリプトを実行しています。出力は標準出力に行っています。
import org.apache.commons.jelly.JellyContext;
import org.apache.commons.jelly.XMLOutput;
public class Sample1 {
public static void main(String[] args) throws Exception{
XMLOutput output = XMLOutput.createXMLOutput( System.out );
JellyContext context = new JellyContext();
context.runScript( "foo.xml", output );
}
}
次は、読み込むjellyスクリプトの例です(例がイマイチ。coreも使ってないし。。。)。
<?xml version="1.0"?>
<j:jelly xmlns:j="jelly:core">
hello!
</j:jelly>
実行するとhello!と表示されます。
次に、jellyのページの最初に紹介されている、JavaBeansをタグライブラリとしてjelly上で使うということをやってみます。まず、簡単なクラスを作ります。このクラスはmessageセッタを持っています。
EchoBean.java
public class EchoBean {
private String message;
public void setMessage(String message){
this.message = message;
}
public void run(){
System.out.println(message);
}
}
このクラスを使うjellyスクリプトは次のようになります。defineタグライブラリを使います。なお、jellyのタグライブラリのリファレンスは、jellyドキュメントのFeaturesのCore Tags、およびTag Librariesにあります。
<?xml version="1.0"?>
<j:jelly xmlns:j="jelly:core"
xmlns:define="jelly:define"
xmlns:my="myTagLib">
<define:taglib uri="myTagLib">
<define:jellybean name="echo" className="EchoBean"/>
</define:taglib>
<my:echo message="hello!"/>
</j:jelly>
先ほどのJavaアプリケーションから実行すると、これもhello!と表示されます。
次の例では、タグのボディ部分も評価しています。
import org.apache.commons.jelly.JellyTagException;
import org.apache.commons.jelly.TagSupport;
import org.apache.commons.jelly.XMLOutput;
public class RoopTag extends TagSupport{
private int count;
public void setCount(int count){
this.count = count;
}
public void doTag(XMLOutput output) throws JellyTagException {
for(int i=0; i<count; i++){
getBody().run( context, output );
}
}
}
jellyスクリプトは次のようになります。
<?xml version="1.0"?>
<j:jelly xmlns:j="jelly:core"
xmlns:define="jelly:define"
xmlns:my="myTagLib">
<define:taglib uri="myTagLib">
<define:jellybean name="echo" className="EchoBean"/>
<define:jellybean name="roop" className="RoopTag"/>
</define:taglib>
<my:echo message="hello!"/>
<my:roop count="3">
<my:echo message="abc"/>
</my:roop>
</j:jelly>
実行するとabcが 3回表示されます。
AntからJellyを実行するには、JellyTaskクラスをtaskdefして使います。Jellyと依存JARおよび、自作したクラスにクラスパスを通しています。
<project default="hoge">
<path id="task.path">
<fileset dir="C:/app/maven-1.0-rc1/lib">
<include name="*.jar"/>
</fileset>
<pathelement location="bin"/>
</path>
<taskdef name="jelly" classname="org.apache.commons.jelly.task.JellyTask"
classpathref="task.path"/>
<target name="hoge">
<jelly script="file:/C:/app/maven-proj/jelly/jakarta-commons/jelly/jelly-test/hoge.xml"/>
</target>
</project>
@TODO ビルドファイルに直接書き込めないものだろうか。。。
そのままjellyスクリプトを記述して利用できます。
<goal name="hoge">
<j:jelly xmlns:j="jelly:core" >
...
</j:jelly>
</goal>
@TODO タグライブラリを自作した場合のクラスパスへの含め方
ふ〜ん、という印象です。どうでしょう?