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.
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.
É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")
}
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
.
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)
}
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