最近,業務で Java を頻繁に使うようになりました(私は社会人1年目のぺえぺえです).
いろいろ調べていたら,Java 6 から Script API が導入されたことを知りました.へぇ〜.
ScriptEngineを使う
Oracle Technology Network for Java Developers
Oracle Technology Network for Java Developers
上記ページで説明されています.
スクリプトの実行時に使用する ClassLoader を変更したい
ScriptEngine の場合,ClassLoader は
java.lang.Thread.currentThread().getContextClassLoader();
が使用されるようです.
これを変更したいときは,Rhino を組み込む手順と同じことをすれば可能になります.
Rhino 組み込み
具体的には,
Context context = Context.enter(); // ClassLoader を変更 context.setApplicationClassLoader(/* ここにクラスローダをセット */);
とすることで変更できます.
これで,JavaScript から,
var hoge = JavaImporter(Packages.org.example.hoge); var h = new hoge.Hoge();
のように,設定したクラスローダ経由で Java クラスが使えるようになります.
JDK1.6.0_03 に組み込まれた Rhino を利用する場合は,
sun.org.mozilla.javascript.internal
以下のクラスを使用することになります.
Rhino の jar を直接利用する場合は,
org.mozilla.javascript
を使用します.
だいたいこんな感じで使えばよいのでしょうか.
(API の詳しい使い方は,Javadocを参照)
Context context = Context.enter(); try { ScriptableObject root = context.initStandardObjects(); // JavaScript で ImportPackage を使いたい場合は,上記コードの代わりに // ScriptableObject root = new ImporterTopLevel(context); // とする. // 1: スクリプト,2: スクリプトが記述されたファイル名,3: 開始行番号,4: Securityを気にしない場合はnull // ↑by Rhino 1.6r7 のコードより Script compiledScript = context.compileString(script, "<Script String1>", 1, null); // 指定された context と root (Scope) で,スクリプトを実行 // ↓実行結果もとれるよ compiledScript.exec(context, root); Object ret = null; // 上のscriptで,例えば "function main()" を定義していた場合,以下のようにして実行する ret = context.evaluateString(root, "main();", "<Script String2>", 1, null); } finally { Context.exit(); }
...あってるかな?
その他
スクリプト実行後の結果を Java から利用するときには,
Object ret = context.evaluateString( ... ); if(ret instanceof NativeJavaObject) { ret = ((NativeJavaObject) ret).unwrap(); }
こんな風に取得することも可能です.
(標準はこっち→ Rhino 組み込み)