作成 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 タグライブラリを自作した場合のクラスパスへの含め方
ふ〜ん、という印象です。どうでしょう?