【コラム】
現在、Javaプラットフォームではスクリプト言語のサポートが急速に進められている。同時に、Java VM上で動作するさまざまなスクリプト言語の実装が登場しており、JavaプラットフォームはすでにJava言語という枠を飛び越え、マルチ言語環境に進化しようとしている。本連載第31回で紹介したBeanShellも、Javaベースのスクリプト言語のひとつだ。
今回取り上げるのは、そのようなさまざまなスクリプト言語とJavaを結びつける役割を果たす「JSR 223: Scripting for the Java Platform」だ。ご存知のように同APIはJava SE 6よりJavaの標準クラスライブラリとして統合されている。JSR 223ではJavaプログラム内で各種スクリプトを実行する、およびスクリプト側からJavaプログラムにアクセスするための標準的な方法が提供される。
JDK 6にはJavaで実装されたJavaScriptエンジンであるRhinoがバンドルされており、標準で利用できるようになっている。その他のスクリプト言語についても対応が進められていて、scripting.dev.java.netで公開されている最新の参照実装には各種エンジンが搭載されている。
まず、JDK 6でJavaScriptを利用する方法をおさらいしておこう。スクリプトの実行にはjavax.script.ScriptEngineクラスを利用する。まずファクトリクラスであるjavax.script.ScriptEngineManagerのインスタンスを生成し、そこからScriptEngineを取得してeval()メソッドでスクリプトを実行すればよい。具体的にはリスト1のようになる。
package apisample;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptingForJavaScript {
public static void main(String[] args) throws Exception {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("js");
try {
engine.eval("print(\"Hello, JavaScript!\")");
} catch (ScriptException ex) {
ex.printStackTrace();
}
}
}
JavaScriptは標準でサポートされているので、ScriptingForJavaScript.javaは通常通りコンパイル/実行できる。
さて、JavaScript以外のスクリプト言語を利用するには別途JSR 223の参照実装を入手しなければならない。最新の実装は前述のプロジェクトサイトにあるドキュメント&ファイルセクションからダウンロードできる。jsr223-engines.zipまたは jsr223-engines.tar.gzを任意の場所 (ここでは[JSR223-ENGINES]と記載する) に解凍して使用する。
配布ファイルにはサポートされるスクリプトエンジン用のフォルダが含まれており、各フォルダ毎に以下の3つのフォルダが用意されている。
そのうちbinとbuildについてはすでに用意されているが、libに格納する実装だけはそれぞれのプロジェクトサイトから別途ダウンロードしてこなければならない。必要とするバージョンについてはREADME.TXTに記載されている。
ここではBeanShellを使用してみる。BeanShellの場合はバージョン2.0 Beta5が必要と書かれているが、BeanShellの公式サイトで配布されている最新版は2.0 Beta4なのでこれを使う。このページよりbsh-2.0b4.jarをダウンロードし、[JSR223-ENGINES]\beanshell\libに配置する。
このbsh-2.0b4.jarとbuildフォルダのbsh-engine.jarをクラスパスに含めることで、JavaプログラムからBeanShellを利用できるようになる。ためしにJDK 6付属のjrunscriptコマンドを使ってみよう。jrunscriptコマンドはqオプションで利用可能なスクリプト言語を調べることができ、lオプションでコマンドラインモードでスクリプトを実行できる(プロンプト1)。
> jrunscript -cp [JSR223-ENGINES]/build/bsh-engine.jar;[JSR223-ENGINES]/lib/bsh-2.0b4.jar -q
Language BeanShell 2.0b5 implemention "BeanShell Engine" 1.0
Language ECMAScript 1.6 implemention "Mozilla Rhino" 1.6 release 2
> jrunscript -cp [JSR223-ENGINES]/build/bsh-engine.jar;[JSR223-ENGINES]/lib/bsh-2.0b4.jar -l bsh
beanshell>
続いてJavaプログラムからBeanShellスクリプトを実行してみよう。手順はJavaScriptの場合とまったく同じで、リスト2のようにする。ここでは簡単なウィンドウを表示させるスクリプトを実行している(第31回参照)。
package apisample;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptingForBeanShell {
public static void main(String[] args) throws Exception {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("bsh");
try {
engine.eval(
"import javax.swing.*;" +
"f = new JFrame(\"BeanShell Sample\");" +
"f.getContentPane().setLayout(new FlowLayout());" +
"button1 = new JButton(\"Hello\");" +
"button2 = new JButton(\"BeanShell!\");" +
"f.getContentPane().add(button1);" +
"f.getContentPane().add(button2);" +
"f.setSize(300, 200);" +
"f.setVisible(true);"
);
} catch (ScriptException ex) {
ex.printStackTrace();
}
}
}
コンパイルおよび実行は、スクリプトエンジンのJARファイルをクラスパスに含めてプロンプト2のように行う。実行するとBeanSehllスクリプトによって図1のようなウィンドウが表示されるはずだ。
> javac -cp ./;[JSR223-ENGINES]/build/bsh-engine.jar;[JSR223-ENGINES]/lib/bsh-2.0b4.jar apisample\ScriptingForBeanShell.java
> java -cp ./;[JSR223-ENGINES]/build/bsh-engine.jar;[JSR223-ENGINES]/lib/bsh-2.0b4.jar apisample.ScriptingForBeanShell
|
|
図1 BeanShellスクリプトによって生成されたウィンドウ |
次に、Javaプログラムからスクリプトのメソッドをコールしてみよう。メソッドのコールには、スクリプトエンジン(ScriptEngine実装)がjavax.script.Invocableインタフェースをimplementsしている必要がある。しかしBeanShellのエンジンはこれをimplementsしていないので(TODOということになっている)、今回はInvocableをサポートしているGroovyを使って試してみることにする。
README.TXTによればGroovyを使うには1.1-beta-2が必要とのことなので、公式サイトのリポジトリより「groovy-all-1.1-beta-2.jar」をダウンロードして[JSR223-ENGINES]\groovy\libに配置する。
プログラムはリスト3のようになる。ここではGroovyスクリプトでadd()メソッドを定義し、それをJavaプログラムからInvocableのinvokeFunction()を利用して呼び出している。
package apisample;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptingForGroovy {
public static void main(String[] args) throws Exception {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("groovy");
String script = "def add(x, y) { x + y }";
try {
engine.eval(script);
Invocable invocable = (Invocable)engine;
Object[] params = { new Integer(50), new Integer(100) };
Object result = invocable.invokeFunction("add", params);
System.out.println(result);
} catch (ScriptException ex) {
ex.printStackTrace();
}
}
}
コンパイルおよび実行は、Groovyのスクリプトエンジンをクラスパスに含めてプロンプト3のように行う。
> javac -cp ./;[JSR223-ENGINES]/build/groovy-engine.jar;[JSR223-ENGINES]/lib/groovy-all-1.1-beta-2.jar apisample\ScriptingForGroovy.java
> java -cp ./;[JSR223-ENGINES]/build/groovy-engine.jar;[JSR223-ENGINES]/lib/groovy-all-1.1-beta-2.jar apisample.ScriptingForGroovy
150
JSR 223を使用すれば、JavaScriptだけでなくさまざまなスクリプト言語を共通の方法で利用できる。今回はBeanShellとGroovyを取り上げたが、ぜひ他のスクリプト言語も試してみてほしい。なお、Java SE 7ではJavaScriptに加えてBeanShellやGroovy、JRubyなどといったスクリプト言語の標準サポートが検討されている。
提供:マイナビ
大学・大学院・短大・専門学生向けの就職情報サイト「マイナビ2010」「マイナビ2009」に今すぐ登録しよう! 大手企業からベンチャー企業までの約13,000社の企業情報を公開、エントリーが可能です。2010年卒予定の方は「マイナビ2010」に、2009年卒予定の方は「マイナビ2009」に登録してください。
毎日コミュニケーションズはプライバシーマークを取得しています。
| 非公式ながらもGrailsで40%の速度改善を確認、Groovy 1.1 RC2登場 [2007/11/6] |
| JavaOne 2007で見たJava SEプラットフォームの現在と未来 [2007/5/10] |
| Tim Bray氏が語る次世代Webテクノロジ - JavaOne 2007 [2007/5/8] |
| Linux Mint 12 KDE登場 [10:26 2/10] |
| Dell、重複排除により最大98%のデータ削減が可能なバックアップストレージを発売 [09:44 2/10] |
| 北大、「ポジトロン断層撮影法」による脳腫瘍の性質を診断する手法を開発 [09:40 2/10] |
| NICTなど、手術支援ロボット「da Vinci」の3D裸眼映像伝送実証実験を計画 [09:36 2/10] |
| TI、再生可能エネルギー向けアプリ開発用マイコン搭載ソーラーキットを発表 [08:00 2/10] |
|
きらら100号記念! ニコニコ静画で「けいおん!」「キルミ」など無料配信開始 [11:04 2/10] ホビー |
|
桜 稲垣早希がエヴァストアの1日店長に就任決定、当日は生中継アリ [11:01 2/10] ホビー |
|
あぁ俺の オタク川柳 予選落ち - 第7回「オタク川柳」投票受付を開始 [11:00 2/10] ネット |
|
沢尻エリカ、5年ぶり主演映画で濡れ場シーンも「腹をくくっています」 [11:00 2/10] エンタメ |
|
上戸彩、後輩の剛力彩芽に「私と顔が似ていません?」- AOKI新CMで共演 [11:00 2/10] エンタメ |