如何使用JSR-223在sbt控制台中获取Scala解释器?

时间:2014-05-30 18:23:29

标签: scala sbt jsr223 scala-2.11

在sbt控制台,sbt版本0.13.5,Scala版本2.11.1中,我可以获得Scala的javax.script.ScriptEngine

scala> val engine = new javax.script.ScriptEngineManager().getEngineByName("scala")
engine: javax.script.ScriptEngine = scala.tools.nsc.interpreter.IMain@bf78a9

但是,我无法使用它:

scala> engine.eval("3")
[init] error: error while loading Object, Missing dependency 'object scala in compiler mirror', required by /usr/lib/jvm/java-7-openjdk-i386/jre/lib/rt.jar(java/lang/Object.class)

Failed to initialize compiler: object scala 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.
scala.reflect.internal.MissingRequirementError: object scala in compiler mirror not found.
  at ...

According to the SBT FAQ,我应该使用Settings做一些魔术,然后将其传递给我的Interpreter构造函数。但是,我没有直接创建Interpreter(如果我间接创建它,它甚至不清楚,因为引擎对象是IMain)。< / p>

Scala ScriptEngine是否有办法在SBT控制台上工作?

1 个答案:

答案 0 :(得分:5)

您可以将引擎转换为scala.tools.nsc.interpreter.IMain,这样您就可以访问settings。然后,您可以使用embeddedDefaults将类路径设置为it was mentioned in the FAQ。只需在调用eval方法之前执行此操作。

val engine = new javax.script.ScriptEngineManager().getEngineByName("scala")
val settings = engine.asInstanceOf[scala.tools.nsc.interpreter.IMain].settings
// MyScalaClass is just any class in your project
settings.embeddedDefaults[MyScalaClass]

鉴于您应该能够运行eval,例如

scala> engine.eval("10")
res3: Object = 10

gist linked from the FAQ或多或少解释了原因。基本上,在使用getEngineByName("scala")创建解释器时,会使用java.class.path并且它仅包含sbt-launch.jar。使用embeddedDefaults的技巧将类路径设置为正确的值(您可以在调用settings之前和之后检查embeddedDefaults)。