Search code examples
javagradlebuildpackjava-17paketo

How do I enable a Cloud Native Buildpacks builder to detect my Gradle Java project's Java version?


I'm having trouble getting either of the two Cloud Native Buildpacks builders I've tried (gcr.io/buildpacks/builder:v1 and paketobuildpacks/builder:base) to fully detect my desired Java version so that the right JVM is used to build my project and to run it. It seems to successfully detect my desired version as it completes the build step, but I notice in the logs during the build that it ends up downloading a version 11 JDK and I get an error when trying to run a container from the built image:

Error: LinkageError occurred while loading main class com.mattwelke.javatests.JavalinPostgresJdbc
java.lang.UnsupportedClassVersionError: com/mattwelke/javatests/JavalinPostgresJdbc has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0

This error infers that it chose to use JDK 17 to build the class files but then JDK 11 to run them.

My project structure is the one produced by running gradle init and choosing "application" as the type of project to be created, except I moved the contents of app up into the root and deleted settings.gradle. I found that I had to do that in order for the first builder I tried to be able to detect it as a Gradle project in the first place. I also had to add id 'com.github.johnrengelman.shadow' version '7.1.2' to the plugins section of build.gradle, otherwise the builder failed to build, with an error about not being able to find a main class.

I added the following to build.gradle to indicate my preferred Java version for the project:

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

I thought that this might be something I'm doing wrong, therefore being a good reason to post to Stack Overflow, instead of raising a GitHub issue in either of the repos for the two builders I tried, because I got the exact same error with both builders (the one from Google and the one from Paketo).


Solution

  • I can't speak to the first builder, but for Paketo Buildpacks, you just need to set BP_JVM_VERSION and that'll tell the builder what version to use. It'll use Java 11 by default, so I think that's why you're getting Java 11.

    Ex: pack build cool-app -e BP_JVM_VERSION=17

    https://paketo.io/docs/howto/java/#install-a-specific-jvm-version

    There is a Gradle Sample App available here.


    I don't know why some things have been built with Java 17, but for the Paketo Java buildpack, you cannot build with one version and run with another version, the same version is always used for both build and run.

    The only time I've seen this happen is when I build locally on Java 17 and pack build -p build/libs/app.jar, forgetting to set BP_JVM_VERSION to 17. In that case, it'll build from my locally compiled code which is from a newer Java version.

    If you leave off the -p argument or have -p point to your Java source code, then you should always get a consistent build with the same version of Java at build and runtime.