【问题标题】:Why do i need Scala compiler at runtime? (Play2/Salat with Scalap dependency)为什么我在运行时需要 Scala 编译器? (具有 Scalap 依赖性的 Play2/Salat)
【发布时间】:2026-02-07 20:50:01
【问题描述】:

我正在使用 Scala / Mongo / Casbah / Salat / Play2,当我尝试使用 Salat 时,它似乎依赖于 Scalap。

使用play run 运行应用程序时它工作正常,但使用play start 我得到以下堆栈:

[info] application - Can't create user 
java.lang.NoClassDefFoundError: scala/tools/nsc/util/ClassPath$JavaContext
    at scala.tools.scalap.scalax.rules.scalasig.ScalaSigParser$.scalaSigFromAttribute(ScalaSig.scala:35) ~[scalap-2.9.1.jar:na]
    at scala.tools.scalap.scalax.rules.scalasig.ScalaSigParser$.parse(ScalaSig.scala:38) ~[scalap-2.9.1.jar:na]
    at com.novus.salat.util.ScalaSigUtil$$anonfun$parseScalaSig0$2.apply(ScalaSigUtil.scala:73) ~[salat-util_2.9.1-0.0.8-SNAPSHOT.jar:0.0.8-SNAPSHOT]
    at com.novus.salat.util.ScalaSigUtil$$anonfun$parseScalaSig0$2.apply(ScalaSigUtil.scala:73) ~[salat-util_2.9.1-0.0.8-SNAPSHOT.jar:0.0.8-SNAPSHOT]
    at scala.Option.map(Option.scala:133) ~[scala-library.jar:na]
    at com.novus.salat.util.ScalaSigUtil$.parseScalaSig0(ScalaSigUtil.scala:73) ~[salat-util_2.9.1-0.0.8-SNAPSHOT.jar:0.0.8-SNAPSHOT]
Caused by: java.lang.ClassNotFoundException: scala.tools.nsc.util.ClassPath$JavaContext
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366) ~[na:1.7.0_01]
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355) ~[na:1.7.0_01]
    at java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_01]
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354) ~[na:1.7.0_01]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423) ~[na:1.7.0_01]
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) ~[na:1.7.0_01]

scala/tools/nsc/util/ClassPath$JavaContext 在 Scala 编译器项目中,所以我添加了 SBT 依赖项:

"org.scala-lang" % "scala-compiler" % "2.9.1"

现在play start 也可以正常工作了。

但是运行我的项目时必须使用 scala 编译器的运行时依赖项是否正常? 为什么它可以在没有 scala 编译器依赖的情况下与 play run 一起使用?不是在生产模式下运行时会自动嵌入吗?

谢谢

【问题讨论】:

标签: scala playframework salat scalap


【解决方案1】:

实际上 Scalap 依赖于 Scala 编译器:

<dependencies>
    <dependency>
        <groupId>org.scala-lang</groupId>
        <artifactId>scala-compiler</artifactId>
        <version>2.9.0.RC4</version>
    </dependency>
</dependencies>

http://www.jarvana.com/jarvana/inspect-pom/org/scala-lang/scalap/2.9.0.RC4/scalap-2.9.0.RC4.pom

我遇到了问题,因为我的依赖项临时是手动处理的,而不是由 SBT 处理的。

现在我通过 SBT 管理它们,它工作正常...但编译器仍被检索为传递依赖项,并以 Salat 作为初始依赖项...

在运行时有编译器很奇怪,但它可以工作......

【讨论】:

    【解决方案2】:

    发生这种情况有两个原因:

    • 如果您在开发模式下工作,您的类会不断重新编译。所以你需要一个编译器。

    • 如果您使用舞台模式,类将永远编译一次,但这是在内部完成的。如果不是,您必须提供对 scala 编译器的引用,它可以替换 scala 编译器依赖项。

    【讨论】:

    • 好的,所以它应该解释为什么它在播放运行时运行良好,但实际上在播放开始时我处于生产模式,之前一切都是编译器,所以我为什么需要编译器依赖项?
    • 就像这里描述的:github.com/playframework/Play20/wiki/Production 使用 start 或 stage 结果是一样的
    • 其实播放服务器编译好,启动好。只有在使用使用 Scalap 的 Salat 时,才能获得以下堆栈。 Scalap 在运行时不可用吗? Scala编译器不应该不在运行时吗?那么为什么要建立这样的依赖关系呢?
    • Scalap 依赖于 Scala 编译器。
    最近更新 更多