3

I changed my application from Java 8 to Java 9. Changed the Windows system environment variable (path) and the JAVA_HOME to Java 9 (jdk-9.0.1).

When running the application in the IDE (IntelliJ) it works fine. It also compiles without problems with sbt. Just running the application with docker doesn't work.

The application seems to be compiled successfully with Java 9 but docker tries to run it with Java 8 (this is what I read from the exception message).

Commands:

sbt docker:publish

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

I get the following error:

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)

What do I have to do, that Docker uses 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 Version: 2.6.7
  • Scala Version 2.12.4
  • SBT Version: 1.0.2
  • sbt-native-packager: 1.3.1
Spenhouet
  • 6,556
  • 12
  • 51
  • 76
  • 2
    You might want to mention the version of the libraries used. And the primary issue here is a core library compiling Java 9 code as Java 8 code instead. Related [Unable to process file module-info.class within a Java9 project results in ClassFormatException](https://stackoverflow.com/questions/45802981/unable-to-process-file-module-info-class-within-a-java9-project-results-in-class) – Naman Oct 30 '17 at 15:34
  • @nullpointer Can you explain further? The application is running fine in my IDE, it compiles without problems with Java 9 (not Java 8). Only if I publish and run it with docker it doesn't work. The error suggests that the project is compiled with java 9 but docker uses java 8. – Spenhouet Oct 30 '17 at 15:37
  • I would guess while you 'publish' and 'run', you might be making use of some core library transitively which might be trying to access the class files as if they are java 8 classes, while they have been compiled using Java 9 instead. For further debugging, you might want to state the complete logs,detailed steps followed during publish and run as mentioned in the question...Wildest of guess ASM has been a library responsible for few such instances I have witnessed in different libraries. – Naman Oct 30 '17 at 15:41

1 Answers1

2

The error means that you are trying to run code compiled using a newer version of Java (9 which has class version 53.0) in an older version of Java (8 which has class version 52.0). So, your docker image probably has Java 8 installed. Let's do some detective work. :-)

If I understand correctly, you are using sbt-native-packager to generate your Docker image. If so, sbt-native-packager is using openjdk:latest image as the base image, as you can see here:

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

Version 1.3.1 is the version used by Play 2.6.7, as you can also see here:

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

The problem is that openjdk:latest image uses Java 8. You can confirm that by looking at the latest code linked at the image page. Here is the code:

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

Given that, you may want to change dockerBaseImage to use a base image that uses Java 9, for example:

dockerBaseImage := "9-jdk"

You can see a complete list of image versions here: https://hub.docker.com/_/openjdk/

marcospereira
  • 12,045
  • 3
  • 46
  • 52
  • 1
    This sound like what I thought. I didn't know how to change the used jdk version. On monday I will give it a try. – Spenhouet Nov 17 '17 at 19:31