我正在尝试运行打包为 JAR(包括依赖项)的 Scala 应用程序,但这会失败,直到使用该-Xbootclasspath/p
选项添加 Scala 库。
调用失败:
java -jar /path/to/target/scala-2.10/application-assembly-1.0.jar
在应用程序完成了一些预期的输出后,控制台显示:
线程“主”scala.reflect.internal.MissingRequirementError 中的异常:未找到编译器镜像中的对象 scala.runtime。在 scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:16) 在 scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:17) 在 scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors .scala:48) 在 scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:40) 在 scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:61) 在 scala.reflect.internal。在 scala.reflect.internal.Mirrors$RootsBase.getRequiredPackage(Mirrors.scala:175) 在 scala.reflect.internal.Definitions$DefinitionsClass 的 Mirrors$RootsBase.getPackage(Mirrors.scala:172)。
工作调用:
java -Xbootclasspath/p:/path/to/home/.sbt/boot/scala-2.10.2/lib/scala-library.jar -jar /path/to/target/scala-2.10/application-assembly-1.0.jar
奇怪的是,它的application-assembly-1.0.jar
构建是为了包含所有依赖项,包括 Scala 库。当提取 JAR 文件时,可以验证scala.runtime
包中的类文件是否已包含在内。
JAR 文件的创建
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.9.1")
被添加到project/plugins.sbt
并assembly
调用了目标。一个大约 25MB 的 JAR 文件结果。
使用 proguard 构建 JAR 显示了与在程序集的 JAR 文件中看到的相同的运行时行为。
触发 MissingRequirementError 的应用程序代码
一些应用程序代码可以正常工作,并且只要new Run
执行以下片段,就会触发前面描述的异常。
import scala.reflect.internal.util.BatchSourceFile
import scala.reflect.io.AbstractFile
import scala.reflect.io.Path.jfile2path
import scala.tools.nsc.Global
import scala.tools.nsc.Settings
…
import scala.tools.nsc._
object Compiler extends Global(new Settings()) {
new Run // This is line 24 from the stack trace!
def parse(path: File) = {
val code = AbstractFile.getFile(path)
val bfs = new BatchSourceFile(code, code.toCharArray)
val parser = new syntaxAnalyzer.UnitParser(new CompilationUnit(bfs))
parser.smartParse()
}
}
val ast = Compiler.parse(file)
其中scala-library
,scala-compiler
和scala-reflect
被定义为 中的依赖项build.sbt
。
对于古玩/背景信息
该应用程序的目的是帮助 Java 和 Scala 程序的本地化。上面代码片段的任务是从 Scala 文件中获取 AST,以便在其中找到方法调用。
问题
- 鉴于 Scala 库包含在 JAR 文件中,为什么需要使用 调用 JAR
-Xbootclasspath/p:scala-library.jar
? - 为什么应用程序的其他部分运行得很好,即使
scala.runtime
后来报告为丢失?