1

I have an issue with the java.lang.UnsupportedClassVersionError error that is being thrown during my test executions. I understand the error and solved it before but in this case I am a bit lost.

This is the error messages (does appear for all test classes):

java.lang.UnsupportedClassVersionError: com/game/backend/resolver/QueryResolverTest 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

And this is my Dockerfile:

FROM gradle:6.6.1-jdk8 as builder
USER root
WORKDIR /builder
ADD . /builder
RUN gradle build --debug

FROM openjdk:11.0.8-slim
WORKDIR /app
EXPOSE 8082
COPY --from=builder /builder/build/libs/game-backend.jar app.jar
CMD ["java", "-jar", "app.jar"]

What I don't understand here is why he says it's compiled by a more recent version? The FROM gradle:6.6.1-jdk8 tells me it's JDK 1.8 which means it's class file version 52 (according to: List of Java class file format major version numbers?). So why is it saying the class was compiled by 55 (Java 11) ?

xetra11
  • 7,671
  • 14
  • 84
  • 159

2 Answers2

0

Ok well I acted a bit small minded here. Even tho the docker image FROM gradle:6.6.1-jdk8 is in fact JDK 1.8 does not mean that gradle will compile with JDK 1.8 it seems.

So I changed it to FROM gradle:6.6.1-jdk11 as builder using JDK 11 now. Why is that helping now?

Well my build.gradle.kt is using:

...
java.sourceCompatibility = JavaVersion.VERSION_11
...
tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "11"
    }
}
...

Which obviously shows that gradle will compile my classes with JDK 11. However what I thought is that only the JDK given by the Docker image FROM (that was JDK8) is available and gradle should've tell me something like

You wanted to build with JDK 11, since that's what your build.gradle says but you only have JDK 8 available (through the gradle:6.6.1-jdk8) image.

But I forgot that gradle itself can download stuff. Which is logical since it's downloading dependencies. So it also seems to download the JDK (11 in this case) it needs to compile according to the build.gradle. However Running the tests is using the Java Runtime Environment and that was brought in by gradle:6.6.1-jdk8 therefore the JRE 8 and not 11 (which is needed since it's all compiled for 11 by gradle).

xetra11
  • 7,671
  • 14
  • 84
  • 159
0

It looks like you have two FROM commands in your Dockerfile and the Java 11 is second so is probably taking precedence.

tschumann
  • 2,776
  • 3
  • 26
  • 42
  • No because the gradle build is running under the layer of the first. The second `FROM` is therefore never reached – xetra11 Sep 09 '20 at 06:25