Sto provando a eseguire un'applicazione Scala compresso come JAR (incluse le dipendenze), ma questo fallisce fino alla Scala la libreria viene aggiunta utilizzando l'opzione -Xbootclasspath/p
."scala.runtime nel mirror del compilatore non trovato", ma funzionante quando avviato con -Xbootclasspath/p: scala-library.jar
invocazione mancanza:
java -jar /path/to/target/scala-2.10/application-assembly-1.0.jar
Dopo l'applicazione ha fatto parte della sua produzione destinata, la console mostra:
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)
invocazione di lavoro:
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
La cosa strana su di esso è che il application-assembly-1.0.jar
è stato creato in modo che includa tutte le dipendenze nella libreria Scala. Quando si estrae il file JAR, è possibile verificare che siano stati inclusi i file di classe nel pacchetto scala.runtime
.
Creazione del file JAR
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.9.1")
è stato aggiunto al project/plugins.sbt
e l'obiettivo assembly
è stato invocato. Un file JAR di circa 25 MB di risultati.
Costruire il JAR con proguard mostra lo stesso comportamento di runtime visto con il file JAR di assembly.
codice di applicazione che fa scattare il codice
Alcuni applicazione MissingRequirementError funziona bene e l'eccezione descritto in precedenza viene attivato non appena il new Run
dai seguenti Esegue frammento.
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)
tra gli altri, scala-library
, scala-compiler
e scala-reflect
sono definiti come dipendenze in build.sbt
.
Per informazioni curiosità/sfondo
Lo scopo dell'applicazione è quello di aiutare nella localizzazione dei programmi Java e Scala. Il compito del frammento di codice sopra è quello di ottenere un AST da un file Scala per trovare le chiamate al metodo in quel punto.
Le domande
- Data la libreria Scala è incluso nel file JAR, il motivo per cui è necessario chiamare il JAR utilizzando
-Xbootclasspath/p:scala-library.jar
? - Perché altre parti dell'applicazione funzionano correttamente anche se
scala.runtime
viene segnalato come mancante in seguito?
questo potrebbe essere perché non avete dato alcun percorso di classe a quella esecuzione del compilatore da usare. Invece di 'Global (new Settings())', prova a dargli delle impostazioni che abbiano lo stesso classpath del tuo programma: 'settings.classpath.value = System.getProperty (" java.class.path ")'. – gourlaysama
o forse 'settings.usejavacp.value = true', o qualcosa di simile ... – gourlaysama
Grazie mille per i vostri commenti. Sembra che io abbia erroneamente assunto che le impostazioni del compilatore siano predefinite a quelle del programma di richiamo. L'aggiunta di 'settings.usejavacp.value = true' o' settings processArgumentString "-usejavacp" 'comporterà un compilatore correttamente configurato e quindi un programma di lavoro. –