使用docker运行Java 9应用程序不起作用 – UnsupportedClassVersionError

我将我的应用程序从Java 8更改为Java 9.将Windows系统环境variables(path)和JAVA_HOME更改为Java 9(jdk-9.0.1)。

在IDE(IntelliJ)中运行应用程序时,它工作正常。 它也编译没有问题与sbt。 只用docker运行应用程序是行不通的。

应用程序似乎用Java 9成功编译,但是docker试图用Java 8来运行它(这是我从exception消息中读取的)。

命令:

sbt docker:publish docker run --rm -p 9000:9000 eu.gcr.io/the-repository-name/the-image-name:1.0 

我得到以下错误:

 Exception in thread "main" java.lang.UnsupportedClassVersionError: Module has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) at java.net.URLClassLoader.access$100(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:368) at java.net.URLClassLoader$1.run(URLClassLoader.java:362) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:361) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at play.api.inject.Modules$.locate(Module.scala:119) at play.api.inject.guice.GuiceableModule$.loadModules(GuiceInjectorBuilder.scala:276) at play.api.inject.guice.GuiceApplicationBuilder$.$anonfun$$lessinit$greater$default$9$1(GuiceApplicationBuilder.scala:30) at play.api.inject.guice.GuiceApplicationBuilder.applicationModule(GuiceApplicationBuilder.scala:102) at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:185) at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137) at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) at play.core.server.ProdServerStart$.start(ProdServerStart.scala:51) at play.core.server.ProdServerStart$.main(ProdServerStart.scala:25) at play.core.server.ProdServerStart.main(ProdServerStart.scala) 

我需要做什么,Docker使用Java 9?


 java --version java 9.0.1 Java(TM) SE Runtime Environment (build 9.0.1+11) Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode) docker version Client: Version: 17.10.0-ce API version: 1.33 Go version: go1.8.3 Git commit: f4ffd25 Built: Tue Oct 17 19:00:02 2017 OS/Arch: windows/amd64 Server: Version: 17.10.0-ce API version: 1.33 (minimum version 1.12) Go version: go1.8.3 Git commit: f4ffd25 Built: Tue Oct 17 19:05:23 2017 OS/Arch: linux/amd64 Experimental: true 
  • Play版本:2.6.7
  • 斯卡拉版本2.12.4
  • SBT版本:1.0.2
  • sbt-native-packager:1.3.1

这个错误意味着你正在尝试运行在较老版本的Java(8,它的类版本为52.0)中使用较新版本的Java(9,它具有类版本53.0)编译的代码。 所以,你的docker镜像可能已经安装了Java 8。 我们来做一些侦探工作。 🙂

如果我理解正确,您正在使用sbt-native-packager来生成您的Docker镜像。 如果是这样,sbt-native-packager正在使用openjdk:latest image作为基础镜像,如下所示:

https://github.com/sbt/sbt-native-packager/blob/v1.3.1/src/main/scala/com/typesafe/sbt/packager/docker/DockerPlugin.scala#L69

版本1.3.1是Play 2.6.7使用的版本,您也可以在这里看到:

https://github.com/playframework/playframework/blob/2.6.7/framework/project/plugins.sbt#L8

问题是openjdk:latest图像使用Java 8.您可以通过查看图像页面链接的latest代码来确认。 这里是代码:

https://github.com/docker-library/openjdk/blob/a893fe3cd82757e7bccc0948c88bfee09bd916c3/8-jdk/Dockerfile#L38-L43

鉴于此,您可能希望将dockerBaseImage更改为使用使用Java 9的基本映像,例如:

 dockerBaseImage := "9-jdk" 

你可以在这里看到完整的图像版本列表: https : //hub.docker.com/_/openjdk/