Nashorn の GlobalScope にやられたので、帳票クリエータを Java8 + Rhino で動かしてみる
こんにちは、開発担当の Masa です。
前回に引き続き Nashorn のグローバルスコープに関する話題です。
現在発売されている「シーオーリポーツ 帳票クリエータ Ver.3 for Java」は Java8 では動作しません。
Java8 で標準搭載されているスクリプトエンジンがそれまでの Rhino から Nashorn へと変更され、
しかも Rhino と Nashorn は 100% の互換性を保っていないことが理由です。
今回のブログは、何とか Rhino との互換性を保とうとするプログラマの苦悩と、
いっそ Java8 + Rhino で動かしてしまえと言う開き直りについてお送りします。
第1章:苦悩
Nashorn では eval した変数や関数は特定のエンジンスコープに関連付けられます。
グローバルスコープの変数を別々のエンジンスコープを指定した eval で変更した場合、
変更内容は共有されません。
つまり、以下のプログラムを実行すると、Nashorn は 0、Rhino は 150 という出力結果が得られます。
public static void main(String[] args) { ScriptEngineManager manager = new ScriptEngineManager(); manager.put("sum", 0); ScriptEngine engine = manager.getEngineByExtension("js"); engine.eval("sum = 150;"); engine.eval("print(sum);", engine.createBindings()); }
Nashorn の出力結果を Rhino と同様にしたい場合、"--global-per-engine" オプションを使用します。
"ScriptEngineManager#getEngine~" する前に System.setProperty("nashorn.args", "--global-per-engine") することで Rhino と同じ結果になりました。
ん~、コレだとクリエータ以外にも影響出ますよね。。。と、いうわけで別の方法を。
NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); ScriptEngine engine = factory.getScriptEngine(new String[] { "--global-per-engine" });
この方法だと影響範囲を生成したエンジンのみに固定できます。
ただし、"jdk.nashorn.api.scripting" パッケージに依存するので Java7 で実行すると
該当パッケージを使用したクラスがロードされた瞬間にエラーとなります。
。。。
他にもイロイロ(本当にイロイロ)あるのですが、こんな感じで苦悩しながら1つ1つ対応中です。
ココロが折れそう。。。
第2章:Java8 + Rhino という選択
スクリプトエンジンにはこだわってないからとにかく Java8 でクリエータを動かしたい!という人には、Java8 + Rhino という選択もあります。
環境の構築方法はコチラで教えてくれてますね。
- mozillaのサイトから "js.jar" をダウンロード(下の方にダウンロードリンクがあります)
- "https://svn.java.net/svn/scripting~svn" からスクリプトエンジンの実装をチェックアウト
- "任意の場所/trunk/engines/javascript/lib/js.jar" を ダウンロードした "js.jar" に置き換え
- "任意の場所/trunk/engines/javascript/make/build.xml" を "ant clean all" で実行
ダウンロードした "js.jar" と コンパイルした "任意の場所/trunk/engines/javascript/build/js-engine.jar" を
クラスパスの通るディレクトリに置いて「シーオーリポーツ 帳票クリエータ Ver.3 for Java」を実行します。
筆者はデベロッパーズマニュアルの単票出力サンプルで試しましたが、正常に出力されました。
「シーオーリポーツ 帳票クリエータ Ver.3 for Java」は現在 Java8 に対応中です。
Nashorn のまま実行したい方は今しばらくお待ちください。