在 Play 中为 Scala 控制器实现 Nashorn

Implementing Nashorn in Play for Scala controller

下面的代码在 Play (2.5) for Scala 控制器中执行 Nashorn/Javascript 脚本。我注入一个 class 来获取运行脚本的引擎。

网上查了一下,关于Nashorn的线程安全,众说纷纭,不清楚。从 Play 控制器调用的下面的 getEngine 方法是否线程安全?

@Singleton
class JavascriptEngine {

   val factory = new NashornScriptEngineFactory

   def getEngine = {  // <-- thread safe?
     factory.getScriptEngine()
   }

}


class Test @Inject()(je: JavascriptEngine) extends Controller  {

    def test = Action { request =>
         val script = "var x = 'this is script 1'; "
         runJS(script)
         Ok("some response")
    }

    def runJS (script: String) = {
          val engine = je.getEngine
          engine.eval(script)
          val x = engine.get("x")
          println(x)
    }


 }

来自 getScriptEngine 的 javadoc:

A new ScriptEngine is generally returned, but implementations may pool, share or reuse engines.

因此,在不查看实现的情况下,在一般情况下(如果总是创建新引擎),这是线程安全的。

在另一种情况下,如果引擎被合并或共享,我会假设工厂代码在内部以线程安全的方式处理合并/共享。

看着 https://alvinalexander.com/java/jwarehouse/openjdk-8/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java.shtml 看来工厂确实总是 returns 新制造的引擎。