よりどりみどり?

あけましておめでとうございます。

新年があけてからずいぶん立ってしまいましたが、今年1回目の連載ということもあるので、あらためてご挨拶してみました。

今年もJavaの新しいところをいろいろと紹介していく所存ですので、よろしくお願いします。

というわけで、新年第1回目に取りあげるのはJava SE 6の目玉機能である、スクリプト言語のサポートです。

思い返せば、去年はスクリプト言語がとても盛り上がりを見せた年でした。Java関連でいうと、JRubyとJavaFX Scriptですね。

JavaVMの上で動作するJRubyやJavaFX Scriptなどのスクリプト言語が盛り上がった理由の1つに、Java SEが正式にスクリプト言語をサポートしたことがあげられます。

JRubyやGroovy、古くはPnutsなどのスクリプト言語は、Java SEがサポートする以前から開発が行なわれてきました。しかし、Javaからスクリプト言語の処理系にアクセスする方法や、Javaとスクリプト言語で同じオブジェクトを共有する方法は、スクリプト言語の処理系によって様々でした。

そこで、これらを統一的に扱えるようにするために JCP で標準策定されたのが、JSR 223 Scripting for Java Platformです。もちろん、Java SE 6は、このJSR 223をサポートしています。

JSR 223はスクリプト言語に依存せず、様々なスクリプト言語に対応しています。JSR 223に対応したスクリプト言語はjava.netのScriptingプロジェクトに集約されています。原稿執筆時点(2007年12月)で33種類ものスクリプト言語がJSR 223で扱うことができるのです。

これらのスクリプト言語は次の3種類に大別できます。

  1. 既存のスクリプト言語に対するブリッジ
  2. 既存のスクリプト言語をJava VMで動作するように移植した言語
  3. はじめからJava VMで動作させることを想定した言語

1のブリッジはCなどで記述された言語処理系には手をいれず、言語処理系を呼び出すブリッジだけをJavaで作成したものです。たとえば、PHP/Java bridgeなどがこのブリッジに相当します。

2の移植言語は、RubyやPythonなどオリジナルの言語処理系とは別に、Javaを使用して新たに処理系を作り上げたものです。Rubyに対するJRuby、Pythonに対するJythonなどがこのグループに入ります。

3の言語は、はじめからJavaで処理系が作られたスクリプト言語です。PnutsGroovyJavaFX Scriptなどがあります。

Java SE 6ではこれらのスクリプト言語をすべて扱うことができます。また、標準でMozillaが開発しているJavaScriptの処理系であるRhinoが使用できます。

とりあえずスクリプトを使ってみる

手っとり早くスクリプトを試してみるのに、jrunscriptという絶好のツールがJDK 6には用意されています。

jrunscriptの使い方は-helpもしくは-?オプションで見ることができます。-helpもしくは-?では英語しか表示されませんが、Java SEのドキュメントにはちゃんと日本語で記述されています。

C:\scripting>jrunscript -help
Usage: jrunscript [options] [arguments...]

where [options] include:
  -classpath <path>    Specify where to find user class files
  -cp <path>           Specify where to find user class files
  -D<name>=<value>     Set a system property
  -J<flag>             Pass <flag> directly to the runtime system
  -l <language>        Use specified scripting language
  -e <script>          Evaluate given script
  -encoding <encoding> Specify character encoding used by script files
  -f <script file>     Evaluate given script file
  -f -                 Interactive mode, read script from standard input
                       If this is used, this should be the last -f option
  -help                Print this usage message and exit
  -?                   Print this usage message and exit
  -q                   List all scripting engines available and exit

If [arguments..] are present and if no -e or -f option is used, then first
argument is script file and the rest of the arguments, if any, are passed
as script arguments. If [arguments..] and -e or -f option is used, then all
[arguments..] are passed as script arguments. If [arguments..], -e, -f are
missing, then interactive mode is used.

-cpや-J、-Dオプションはjavacと共通です。

オプションの一番下にある-qオプションは使用できるすべてのスクリプト言語を出力するオプションです。このオプションから試してみましょう。

C:\scripting>jrunscript -q
Language ECMAScript 1.6 implemention "Mozilla Rhino" 1.6 release 2

ECMAScriptというのはJavaScriptのことですね。前述したように、Java SE 6は標準でJavaScriptが使用できます。また、JavaScriptの処理系がMozillaのRhinoだということも、ここから分かります。

次に、筆者の環境で試してみました。

C:\scripting>jrunscript -q
Language FX 0.1 implemention "JavaFXEngine" 0.1a
Language ECMAScript 1.6 implemention "Mozilla Rhino" 1.6 release 2

筆者はデフォルトでJavaFX Scriptをクラスパスに組み込んであるため、ECMAScript以外に、FXが表示されています。このように、jrunscriptはJavaScriptだけでなく、他のスクリプト言語でも使用することができます。

言語を指定するには-lオプションを使用します。指定しなかった場合は、デフォルトでJavaScriptが使用されます。

それではjrunscriptでスクリプトを実行させてみましょう。

jrunscriptを-fオプションもしくは-eオプションを使用せず、引数もなしで起動すると、インタラクティブモードになります。

一番はじめは、お決まりのHello, World!です。

C:\scripting>jrunscript
js> print('Hello, World!\n');
Hello, World!
js>

もちろん、複数行にわたるスクリプトでも実行できます。

js> var i;
js> i = 10;
10
js> print(i + '\n');
10
js>

しかし、1行で完結しないスクリプトはエラーが出ます。 以下に、forループを途中まで入力したところで、改行した場合です。

js> for (i = 0; i < 10; i++) {
script error: sun.org.mozilla.javascript.internal.EvaluatorException:
missing } in compound statement (<STDIN>#1) in <STDIN>
at line number 1
js>

閉じカッコがないというエラーです。これは以下のように1行に記述すれば、動作します。

js> for (i = 0; i < 10; i++) { print(i + ' '); }
0 1 2 3 4 5 6 7 8 9 js>

-eオプションを使うとjrunscriptの引数として、スクリプトを指定することができます。スクリプトはダブルクオンテーション("")で囲みます。

C:\scripting>jrunscript -e "print('Hello, World!');"
Hello, World!

-eでスクリプトを実行する場合、スクリプト中にダブルクオンテーションが存在する場合は\"とエスケープします。

C:\scripting>jrunscript -e "print(\"Hello, World!\");"
Hello, World!

ファイルからスクリプト実行

今まで示したように、jrunscriptを使えば、インタラクティブにスクリプトを実行できます。ちょっと試すにはいいのですが、長いスクリプトを実行するのはかなり大変です。

こんな時には、ファイルにスクリプトを記述しておいて、それを実行するようにします。

そこで、以下のようなスクリプトファイル(hello.js)を書いてみました。

var names = ['World', 'Java', 'JavaScipt', 'Japan'];
for (i = 0; i < names.length; i++) {
    print('Hello, ' + names[i] + '!\n');
}

jrunscriptでスクリプトファイルからスクリプトを実行するには、-fオプションを使用します。

C:\scripting>jrunscript -f hello.js
Hello, World!
Hello, Java!
Hello, JavaScipt!
Hello, Japan!

また、-fオプションもしくは-eオプションを指定せずに引数のみを指定した場合、第1引数がスクリプトファイル、それ以降の引数がスクリプトに対する引数として実行されます。したがって、次のように記述しても、同じ結果を得ることができます。

C:\scripting>jrunscript hello.js
Hello, World!
Hello, Java!
Hello, JavaScipt!
Hello, Japan!