web-dev-qa-db-fra.com

Appliquer Java pour Scala dans sbt?

Mon scala application ne fonctionnera qu'avec Java 7 car cela dépend des bibliothèques qui n'apparaissaient que dans cette version du JDK).

Comment puis-je appliquer cela dans sbt, afin que le message d'erreur correct soit immédiatement affiché à l'utilisateur s'il utilise la mauvaise version de Java lors du démarrage de sbt pour exécuter/compiler l'application?

REMARQUE: Il n'y a PAS code source Java ™ à compiler ici. I niquement ont Scala. Le code Scala nécessite un import Java.nio.file.Path disponible depuis Java 7.

58
Henry Story

L'utilisation de javacOptions ++= Seq("-source", "1.7", "-target", "1.7") ne fonctionne pas si vous n'avez pas de sources Java.

Mais vous pouvez définir la machine virtuelle Java cible pour le compilateur Scala dans build.sbt ou Build.scala:

scalacOptions += "-target:jvm-1.7"

En conséquence, il imprime sur un JDK 6:

$ sbt clean run
[info] Set current project to default-cd5534 (in build file:/tmp/so/)
[success] Total time: 0 s, completed 27.10.2013 14:31:43
[info] Updating {file:/tmp/so/}default-cd5534...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /tmp/so/target/scala-2.10/classes...
[info] Running Main 
[error] (run-main) Java.lang.UnsupportedClassVersionError: Main : Unsupported major.minor version 51.0
Java.lang.UnsupportedClassVersionError: Main : Unsupported major.minor version 51.0
        at Java.lang.ClassLoader.defineClass1(Native Method)
        at Java.lang.ClassLoader.defineClass(ClassLoader.Java:634)
        at Java.security.SecureClassLoader.defineClass(SecureClassLoader.Java:142)
        at Java.net.URLClassLoader.defineClass(URLClassLoader.Java:277)
        at Java.net.URLClassLoader.access$000(URLClassLoader.Java:73)
        at Java.net.URLClassLoader$1.run(URLClassLoader.Java:212)
        at Java.security.AccessController.doPrivileged(Native Method)
        at Java.net.URLClassLoader.findClass(URLClassLoader.Java:205)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:321)
        at Java.lang.ClassLoader.loadClass(ClassLoader.Java:314)
[trace] Stack trace suppressed: run last compile:run for the full output.
Java.lang.RuntimeException: Nonzero exit code: 1
        at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code: 1
[error] Total time: 4 s, completed 27.10.2013 14:31:47

Remarque: Peut-être que cela ne fonctionne que pour la dernière version de SBT/Scalac.

50
Schleichardt

Étant Scala, vous pouvez mettre des assertions dans la définition de build. Sbt définit le initialize comme un endroit commun pour des choses comme ça, mais vous pouvez utiliser n'importe quel paramètre, y compris un paramètre personnalisé Par exemple,

initialize := {
   val _ = initialize.value // run the previous initialization
   val classVersion = sys.props("Java.class.version")
   val specVersion = sys.props("Java.specification.version")
   assert(..., "Java N or above required")
}
19
Mark Harrah

Pour quiconque à l'avenir, c'est aussi une bonne façon de le faire. Il arrête immédiatement l'exécution s'il ne trouve pas la bonne Java:

initialize := {
  val _ = initialize.value // run the previous initialization
  val required = "1.8"
  val current  = sys.props("Java.specification.version")
  assert(current == required, s"Unsupported JDK: Java.specification.version $current != $required")
}

Vous mettez cela dans votre build.sbt.

18
user2592126

Dans SBT 0.13.6, il y a une nouvelle classe VersionNumber et un trait VersionNumberCompatibility. Ajuster l'approche recommandée par @MarkHarrah pour utiliser celle-ci pourrait faire ce qui suit:

initialize := {
    val _ = initialize.value // run the previous initialization
    val required = VersionNumber("1.8")
    val curr = VersionNumber(sys.props("Java.specification.version"))
    assert(CompatibleJavaVersion(curr, required), s"Java $required or above required")
}

...
/** Java specification version compatibility rule. */
object CompatibleJavaVersion extends VersionNumberCompatibility {
    def name = "Java specification compatibility"
    def isCompatible(current: VersionNumber, required: VersionNumber) =
        current.numbers.Zip(required.numbers).foldRight(required.numbers.size<=current.‌​numbers.size)((a,b) => (a._1 > a._2) || (a._1==a._2 && b))
    def apply(current: VersionNumber, required: VersionNumber) = isCompatible(current, required)
}
11
metasim

Afin de compiler en Java 7, vous devez ajouter l'option javac pour compiler avec la source 1.7.

Vous devez ajouter javacOptions ++= Seq("-source", "1.7") à votre configuration de build SBT qui se trouve dans le dossier/project.

Voici la référence de SBT: http://www.scala-sbt.org/release/docs/Detailed-Topics/Java-Sources.html

3
Andrew Jones

Juste au cas où si vous utilisez les paramètres de changement de scala-ide basés sur Eclipse dans

fenêtre -> pref - scala -> standard -> cible -> jvm-1.7

enter image description here

1
Jai