2011-12-07 15 views
18

Il comando ': javap' nella console di scala 2.9.1 richiede il tool.jar (da JDK6) nel 'classpath'. Da cmd-line può essere fatto con l'argomento '-cp' o la variabile d'ambiente CLASSPATH.Aggiungere tools.jar nel classpath del progetto sbt

Come fare lo stesso per la console di scala che ha invocato da SBT con i comandi "console" e "console-quick"?

risposta

31

risposta lunga, che potrebbe aiutarti altrove.

Se voglio sapere qualcosa in SBT, ho inspect esso:

> inspect console 
[info] Task: Unit 
[info] Description: 
[info] Starts the Scala interpreter with the project classes on the classpath. 
[info] Provided by: 
[info] {file:/home/dcs/github/anti-xml/}default-39679a/compile:console 
[info] Dependencies: 
[info] compile:compilers(for console) 
[info] compile:full-classpath 
[info] compile:scalac-options(for console) 
[info] compile:initial-commands(for console) 
[info] compile:streams(for console) 
[info] Delegates: 
[info] compile:console 
[info] *:console 
[info] {.}/compile:console 
[info] {.}/*:console 
[info] */compile:console 
[info] */*:console 
[info] Related: 
[info] test:console 

Ok, c'è una dipendenza interessante in compile:full-classpath. Vorrei che fosse compile:full-classpath(for console), ma non lo è. Tuttavia, non dovrebbe causarmi problemi in questo caso. Facciamo inspect it.

> inspect compile:full-classpath 
[info] Task: scala.collection.Seq[sbt.Attributed[java.io.File]] 
[info] Description: 
[info] The exported classpath, consisting of build products and unmanaged and managed, internal and external dependencies. 
[info] Provided by: 
[info] {file:/home/dcs/github/anti-xml/}default-39679a/compile:full-classpath 
[info] Dependencies: 
[info] compile:exported-products 
[info] compile:dependency-classpath 
[info] Reverse dependencies: 
[info] compile:console 
[info] Delegates: 
[info] compile:full-classpath 
[info] *:full-classpath 
[info] {.}/compile:full-classpath 
[info] {.}/*:full-classpath 
[info] */compile:full-classpath 
[info] */*:full-classpath 
[info] Related: 
[info] compile:full-classpath(for doc) 
[info] test:full-classpath 
[info] test:full-classpath(for doc) 
[info] *:full-classpath(for console) 
[info] runtime:full-classpath 
[info] compile:full-classpath(for console) 

Ok, potrei andare oltre nelle dipendenze, ma non penso sia necessario. Vediamo cosa c'è dentro:

> show compile:full-classpath 
[warn] Credentials file /home/dcs/.ivy2/.credentials does not exist 
[info] List(Attributed(/home/dcs/github/anti-xml/target/scala-2.9.1/classes), Attributed(/home/dcs/.sbt/boot/scala-2.9.1/lib/scala-library.jar)) 
[success] Total time: 0 s, completed Dec 7, 2011 3:49:30 PM 

Ok, niente di inaspettato. Aggiungiamo tools.jar.

Per cambiare qualcosa devo usare set, e devo rispettare un sacco di casi di cammello e altre regole per farlo funzionare. Se avessi compile:full-classpath(for console), quello diventerebbe fullClasspath in Compile in console. Notare il maiuscolo in Compile e che full-classpath è diventato fullClasspath e il generale riordino dei nomi di elemento. Details here.

Credo che uno dovrebbe essere in grado di prendere l'output di show (o, almeno, inspect) e dei mangimi destra di nuovo a set, ma questo non è il caso (per ora, comunque), quindi basta imparare queste regole conversioni .

Non voglio ridigitare tutto, basta aggiungere un file JAR. Devo usare += per quello. Gli operatori utilizzati per cambiare le cose possono essere trovati here.

Il classpath sembra aver bisogno di alcune cose da Attributed. Controlla i documenti dettagliati su Classpath nel wiki SBT e scopri come ottenerne uno. Fortunatamente, la maggior parte dei valori che potrei voler cambiare non è così difficile da creare come questa.

> set fullClasspath in Compile += Attributed.blank(file("/usr/lib/jvm/java-6-sun-1.6.0.26/lib/tools.jar")) 
[info] Reapplying settings... 
[info] Set current project to anti-xml (in build file:/home/dcs/github/anti-xml/) 

Sembra aver funzionato. Diamo il suo contenuto a show per confermare, poiché anche scrivere compile anziché Compile potrebbe farlo cambiare la cosa sbagliata.

> show compile:full-classpath                    
[warn] Credentials file /home/dcs/.ivy2/.credentials does not exist 
[info] List(Attributed(/home/dcs/github/anti-xml/target/scala-2.9.1/classes), Attributed(/home/dcs/.sbt/boot/scala-2.9.1/lib/scala-library.jar), Attributed(/usr/lib/jvm/java-6-sun-1.6.0.26/lib/tools.jar)) 
[success] Total time: 0 s, completed Dec 7, 2011 3:50:07 PM 

Sì, eccolo. Proviamoci:

> console 
[warn] Credentials file /home/dcs/.ivy2/.credentials does not exist 
[info] Starting scala interpreter... 
[info] 
import com.codecommit.antixml._ 
bookstore: com.codecommit.antixml.Elem = <bookstore><book><title>For Whom the Bell Tolls</title><author>Hemmingway</author></book><book><title>I, Robot</title><author>Isaac Asimov</author></book><book><title>Programming Scala</title><author>Dean Wampler</author><author>Alex Payne</author></book></bookstore> 
books: com.codecommit.antixml.Zipper[com.codecommit.antixml.Elem] = <book><title>For Whom the Bell Tolls</title><author>Hemmingway</author></book><book><title>I, Robot</title><author>Isaac Asimov</author></book><book><title>Programming Scala</title><author>Dean Wampler</author><author>Alex Payne</author></book> 
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_26). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> :javap com.codecommit.antixml.Elem 
Compiled from "node.scala" 
public class com.codecommit.antixml.Elem extends java.lang.Object implements com.codecommit.antixml.Node,com.codecommit.antixml.Selectable,scala.ScalaObject,scala.Product,scala.Serializable{ 
    public static final scala.Function1 tupled(); 
    public static final scala.Function1 curry(); 
    public static final scala.Function1 curried(); 
    public static final boolean isValidName(java.lang.String); 
    public scala.collection.Iterator productIterator(); 
    public scala.collection.Iterator productElements(); 
    public java.lang.Object $bslash(com.codecommit.antixml.Selector, com.codecommit.antixml.CanBuildFromWithZipper); 
    public java.lang.Object $bslash$bslash(com.codecommit.antixml.Selector, com.codecommit.antixml.CanBuildFromWithZipper); 
    public java.lang.Object $bslash$bslash$bang(com.codecommit.antixml.Selector, com.codecommit.antixml.CanBuildFromWithZipper); 
    public java.lang.Object select(com.codecommit.antixml.Selector, com.codecommit.antixml.CanBuildFromWithZipper); 
    public com.codecommit.antixml.Zipper toZipper(); 
    public scala.Option prefix(); 
    public java.lang.String name(); 
    public com.codecommit.antixml.Attributes attrs(); 
    public scala.collection.immutable.Map scope(); 
    public com.codecommit.antixml.Group children(); 
    public com.codecommit.antixml.Elem canonicalize(); 
    public java.lang.String toString(); 
    public com.codecommit.antixml.Group toGroup(); 
    public com.codecommit.antixml.Group copy$default$5(); 
    public scala.collection.immutable.Map copy$default$4(); 
    public com.codecommit.antixml.Attributes copy$default$3(); 
    public java.lang.String copy$default$2(); 
    public scala.Option copy$default$1(); 
    public com.codecommit.antixml.Elem copy(scala.Option, java.lang.String, com.codecommit.antixml.Attributes, scala.collection.immutable.Map, com.codecommit.antixml.Group); 
    public int hashCode(); 
    public boolean equals(java.lang.Object); 
    public java.lang.String productPrefix(); 
    public int productArity(); 
    public java.lang.Object productElement(int); 
    public boolean canEqual(java.lang.Object); 
    public com.codecommit.antixml.Elem(scala.Option, java.lang.String, com.codecommit.antixml.Attributes, scala.collection.immutable.Map, com.codecommit.antixml.Group); 
} 

Successo !!!

Ovviamente questa sessione è una bugia. Mi ci è voluto molto più tempo per arrivare lì, ma è soprattutto pratica.

+0

Grazie, Daniel, per la risposta dettagliata. –

+0

con SBT 0.12.0 ottengo: $ console sbt scala> impostato fullClasspath in Compile + = Attributed.blank (file ("/ usr/lib/jvm/jdk1.7.0/lib/tools.jar")) : 1: errore: ';' aspettato ma '.' trovato. set fullClasspath in Compile + = Attributed.blank (file ("/ usr/lib/jvm/jdk1.7.0/lib/tools.jar")) –

+1

Non sicuro quale versione di SBT sia successo, ma ora la dipendenza è 'compile: console :: fullClasspath' come desiderato. 'fullClasspath in Compile in console' funziona. –

6

https://github.com/ensime/ensime-server/blob/master/build.sbt#L35

// epic hack to get the tools.jar JDK dependency 
val JavaTools = List[Option[String]] (
    // manual 
    sys.env.get("JDK_HOME"), 
    sys.env.get("JAVA_HOME"), 
    // osx 
    try Some("/usr/libexec/java_home".!!.trim) 
    catch { 
    case _: Throwable => None 
    }, 
    // fallback 
    sys.props.get("java.home").map(new File(_).getParent), 
    sys.props.get("java.home") 
).flatten.map { n => 
    new File(n + "/lib/tools.jar") 
}.find(_.exists).getOrElse (
    throw new FileNotFoundException (
    """Could not automatically find the JDK/lib/tools.jar. 
     |You must explicitly set JDK_HOME or JAVA_HOME.""".stripMargin 
) 
) 
Problemi correlati