Search code examples
scalaplayframeworkjava-8nashorn

PlayFramework NoClassDefFoundError: jdk/nashorn/api/scripting/NashornScriptEngineFactory


Calling the NashornScriptEngineFactory yields a RuntimeException on a simple PlayFramework application.

build.sbt

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.6"

scalacOptions += "-target:jvm-1.8"

Application.scala

import jdk.nashorn.api.scripting.NashornScriptEngineFactory
import play.api.mvc._

object Application extends Controller
{
    def index = Action
    {
        val nashorn = new NashornScriptEngineFactory().getScriptEngine( "-scripting" )
        Ok( nashorn.eval( "3;" ).toString )
    }
}

On a similar sbt project however, it works:

Main.scala

import jdk.nashorn.api.scripting.NashornScriptEngineFactory

object Main extends App
{
    val nashorn = new NashornScriptEngineFactory().getScriptEngine( "-scripting" )

    println( nashorn.eval( "4;" ) )
}

Why is play failing to load the required factory?

Stacktrace

[error] application - 

! @6locb3604 - Internal server error, for (GET) [/] ->

play.api.Application$$anon$1: Execution exception[[RuntimeException: java.lang.NoClassDefFoundError: jdk/nashorn/api/scripting/NashornScriptEngineFactory]]
    at play.api.Application$class.handleError(Application.scala:296) ~[play_2.11-2.3.8.jar:2.3.8]
    at play.api.DefaultApplication.handleError(Application.scala:402) [play_2.11-2.3.8.jar:2.3.8]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:205) [play_2.11-2.3.8.jar:2.3.8]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:202) [play_2.11-2.3.8.jar:2.3.8]
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36) [scala-library-2.11.6.jar:na]
Caused by: java.lang.RuntimeException: java.lang.NoClassDefFoundError: jdk/nashorn/api/scripting/NashornScriptEngineFactory
    at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:523) ~[play_2.11-2.3.8.jar:2.3.8]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:130) ~[play_2.11-2.3.8.jar:2.3.8]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:130) ~[play_2.11-2.3.8.jar:2.3.8]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21) ~[play_2.11-2.3.8.jar:2.3.8]
    at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:129) ~[play_2.11-2.3.8.jar:2.3.8]
Caused by: java.lang.NoClassDefFoundError: jdk/nashorn/api/scripting/NashornScriptEngineFactory
    at controllers.Application$$anonfun$index$1.apply(Application.scala:10) ~[classes/:na]
    at controllers.Application$$anonfun$index$1.apply(Application.scala:9) ~[classes/:na]
    at play.api.mvc.ActionBuilder$$anonfun$apply$17.apply(Action.scala:464) ~[play_2.11-2.3.8.jar:2.3.8]
    at play.api.mvc.ActionBuilder$$anonfun$apply$17.apply(Action.scala:464) ~[play_2.11-2.3.8.jar:2.3.8]
    at play.api.mvc.ActionBuilder$$anonfun$apply$16.apply(Action.scala:433) ~[play_2.11-2.3.8.jar:2.3.8]
Caused by: java.lang.ClassNotFoundException: jdk.nashorn.api.scripting.NashornScriptEngineFactory
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_40]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_40]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_40]
    at controllers.Application$$anonfun$index$1.apply(Application.scala:10) ~[classes/:na]
    at controllers.Application$$anonfun$index$1.apply(Application.scala:9) ~[classes/:na]

Solution

  • This is related to https://github.com/playframework/playframework/pull/3420 and works in play 2.4.x!

    addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.4.0-M3")