Home About
javascript, rhino, groovy

Rhino で実行する javascript をコンパイルしてから使う

いままで Javaから javascript を実行するのに、 evaluateString ばかり使っていたが、事前にこれをコンパイルして使うことができるらしいので、試してみた。

Pikachu クラス再び

こちら でつくった Pikachu クラスを使う javascript コードをコンパイルしてから使ってみる。

Pikachu クラス:

public class Pikachu extends ScriptableObject {
    @Override
    String getClassName() { return 'Pikachu' }

    Pikachu(){}

    @JSFunction
    String sayHello(int i){ return 'pika ' * i }
}

これを使う javascript コードの実行は 以前のコードでは evaluateString していた:

def script0 = 'pikachu.sayHello(3);'
def result0 = cx.evaluateString(scope, script0, "<cmd>", 1, null)

これを事前にコンパイルして使うには:

def script0 = 'pikachu.sayHello(3);'
def compiledScript = cx.compileString(script0, 'script0', 1, null)
compiledScript.exec(cx, scope)

これだけです。

コード全体

@Grab(group='org.mozilla', module='rhino', version='1.7.12')
import org.mozilla.javascript.Context
import org.mozilla.javascript.ScriptableObject
import org.mozilla.javascript.annotations.JSFunction

public class Pikachu extends ScriptableObject {
    @Override
    String getClassName() { return 'Pikachu' }

    Pikachu(){}

    @JSFunction
    String sayHello(int i){ return 'pika ' * i }
}

def script0 = '''\
    |pikachu.sayHello(3);
    |'''.stripMargin('|')

def cx = Context.enter()
def compiledScript = cx.compileString(script0, 'script0', 1, null)

def scope = cx.initStandardObjects()
ScriptableObject.defineClass(scope, Pikachu.class)
def pikachu = cx.newObject(scope, "Pikachu")
scope.put("pikachu", scope, pikachu)

def result = compiledScript.exec(cx, scope)
println(result)

Context.exit()

まとめ

コンパイルしてから使うと速いらしいので活用していきたい。