2010-11-08 15 views
8

Come richiesto in this thread sulla mailing list di Scala, come posso creare un REPL di Scala incorporato che eredita il classpath del programma principale? Supponiamo che il programma principale della famiglia sia lanciato usando scala -cp <classpath> ...; È possibile accedere a <classpath> come stringa e utilizzare per inizializzare il REPL incorporato? (Il Java classpath, disponibile tramite System.getProperty("java.class.path"), sembra differire dal percorso di classe Scala.)Embedded Scala REPL eredita il classpath genitore

In alternativa, forse i (ScalaDays di Michael Dürig embedded Scala REPL può ereditare o costruire il suo ClassLoader dal processo genitore 2010 colloquio potrebbero essere rilevanti). È questo l'approccio raccomandato?

+0

Non ho mai sentito parlare di un interprete di Scala. Dove lo posso prendere? – ziggystar

+0

Per interprete intendo il REPL di Scala. Viene fornito con il compilatore Scala. È ciò che ottieni quando esegui l'eseguibile 'scala' dalla riga di comando. Questa domanda riguarda l'incorporamento di un REPL all'interno di un programma Scala in esecuzione. –

+0

Ho modificato la tua risposta per riflettere che intendi REPL. – ziggystar

risposta

6

che sto cercando di fare la stessa cosa, e ho appena trovato un modo mio da Googling:

lazy val urls = java.lang.Thread.currentThread.getContextClassLoader match { 
    case cl: java.net.URLClassLoader => cl.getURLs.toList 
    case _ => error("classloader is not a URLClassLoader") 
} 
lazy val classpath = urls map {_.toString} 

Il codice di cui sopra si ottiene il percorso di classe nel contesto attuale.

settings.classpath.value = classpath.distinct.mkString(java.io.File.pathSeparator) 

Metti che nella vostra settings.classpath e si dovrebbe essere in grado di accendere la spedizione o qualunque libreria che vi serve.

+0

Grazie, questo è utile.La soluzione che avevo scelto era di usare la variabile di ambiente del classpath Java (ad esempio '$ CLASSPATH') invece del classpath Scala. Il classpath Java viene ereditato dall'interprete incorporato e quindi funziona l'opzione "usejavacp". –

2

impostare la proprietà usejavacp true:

val settings = new scala.tools.nsc.Settings 
settings.usejavacp.value = true 
+0

Questa tecnica non sembra aggiungere il classpath _Scala_ all'interprete appena creato. Come documentato in scala.tools.nsc.StandardScalaSettings.scala', questa opzione include solo 'java.class.path' nella risoluzione del percorso di classe. –

+0

Dai un'occhiata a https://lampsvn.epfl.ch/trac/scala/wiki/Classpath e il relativo codice sorgente su http://lampsvn.epfl.ch/svn-repos/scala/scala-msil/trunk/ src/compiler/scala/tools/util/PathResolver.scala Questi descrivono l'attuale gestione del percorso di classe in modo abbastanza dettagliato. – michid

+0

Non sono sicuro di come utilizzare queste informazioni. Esiste un modo per accedere all'istanza di scala.tools.util.PathResolver nel programma attualmente in esecuzione? Se è così, posso riutilizzare il suo oggetto Impostazioni per l'interprete incorporato che sto creando. –

1

Ci non sembra essere un modo semplice per accedere al "classpath Scala" dall'interno di un programma Scala in esecuzione (al contrario, il "percorso di classe Java" è disponibile tramite la proprietà di sistema java.class.path). Si vorrebbe accedere, ad esempio, al campo Calculated.userClasspath nell'istanza di scala.tools.PathResolver, ma quest'ultimo non sembra accessibile. Forse la soluzione più semplice è modificare lo script di avvio scala per memorizzare la stringa di parametro in una variabile di ambiente.

Supponendo che il percorso di classe Scala desiderato può essere determinato, può essere passato all'interprete Scala incorporato tramite: settings.classpath.value = ...

Aggiornamento: anche se la stringa classpath Scala non può essere direttamente raggiungibile dalla runtime Scala, @ Eugene sottolinea che può essere estratto dal classloader di contesto. Grazie.

Problemi correlati