Skip to content

Java 21 Gradle Unsupported class file major version 65

Problem Statement

When using Gradle 8.5 with Java 21, you may encounter an error during compilation when introducing new dependencies: Unsupported class file major version 65. This error typically appears as:

startup failed:
General error during conversion: Unsupported class file major version 65

java.lang.IllegalArgumentException: Unsupported class file major version 65
at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:199)
...

Key observations:

  • The error occurs when adding new dependencies to your project
  • Compilation succeeds with Java 17 (JDK 17)
  • A workaround exists: compiling with Java 17, cleaning the build, then switching to Java 21
  • Error code 65 corresponds to Java 21 class files (major version 65 = Java 21)

The core issue involves compatibility between your Gradle version, JDK, and dependencies—specifically older components that don't recognize Java 21's class file format.

Why This Happens

The error occurs because:

  1. Java 21 uses class file major version 65
  2. Older versions of Gradle (pre-8.6) and related tooling contain outdated ASM libraries that don't support version 65
  3. Dependency resolution mechanisms may unexpectedly trigger incompatible components

The workaround you discovered works because the initial Java 17 build generates compatible class files, but this isn't a sustainable solution.

1. Upgrade Gradle to Java 21-Compatible Version

Minimum Requirements:

  • Gradle 8.6+ (first version with full Java 21 support)
  • Gradle 8.7+ (recommended for latest stability patches)

Update your gradle-wrapper.properties:

properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Add to your build.gradle:

groovy
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

Benefits of Java Toolchains:

  • Automatically detects compatible JDKs
  • Ensures consistent compilation across environments
  • Eliminates manual JDK path configuration

3. Set Explicit Compatibility Flags

In your build.gradle:

groovy
java {
    sourceCompatibility = JavaVersion.VERSION_21
    targetCompatibility = JavaVersion.VERSION_21
}

WARNING

This alone may not resolve the issue if your Gradle version is outdated or cache is corrupted. Combine with Solution 1.

4. Clear Gradle Cache and Verify Environment

  1. Delete project-specific caches:

    bash
    ./gradlew clean
    rm -rf .gradle
  2. Verify environment variables:

    bash
    # Check JAVA_HOME matches Java 21 installation
    echo $JAVA_HOME
    
    # Example output should point to JDK 21:
    # /Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home
  3. Update system PATH to include JDK 21 binaries first

5. For Android Projects

Update Android Gradle Plugin (AGP) in settings.gradle:

groovy
pluginManagement {
    plugins {
        id 'com.android.application' version '8.4.0' // Min for Java 21
        id 'com.android.library' version '8.4.0'
    }
}

Update Gradle wrapper (as shown in Solution 1)

Solution Comparison Table

ApproachBenefitWhen to Use
Java Toolchain (Recommended)Automatic JDK handlingAll new projects
Multi-developer environments
Gradle UpgradeResolves core compatibilityRequired for any Java 21 setup
Compatibility FlagsExplicit version targetingProjects requiring specific bytecode output
Cache Clean + Env CheckResolves configuration conflictsAfter changing JDK installations
Android Plugin UpdateFixes Android-specific issuesAndroid projects using Java 21

Why These Solutions Work

  1. Gradle 8.6+ includes updated ASM libraries (9.5+) that support class file version 65
  2. The Java toolchain feature ensures consistent JDK usage across all compilation tasks
  3. Cache clearing eliminates corrupted class files from previous builds
  4. Environment verification prevents conflicts between multiple JDK installations

Best Practices

  • Verify Gradle version with ./gradlew --version
  • Use SDKMAN! for managing multiple JDK versions
  • Prefer toolchains over manual JDK path configuration

Preventing Future Version Conflicts

  1. Create gradle.properties with explicit version:
properties
# gradle.properties
javaVersion=21
org.gradle.java.home=/path/to/jdk21
  1. Reference in build.gradle:
groovy
java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(providers.gradleProperty("javaVersion").get().toInteger())
    }
}

These solutions resolve the core compatibility conflict while establishing a sustainable configuration for Java 21 development with Gradle. The Java toolchain approach provides the most robust long-term solution by decoupling your project from specific JDK installations.