“scala.runtime in compiler mirror not found”,但是在使用-Xbootclasspath / p启动时工作:scala-library.jar

我试图运行一个打包为JAR(包括依赖项)的 Scala应用程序,但是直到通过使用-Xbootclasspath / p选项添加Scala库才会失败.

失败调用

java -jar /path/to/target/scala-2.10/application-assembly-1.0.jar

应用程序执行一些预期的输出后,控制台显示

Exception in thread “main”
scala.reflect.internal.MissingRequirementError: object scala.runtime
in compiler mirror not found.
at scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:16)
at scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:17)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:48)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:40)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:61)
at scala.reflect.internal.Mirrors$RootsBase.getPackage(Mirrors.scala:172)
at scala.reflect.internal.Mirrors$RootsBase.getrequiredPackage(Mirrors.scala:175)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.RuntimePackage$lzycompute(DeFinitions.scala:181)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.RuntimePackage(DeFinitions.scala:181)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.RuntimePackageClass$lzycompute(DeFinitions.scala:182)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.RuntimePackageClass(DeFinitions.scala:182)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.AnnotationDefaultAttr$lzycompute(DeFinitions.scala:1015)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.AnnotationDefaultAttr(DeFinitions.scala:1014)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.syntheticCoreClasses$lzycompute(DeFinitions.scala:1144)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.syntheticCoreClasses(DeFinitions.scala:1143)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.symbolsNotPresentInBytecode$lzycompute(DeFinitions.scala:1187)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.symbolsNotPresentInBytecode(DeFinitions.scala:1187)
at scala.reflect.internal.DeFinitions$DeFinitionsClass.init(DeFinitions.scala:1252)
at scala.tools.nsc.Global$Run.(Global.scala:1290)
at extract.ScalaExtractor$Compiler$2$.(ScalaExtractor.scala:24)

工作调用

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中,并且调用了程序集目标.大约25MB的JAR文件结果.

使用proguard构建JAR显示与程序集的JAR文件所见的相同的运行时行为.

触发MissingRequirementError的应用程序代码

一些应用程序代码工作正常,并且一旦从以下片段执行新的运行,就会触发先前描述的异常.

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文件中,为什么需要使用-Xbootclasspath / p:scala-library.jar调用JAR?
>为什么应用程序的其他部分运行正常,即使scala.runtime稍后报错?

解决方法

使用熟悉的按键配置设置的简单方法

import scala.tools.nsc.Global
  import scala.tools.nsc.Settings
  def main(args: Array[String]) {
    val s = new Settings
    s processArgumentString "-usejavacp"
    val g = new Global(s)
    val r = new g.Run
  }

这适用于您的场景.

更容易:

java -Dscala.usejavacp=true -jar ./scall.jar

奖金信息,我偶然遇到了the enabling commit message

Went ahead and implemented classpaths as described in email to
scala-internals on the theory that at this point I must kNow what I’m
doing.

** PUBLIC SERVICE ANNOUNCEMENT **

If your code of whatever kind stopped working with this commit (most
likely the error is something like “object scala not found”) you can
get it working again with either of:

passing -usejavacp on the command line

set system property “scala.usejavacp” to “true”

Either of these will alert scala that you want the java application classpath to be utilized by scala as well.

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...