前回は,Java関連スクリプト言語の概要について説明しました。では実際の使い方を見ていきましょう。

 Java仮想マシン上で動作するスクリプト言語を利用する利点は大きく二つあります。「Javaからスクリプト言語が使える」点と「スクリプト言語からJavaが使える」点です。今回は,前者を取り上げます。

 「Javaからスクリプト言語が使える」とは,Javaのコードの中でスクリプト言語のコードを実行できるということです。これにより,Javaで記述したアプリケーションの動作をスクリプト言語で設定できるようになります。例えば,Emacsの動作をLispで記述できるのと同じように,Javaで書かれたエディタの設定をスクリプト言語で行えるようになります。実際に,RubyのJava実装であるJRubyを組み込んだテキスト・エディタ「erie」(作者はたけぞう氏)があります。また,アプリケーション・サーバーのBEA WebLogic Server 9.0は,PythonのJava実装であるJythonで運用/管理用スクリプトを記述できます。

 今回は例としてJRubyを取り上げます。JRuby自体の完成度は,正直に言ってまだあまり高くありません。ただ,フレームワークRuby on Railsの成功でRubyへの注目が高まっており,「JavaでRubyを使いたい」というニーズはそれなりにあるのではないかと考えられるからです(ちなみにJRubyではまだRuby on Railsは動きません)。

 JRubyを利用するには,JRubyのページからバイナリ・パッケージ(jruby-bin-0.8.x.tar.gz)をダウンロードして解凍します。Windows用とUNIX用の起動スクリプトがそれぞれ用意されており,環境変数(JAVA_HOMEとJRUBY_HOME)を設定するだけですぐに使えます。

 JRubyの用意ができたら,Javaの中でRubyのコードを動かしてみましょう。あらかじめ,JRubyに含まれる「jruby.jar」にクラスパスを通しておいてください。


リスト1●RubyRunner.java

import org.jruby.Ruby;

public class RubyRunner {

  private static String rubyCode = "3.times{|i|p i}";

  public static void main (String[] args) {
    Ruby runtime = org.jruby.Ruby.getDefaultInstance();
    try {
      runtime.evalScript(rubyCode);
    } catch(Exception e) {
      System.err.println(e);
    }
  }
}

 どうでしょうか。とても簡単ですね。JRubyで用意されているRuby型のインスタンスをgetDefaultInstanceメソッドで生成し,evalScriptメソッドを呼び出すだけです。

 この方法の問題点は,汎用性がないことです。他のスクリプト言語を使うときは,改めてスクリプト言語を実行する方法を調べなければなりません。

 そこで「BSF(Bean Scripting Framework)」の出番です。BSFはJavaで様々なスクリプト言語を利用するためのフレームワークです。元々IBMで開発されましたが,現在はオープンソース化され,Apache Jakarta Projectの一つになっています。BSFを使うことで,汎用的なAPIでスクリプト言語を動作させられるようになります。BSFが標準でサポートするスクリプト言語には,Rhino(JavaScript),Jython(Python),Jacl(Tcl)などがあります。独自のBSFエンジンを実装しているものとしては,BeanShell(Javaインタプリタ),JRuby(Ruby),JudoScript,Groovyなどがあります。

 では,BSFを使ってリスト1と同じ動作を実現してみましょう。今度は,jruby.jarに加え,JRubyに含まれる「bsf.jar」にもクラスパスを通しておきます。


リスト2●BSFRunner.java

import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;

public class BSFRunner {

  private static String rubyCode = "3.times{|i|p i}";

  public static void main(String[] args) {
    BSFManager manager = new BSFManager();
    manager.registerScriptingEngine("ruby",
      "org.jruby.javasupport.bsf.JRubyEngine",
      new String[] { "rb" });
    try {
      manager.eval("ruby", "(java)", 1, 1, rubyCode);
    } catch (BSFException e) {
      System.err.println(e);
    }
  }
}

 リスト1と似ていますね。違いは,Rubyのインスタンスの代わりにBSFManagerのインスタンスを生成し,そこにJRubyが用意しているRubyの実行エンジンを登録する点です。また,コードを実行するメソッドがevalになります。

 ちなみに,2006年第3四半期に登場予定のJava SE 6(開発コード名Mustang)は,「JSR 223」というスクリプト言語サポート機能を搭載することが決まっています。JSR 223でスクリプト言語のコードを実行する方法はBSFとよく似ています。ScriptEngineManagerのインスタンスを生成し,getEngineByNameというメソッドを使ってスクリプト言語に応じたScriptEngineのインスタンスを生成します。

 現在は,JSR 223よりBSFのほうが対応している言語が多いので,まだJSR 223をそれほど意識する必要はないでしょう。ただ,JSR 223は,将来,Javaの標準になることが決まっていますから,いずれはBSFを置き換えていくのかもしれません。

 次回は,「スクリプト言語からJavaを使う方法」をご紹介します。