Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala.tools.nsc.IMain within Play 2.1

I googled a lot and am totally stuck now. I know, that there are similar questions but please read to the end. I have tried all proposed solutions and none did work.

I am trying to use the IMain class from scala.tools.nsc within a Play 2.1 project (Using Scala 2.10.0).

Controller Code

This is the code, where I try to use the IMain in a Websocket. This is only for testing.

object Scala extends Controller {
  def session = WebSocket.using[String] { request =>
    val interpreter = new IMain() 
    val (out,channel) = Concurrent.broadcast[String]
    val in = Iteratee.foreach[String]{ code =>
      interpreter.interpret(code) match {
        case Results.Error =>      channel.push("error")
        case Results.Incomplete => channel.push("incomplete")
        case Results.Success =>    channel.push("success")
      }      
    } 
    (in,out)
  }
}

As soon as something gets sent over the Websocket the following error gets logged by play:

Failed to initialize compiler: object scala.runtime in compiler mirror not found.
** Note that as of 2.8 scala does not assume use of the java classpath.
** For the old behavior pass -usejavacp to scala, or if using a Settings
** object programatically, settings.usejavacp.value = true.

Build.scala

object ApplicationBuild extends Build {
  val appName         = "escalator"
  val appVersion      = "1.0-SNAPSHOT"

  val appDependencies = Seq(
    "org.scala-lang" % "scala-compiler" % "2.10.0"
  )

  val main = play.Project(appName, appVersion, appDependencies).settings(    
  )
}

What I have tried so far

All this didn't work:

  • I have included fork := true in the Build.scala
  • A Settings object with:
    • embeddedDefaults[MyType]
    • usejavacp.value = true
  • The soultion proposed as answer to Question Embedded Scala REPL inherits parent classpath

I dont know what to do now.

like image 761
Martin Ring Avatar asked May 12 '13 19:05

Martin Ring


1 Answers

The problem here is that sbt doesnt add scala-library to the class path. The following workaround works. First create a folder lib in the top project directory(the parent of app,conf etc) and copy there the scala-library.jar

Then you can use the following code to host an interpreter :

      val settings = new Settings
      settings.bootclasspath.value +=scala.tools.util.PathResolver.Environment.javaBootClassPath + File.pathSeparator + "lib/scala-library.jar"
      val in = new IMain(settings){
            override protected def parentClassLoader = settings.getClass.getClassLoader()
      }
     val res = in.interpret("val x = 1")

The above creates the bootclasspath by adding to the java class the scala library. It's not a problem with play framework it comes from the sbt. The same problem occures for any scala project when it runs with sbt. Tested with a simple project. When it runs from eclipse its works fine.

EDIT: Link to sample project demonstrating the above.`

like image 145
Iraklis Avatar answered Sep 19 '22 13:09

Iraklis