gradlegradle-plugingradlew

How do I relocate an existing jar file using gradle?


I'm working on a project that uses java, among other things, and bazel. I'm running into a mess of dependency conflicts and want to shade a jar. Bazel does not have a way to do this so I am using Gradle which I have never used before. Working with chatGPT this is the script I currently have:


    plugins {
        id("java")
        id("com.github.johnrengelman.shadow") version "8.1.1"
    }
    
    repositories {
        mavenCentral()
        maven {
            url = uri("https://mvnrepository.com/artifact")
        }
    }
    
    dependencies {
        implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.0'
    }
    
    tasks.named('shadowJar', com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
        relocate 'com.fasterxml.jackson', 'shaded.com.fasterxml.jackson'
    }

Gradle is version 8.10.2. The error I'm getting is this:

    java.lang.IllegalArgumentException: Unsupported class file major version 65
            at org.objectweb.asm.ClassReader.<init>(ClassReader.java:199)
            at org.objectweb.asm.ClassReader.<init>(ClassReader.java:180)
            at org.objectweb.asm.ClassReader.<init>(ClassReader.java:166)
            at org.objectweb.asm.ClassReader.<init>(ClassReader.java:287)

Between Googling and ChatGPT I've tried quite a few things, but nothing has quite worked and ChatGPT is starting to spit out the same recommendations already tried.

Edit: For additional clarification about the solution, I switched to openjdk 21 and then switched the plugin to com.gradleup.shadow which seems to be the successor to the dead repo I had been using.


Solution

  • General

    It seems your gradle version uses a Java compiler which cannot handle Java 21 byte code - maybe compiled by Bazel.

    Check Java version used by gradle

    If you use a gradle wrapper (which is the recommended way - see https://docs.gradle.org/current/userguide/gradle_wrapper.html)

    you can check this by

    ./gradlew --version
    

    from command line.

    If you use a system installed gradle version the command will be:

    gradle --version
    

    In both situations you will get an output like:

    ------------------------------------------------------------
    Gradle 8.10.2
    ------------------------------------------------------------
    
    Build time:   2023-11-29 14:08:57 UTC
    Revision:     28aca86a7180baa17117e0e5ba01d8ea9feca598
    
    Kotlin:       1.9.20
    Groovy:       3.0.17
    Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
    JVM:          17.0.12 (Eclipse Adoptium 17.0.12+7)
    OS:           Linux 5.15.0-122-generic amd64
    

    In the example above, you see that gradle uses Java 17.

    Change Java JDK version in gradle

    To change this, you can either setup this inside build.gradle - see How do I tell Gradle to use specific JDK version?

    Or you install on your OS a JDK >= Java 21 (this must be the OS default afterwards).

    Then check used Java version again by ./gradlew --version. When the output shows the Java 21 version your build should work now.