2014-12-14 18 views
8

Attualmente sto lavorando su un progetto usando Scala e Play Framework 2. Voglio compilare del codice Scala durante il runtime e ottenere il risultato dall'interprete. Ho trovato alcuni esempi su internet e, infine, si avvicinò con il seguente codice:scala.reflect.internal.FatalError: pacchetto scala non ha un membro Int

package controllers 

import play.api.mvc.{Action, Controller} 
import javax.script.ScriptEngineManager 

class Interpreter extends Controller { 

    val interpreter = new ScriptEngineManager().getEngineByName("scala") 
    val settings = interpreter.asInstanceOf[scala.tools.nsc.interpreter.IMain].settings 
    settings.embeddedDefaults[Interpreter] 
    settings.usejavacp.value = true 

    def index = Action { 
     Ok(views.html.interpreter()) 
    } 

    def interpret(input: String) = Action { 
     implicit request => interpreter.eval("1 to 10 foreach println") 
     Ok("Got: " + input) 
    } 
} 

object Interpreter 

mio problema è che ottengo sempre un errore dal scala.reflect.internal.FatalError: "package scala does not have a member Int", quando si cerca di eseguire questo codice. Dopo alcune ricerche ho trovato problemi simili descritti in questo post:

Scala and Play 2.0 Plugins Update 0.38.437 is Out

Scala compiler error: package api does not have a member materializeWeakTypeTag

La mia attuale versione Scala è 2.11.4, così ho cercato di passare a un diverso "scala-compilatore" e versioni "scala-library" nel mio file "build.sbt", ma senza successo. Come è stato menzionato nei post precedenti, probabilmente è un bug in Scala. Mi chiedevo se qualcuno avesse una soluzione o forse qualche soluzione alternativa per il problema descritto.

Grazie in anticipo per qualsiasi aiuto o consiglio.

+0

Non sono sicuro di ottenere esattamente ciò che si vuole fare, ma interpretare il metodo sul controller dovrebbe restituire un'azione che è fondamentalmente una funzione (play.api.mvc.Request => play.api.mvc.Result) . Nel tuo codice hai una richiesta implicita => Oggetto (proveniente dalla funzione eval) e poi restituisci il risultato Ok. È corretto? – Kris

+0

1) per ottenere l'input: stringa da un campo di testo sul lato frontend 2) passare alla funzione interpret() 3) valutare l'input 4) e infine restituire l'output fornito dal compilatore . – dima

+0

Sembra che questo problema riguardi solo le applicazioni specifiche. Lo stesso argomento su "scala script engine" di Google Gruppi https://groups.google.com/forum/#!topic/scala-script-engine/9YteLsdXPKU –

risposta

2

il problema è nel classpath in progetti che utilizzano Scala and Play quadro 2. può essere risolto popolando classpath dalla SBT alla domanda:

Aggiungi build.sbt di file:

val sbtcp = taskKey[Unit]("sbt-classpath") 

sbtcp := { 
    val files: Seq[File] = (fullClasspath in Compile).value.files 
    val sbtClasspath : String = files.map(x => x.getAbsolutePath).mkString(":") 
    println("Set SBT classpath to 'sbt-classpath' environment variable") 
    System.setProperty("sbt-classpath", sbtClasspath) 
} 

compile <<= (compile in Compile).dependsOn(sbtcp) 

Codice:

package controllers 

import play.api.mvc.{Action, Controller} 
import javax.script.ScriptEngineManager 

class Interpreter extends Controller { 

    val interpreter = new ScriptEngineManager().getEngineByName("scala") 
    val settings = interpreter.asInstanceOf[scala.tools.nsc.interpreter.IMain].settings 
    //settings.embeddedDefaults[Interpreter] // not need 
    //settings.usejavacp.value = true // not need 
    val sbtClasspath = System.getProperty("sbt-classpath") 
    settings.classpath.value = s".:${sbtClasspath}" // <-- this line fix the problem 

    def index = Action { 
     Ok(views.html.interpreter()) 
    } 

    def interpret(input: String) = Action { 
     implicit request => interpreter.eval("1 to 10 foreach println") 
     Ok("Got: " + input) 
    } 
} 

object Interpreter 

Nella produzione deve essere utilizzato un altro scenario per ottenere un classpath corretto.

Probabilmente si utilizza una chiave '-cp' o '-classpath' dalla riga di comando.