Я пытаюсь запустить приложение Scala, упакованное как JAR (включая зависимости), но это не удастся, пока библиотека Scala не будет добавлена с помощью параметра -Xbootclasspath/p
.
Сбой вызова:
java -jar /path/to/target/scala-2.10/application-assembly-1.0.jar
После того, как приложение выполнило какой-либо намеченный вывод, консоль показывает:
Исключение в потоке "main" scala.reflect.internal.MissingRequirementError: object scala.runtime в зеркале компилятора не найден. в scala.reflect.internal.MissingRequirementError $.signal(MissingRequirementError.scala: 16) в scala.reflect.internal.MissingRequirementError $.notFound(MissingRequirementError.scala: 17) на scala.reflect.internal.Mirrors $RootsBase.getModuleOrClass(Зеркала .scala: 48) в scala.reflect.internal.Mirrors $RootsBase.getModuleOrClass(Mirrors.scala: 40) в scala.reflect.internal.Mirrors $RootsBase.getModuleOrClass(Mirrors.scala: 61) в scala.reflect.internal.Mirrors $RootsBase.getPackage(Зеркала .scala: 172) в scala.reflect.internal.Mirrors $RootsBase.getRequiredPackage(Зеркала .scala: 175) at scala.reflect.internal.Definitions $ОпределенияClass.RuntimePackage $lzycompute (Определения .scala: 181) at scala.reflect.internal.Definitions $DefinitionsClass.RuntimePackage(Definitions.scala: 181) at scala.reflect.internal.Definitions $ОпределенияClass.RuntimePackageClass $lzycompute (Определения .scala: 182) at scala.reflect.internal.Definitions $DefinitionsClass.RuntimePackageClass(Определения .scala: 182) at scala.reflect.internal.Definitions $ОпределенияClass.AnnotationDefaultAttr $lzycompute (Определения .scala: 1015) at scala.reflect.internal.Definitions $DefinitionsClass.AnnotationDefaultAttr(Определения .scala: 1014) at scala.reflect.internal.Definitions $ОпределенияClass.syntheticCoreClasses $lzycompute (Определения .scala: 1144) at scala.reflect.internal.Definitions $DefinitionsClass.syntheticCoreClasses(Definitions.scala: 1143) at scala.reflect.internal.Definitions $DefinitionsClass.symbolsNotPresentInBytecode $lzycompute (Определения .scala: 1187) at scala.reflect.internal.Definitions $DefinitionsClass.symbolsNotPresentInBytecode(Definitions.scala: 1187) at scala.reflect.internal.Definitions $ОпределенияClass.init(Определения .scala: 1252) at scala.tools.nsc.Global $Run. (Global.scala: 1290) at extract.ScalaExtractor $Компилятор $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
, и была вызвана цель assembly
. Файл JAR с результатами около 25 МБ.
Построение JAR с помощью proguard показывает то же поведение во время выполнения, что и в файле сборки 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
.
Для информации о curios/background
Цель приложения - помочь в локализации программ Java и Scala. Задача фрагмента кода выше - получить AST из файла Scala, чтобы найти там вызовы методов.
Вопросы
- Учитывая, что библиотека Scala включена в файл JAR, почему необходимо вызвать JAR с помощью
-Xbootclasspath/p:scala-library.jar
? - Почему другие части приложения работают нормально, даже если
scala.runtime
сообщается как пропавший позже?