你如何 specify/figure 找出 运行 脂肪罐需要哪个最小值 JDK?
How do you specify/figure out which minimum JDK is required for running the fat jar?
我在一个项目中使用了 sbt-assembly,我有一些 java 14 个 jar,而我的本地机器默认有 JDK 8 个 JDK。
sbt assembly
任务成功,生成了一个fat jar。
当我 运行 它与 JDK 8 时,我得到错误:
Exception in thread "main" java.lang.UnsupportedClassVersionError: javafx/event/EventTarget has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
JDK11(55.0版)是我需要的。果然,当我在 shell 上设置 JDK 11 时,我可以 运行 fat jar.
有没有办法明确 build.sbt
文件中的目标 JDK 版本?
另外,令我惊讶的是,即使我在依赖项中有 Java 14 个 jar,应用程序 运行 在 JDK 11 上也很好。它只是 Java 的一个例子吗的最高向后兼容性在行动?我想知道还有什么可以在工作。
这就是我的 build.sbt
的样子
name := "scalafx-app"
version := "0.1"
scalaVersion := "2.13.3"
scalacOptions += "-Ymacro-annotations"
useCoursier := false
assemblyMergeStrategy in assembly := {
case "module-info.class" => MergeStrategy.concat
case x =>
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
}
lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.1.1"
lazy val osName = System.getProperty("os.name") match {
case n if n.startsWith("Linux") => "linux"
case n if n.startsWith("Mac") => "mac"
case n if n.startsWith("Windows") => "win"
case _ => throw new Exception("Unknown platform!")
}
lazy val javaFXModules = Seq("base", "controls", "fxml", "graphics", "media", "web")
lazy val root = (project in file("."))
.settings(
libraryDependencies += scalaTest % Test,
// scalafx
libraryDependencies += "org.scalafx" %% "scalafx" % "14-R19",
libraryDependencies ++= javaFXModules.map(m =>
"org.openjfx" % s"javafx-$m" % "14.0.1" classifier(osName) withJavadoc()
),
libraryDependencies += "org.scalafx" %% "scalafxml-core-sfx8" % "0.5",
// javafx custom components
libraryDependencies += "com.jfoenix" % "jfoenix" % "9.0.9",
libraryDependencies += "org.kordamp.ikonli" % "ikonli-javafx" % "11.4.0",
libraryDependencies += "org.kordamp.ikonli" % "ikonli-material-pack" % "11.4.0",
// json parsing
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.9.0",
libraryDependencies += "com.squareup.moshi" % "moshi" % "1.9.3",
// logging
libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2",
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.2.3",
)
A JAR 就像 classes 的 zip,每个 class 都是你可以用 javap
检查的那个通过查看 "主要版本" 字段的值,查看他们需要哪个 JDK 版本;参见 this。
如果你想确保 classes 被编译成特定的 Java 版本,你可以使用 release
& target
scalac options.
像这样:
// Ensure the compiler emits Java 8 bytecode.
scalacOptions ++= Seq("-release", "8", "-target:8")
release
用于指定使用哪个Javasdtlib
target
用于指定发出哪个 bytcode 版本。
我在一个项目中使用了 sbt-assembly,我有一些 java 14 个 jar,而我的本地机器默认有 JDK 8 个 JDK。
sbt assembly
任务成功,生成了一个fat jar。
当我 运行 它与 JDK 8 时,我得到错误:
Exception in thread "main" java.lang.UnsupportedClassVersionError: javafx/event/EventTarget has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
JDK11(55.0版)是我需要的。果然,当我在 shell 上设置 JDK 11 时,我可以 运行 fat jar.
有没有办法明确 build.sbt
文件中的目标 JDK 版本?
另外,令我惊讶的是,即使我在依赖项中有 Java 14 个 jar,应用程序 运行 在 JDK 11 上也很好。它只是 Java 的一个例子吗的最高向后兼容性在行动?我想知道还有什么可以在工作。
这就是我的 build.sbt
的样子
name := "scalafx-app"
version := "0.1"
scalaVersion := "2.13.3"
scalacOptions += "-Ymacro-annotations"
useCoursier := false
assemblyMergeStrategy in assembly := {
case "module-info.class" => MergeStrategy.concat
case x =>
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
}
lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.1.1"
lazy val osName = System.getProperty("os.name") match {
case n if n.startsWith("Linux") => "linux"
case n if n.startsWith("Mac") => "mac"
case n if n.startsWith("Windows") => "win"
case _ => throw new Exception("Unknown platform!")
}
lazy val javaFXModules = Seq("base", "controls", "fxml", "graphics", "media", "web")
lazy val root = (project in file("."))
.settings(
libraryDependencies += scalaTest % Test,
// scalafx
libraryDependencies += "org.scalafx" %% "scalafx" % "14-R19",
libraryDependencies ++= javaFXModules.map(m =>
"org.openjfx" % s"javafx-$m" % "14.0.1" classifier(osName) withJavadoc()
),
libraryDependencies += "org.scalafx" %% "scalafxml-core-sfx8" % "0.5",
// javafx custom components
libraryDependencies += "com.jfoenix" % "jfoenix" % "9.0.9",
libraryDependencies += "org.kordamp.ikonli" % "ikonli-javafx" % "11.4.0",
libraryDependencies += "org.kordamp.ikonli" % "ikonli-material-pack" % "11.4.0",
// json parsing
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.9.0",
libraryDependencies += "com.squareup.moshi" % "moshi" % "1.9.3",
// logging
libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.9.2",
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.2.3",
)
A JAR 就像 classes 的 zip,每个 class 都是你可以用 javap
检查的那个通过查看 "主要版本" 字段的值,查看他们需要哪个 JDK 版本;参见 this。
如果你想确保 classes 被编译成特定的 Java 版本,你可以使用 release
& target
scalac options.
像这样:
// Ensure the compiler emits Java 8 bytecode.
scalacOptions ++= Seq("-release", "8", "-target:8")
release
用于指定使用哪个Javasdtlibtarget
用于指定发出哪个 bytcode 版本。