Android项目解决Unsupported class file major version 61错误

0 次阅读

Android项目开发过程中,如果遇到 Unsupported class file major version 61,通常不是代码本身存在语法错误,而是 Java版本、Gradle版本、Android Gradle Plugin(AGP)版本之间不兼容导致的。

其中,major version 61 对应 Java 17。也就是说,某个 .class 文件是使用 Java 17 编译生成的,但当前Android构建环境中的Java运行时、Gradle或相关构建工具无法正确解析这个版本的字节码。

一、Unsupported class file major version 61是什么意思

典型错误信息类似:

Unsupported class file major version 61

或者:

java.lang.IllegalArgumentException:
Unsupported class file major version 61

还可能出现在Gradle构建过程中:

Execution failed for task ':app:compileDebugJavaWithJavac'.

需要重点关注 major version 61

Java编译后的 .class 文件内部包含版本信息,不同JDK生成的class文件版本并不相同:

Java版本Class Major Version
Java 852
Java 953
Java 1054
Java 1155
Java 1256
Java 1357
Java 1458
Java 1559
Java 1660
Java 1761
Java 1862
Java 1963
Java 2064
Java 2165

所以看到:

Unsupported class file major version 61

基本可以判断:当前构建链中存在Java 17编译出来的class文件,而负责读取它的工具版本过低。

二、为什么Android项目容易出现这个错误

Android项目的构建环境并不是只有一个Java版本。

一个项目通常同时涉及:

Android Studio
      ↓
JDK
      ↓
Gradle
      ↓
Android Gradle Plugin
      ↓
各种Gradle插件
      ↓
项目依赖

任何一层存在版本不匹配,都可能出现class文件版本错误。

例如:

某个依赖使用JDK 17编译
        ↓
class文件版本 = 61
        ↓
项目使用较旧的Gradle
        ↓
旧Gradle无法解析Java 17 class
        ↓
Unsupported class file major version 61

因此,单纯修改业务代码通常无法解决这个问题。

三、首先检查当前Java版本

打开终端执行:

Bash
java -version

例如:

openjdk version "17.0.12"
OpenJDK Runtime Environment
OpenJDK 64-Bit Server VM

如果显示:

17

说明当前命令行使用的是Java 17。

也可以执行:

Bash
javac -version

查看Java编译器版本。

需要注意的是,终端中的Java版本和Android Studio使用的Gradle JDK可能不是同一个版本

四、检查Android Studio使用的Gradle JDK

Android Studio中可以检查Gradle使用的JDK。

通常可以进入:

Settings
→ Build, Execution, Deployment
→ Build Tools
→ Gradle

找到:

Gradle JDK

不同版本Android Studio的界面名称可能略有区别。

如果项目要求Java 17,而这里仍然使用Java 8或Java 11,就可能产生构建问题。

例如项目明确采用较新的Android Gradle Plugin:

Android Gradle Plugin
8.x

那么通常应该使用:

JDK 17

而不是继续使用JDK 8。

五、检查项目使用的Gradle版本

打开项目根目录下的:

gradle/wrapper/gradle-wrapper.properties

查看:

properties
distributionUrl=https://services.gradle.org/distributions/gradle-xxx-bin.zip

例如:

properties
distributionUrl=https://services.gradle.org/distributions/gradle-8.2-bin.zip

这里的版本就是项目实际使用的Gradle版本。

也可以执行:

Bash
./gradlew --version

Windows系统可以使用:

bat
gradlew.bat --version

输出中通常可以看到:

Gradle 8.x
JVM: 17.x

这比单独执行 java -version 更有参考价值,因为它能够直接确认Gradle实际运行在哪个JDK上。

六、检查Android Gradle Plugin版本

继续查看项目的Gradle配置。

传统项目可能在:

build.gradle

中看到:

gradle
buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:7.4.2'
    }
}

较新的项目则可能使用:

Kotlin
plugins {
    id 'com.android.application' version '8.1.0' apply false
}

这里的:

com.android.tools.build:gradle

或者:

com.android.application

对应的版本,就是Android Gradle Plugin版本。

需要让以下三个部分相互匹配:

JDK
Gradle
Android Gradle Plugin

不要只看到错误就盲目升级其中一个。

七、最常见的解决方案:升级Gradle和构建插件

如果项目使用较老的Gradle,但依赖或者插件已经采用Java 17编译,可以考虑升级Gradle。

例如原项目:

Gradle 6.x
Android Gradle Plugin 4.x

而某个新依赖已经使用Java 17编译,那么旧构建链就可能无法处理major version 61。

可以将Gradle Wrapper升级到与当前AGP兼容的版本。

例如:

properties
distributionUrl=https://services.gradle.org/distributions/gradle-8.2-bin.zip

然后同步项目:

Bash
./gradlew --version

确认版本已经生效。

Windows:

bat
gradlew.bat --version

升级Gradle时,不建议只修改Wrapper版本而完全不考虑AGP版本。Gradle和AGP之间存在兼容关系,正确做法是根据项目现有AGP版本选择合适的Gradle版本。

八、如果项目较老,可以降低Java版本

并不是所有Android项目都应该直接升级到Java 17。

如果这是一个维护多年的老项目,并且:

Gradle版本较低
AGP版本较低
第三方插件较旧

贸然升级整个构建环境,可能引入更多问题。

这种情况下,可以考虑让项目回到旧Java版本。

例如项目原本基于Java 11:

JDK 11
Gradle旧版本
AGP旧版本

那么可以使用JDK 11构建,而不是强制使用JDK 17。

但是这里存在一个关键问题:

如果真正产生major version 61的依赖本身要求Java 17,那么降低项目JDK并不能解决根本问题。

这时应该寻找该依赖的较低版本,或者升级项目构建工具。

九、检查Gradle中的Java Toolchain配置

有些项目会显式指定Java版本。

例如:

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

或者:

gradle
kotlin {
    jvmToolchain(17)
}

Android项目中还可能看到:

gradle
compileOptions {
    sourceCompatibility JavaVersion.VERSION_17
    targetCompatibility JavaVersion.VERSION_17
}

Kotlin项目则可能存在:

gradle
kotlinOptions {
    jvmTarget = '17'
}

这些配置需要结合项目实际构建环境一起检查。

例如:

gradle
android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
}

如果项目已经决定使用Java 17,那么最好确保Android Studio、Gradle、AGP以及相关Kotlin插件都处于相互兼容的版本范围。

十、检查是不是第三方依赖导致的

有时候你的Android代码完全没有使用Java 17,但依然出现:

Unsupported class file major version 61

这种情况非常常见。

原因可能是某个第三方库升级后,发布的构件已经使用更高版本JDK编译。

例如:

项目原来的依赖 → Java 11
新版本依赖 → Java 17

升级依赖以后,旧项目就可能突然出现major version 61错误。

可以使用Gradle查看依赖关系:

Bash
./gradlew app:dependencies

如果是Windows:

bat
gradlew.bat app:dependencies

还可以针对具体配置查看依赖:

Bash
./gradlew app:dependencies --configuration debugRuntimeClasspath

通过依赖树寻找最近修改或者刚刚升级的库。

十一、检查Gradle插件依赖

除了普通Android依赖,还要特别检查Gradle插件。

例如:

gradle
classpath 'com.google.gms:google-services:xxx'

或者:

gradle
classpath 'com.google.firebase:firebase-crashlytics-gradle:xxx'

以及其他第三方Gradle插件。

这些插件本身会运行在Gradle JVM中。

如果某个插件的新版本使用Java 17编译,而项目仍然使用旧Gradle环境,就可能出现:

Unsupported class file major version 61

因此,如果错误是在Gradle初始化、配置阶段出现,而不是Java/Kotlin源码编译阶段出现,那么应该重点检查:

Gradle插件
构建脚本
Gradle版本
JDK版本

十二、清理Gradle缓存后重新构建

版本调整完成后,如果仍然出现相同错误,可以清理构建缓存。

首先执行:

Bash
./gradlew clean

Windows:

bat
gradlew.bat clean

然后重新构建:

Bash
./gradlew assembleDebug

如果怀疑Gradle缓存中的旧构件有问题,可以进一步检查用户目录下的Gradle缓存。

Linux/macOS通常位于:

~/.gradle/caches

Windows通常位于:

C:Users用户名.gradlecaches

删除缓存后重新构建,会重新下载依赖,因此执行前应确认网络和仓库配置正常。

十三、Android Studio缓存问题也需要排查

如果命令行执行Gradle正常,但Android Studio中仍然报:

Unsupported class file major version 61

可以考虑重新同步项目。

例如:

File
→ Sync Project with Gradle Files

必要时再执行:

File
→ Invalidate Caches / Restart

不过需要注意,Android Studio缓存通常不是 major version 61 的根本原因。

如果命令行同样失败,优先处理:

JDK
Gradle
AGP
依赖

而不是反复清理IDE缓存。

十四、Kotlin项目还要检查Kotlin版本

如果Android项目使用Kotlin,还需要检查Kotlin插件版本。

例如:

gradle
plugins {
    id 'org.jetbrains.kotlin.android' version 'xxx'
}

以及:

gradle
kotlinOptions {
    jvmTarget = '17'
}

Java和Kotlin的目标版本最好保持一致。

例如:

gradle
android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
}

kotlinOptions {
    jvmTarget = '17'
}

如果一个使用:

Java 17

另一个却使用:

JVM 1.8

虽然不一定直接导致major version 61,但容易形成额外的构建兼容问题。

十五、不要把compileSdk与Java版本混为一谈

很多开发者看到Android项目升级后出现构建错误,会误以为:

compileSdk 版本越高
=
Java版本越高

实际上这两个概念并不等价。

例如:

gradle
android {
    compileSdk 35
}

表示Android API编译级别,而:

JDK 17

表示Java构建环境。

它们分别解决不同的问题。

因此,遇到:

Unsupported class file major version 61

首先应该检查JDK、Gradle和AGP,而不是单纯修改:

gradle
compileSdk
targetSdk
minSdk

十六、推荐的排查顺序

为了避免反复修改配置,可以按照下面的顺序排查。

第一步:确认Java版本

Bash
java -version

第二步:确认Gradle实际使用的JDK

Bash
./gradlew --version

重点查看:

Gradle
JVM

第三步:确认AGP版本

检查:

build.gradle
settings.gradle
build.gradle.kts
settings.gradle.kts

找到Android Gradle Plugin版本。

第四步:确认Gradle Wrapper版本

检查:

gradle/wrapper/gradle-wrapper.properties

第五步:检查最近升级的依赖

尤其关注:

Gradle插件
Kotlin插件
AndroidX库
第三方SDK
构建工具

第六步:统一Java配置

检查:

Gradle JDK
JAVA_HOME
compileOptions
kotlinOptions
Java Toolchain

第七步:清理并重新构建

Bash
./gradlew clean
./gradlew assembleDebug

通过这样的顺序,通常可以比较快定位真正的问题来源。

十七、一个典型案例

假设旧Android项目环境如下:

JDK 11
Gradle 6.7
AGP 4.2

后来升级了某个Gradle插件,该插件使用Java 17编译。

于是构建时出现:

Unsupported class file major version 61

原因可以理解为:

新插件
    ↓
Java 17编译
    ↓
class major version 61
    ↓
旧Gradle构建环境
    ↓
无法读取Java 17字节码

解决方法通常有两个方向。

方案一:升级整个构建链

JDK升级
    ↓
Gradle升级
    ↓
AGP升级
    ↓
兼容其他插件和依赖

方案二:降低相关插件或依赖版本

Java 17插件
    ↓
切换到兼容旧JDK的版本
    ↓
继续使用旧项目构建环境

对于老项目而言,第二种方案往往风险更低。

十八、常见误区

误区一:只升级JDK

如果当前环境:

Gradle太旧

即使安装了Java 17,也不一定能够解决问题。

JDK、Gradle和AGP需要整体考虑。

误区二:只修改sourceCompatibility

例如:

gradle
sourceCompatibility JavaVersion.VERSION_17

这并不能让一个不支持Java 17 class文件的旧Gradle突然获得Java 17解析能力。

它只是编译配置的一部分。

误区三:随便升级所有依赖

看到错误后直接执行大量依赖升级,很容易把一个问题变成多个问题。

更合理的方式是:

定位引入Java 17字节码的组件
        ↓
确认当前构建链能力
        ↓
选择升级构建工具或降低组件版本

误区四:只看java -version

真正运行Gradle的是Gradle配置的JDK。

所以:

Bash
java -version

和:

Bash
./gradlew --version

都应该检查。

十九、如何快速判断应该升级还是降级

可以按照这个思路判断:

如果项目本身已经比较新:

新Android Studio
新AGP
新Gradle

但JDK比较旧,那么优先考虑:

升级JDK

如果项目比较老:

旧AGP
旧Gradle
旧插件

突然因为某个依赖升级出现:

major version 61

可以优先考虑:

降低该依赖版本

如果项目准备长期维护,并且依赖已经普遍要求Java 17,则可以考虑:

升级JDK
+
升级Gradle
+
升级AGP
+
同步调整Kotlin及第三方插件

不要为了修复一个错误而无计划地升级整个项目。

二十、最终解决思路

Unsupported class file major version 61 的核心并不是“Android代码写错了”,而是构建工具无法处理Java 17生成的class文件

看到:

Unsupported class file major version 61

首先记住:

major version 61 = Java 17

然后重点检查:

1. 当前JDK版本
2. Gradle实际使用的JDK
3. Gradle Wrapper版本
4. Android Gradle Plugin版本
5. Kotlin插件版本
6. 第三方Gradle插件
7. 最近升级的Android依赖
8. Java/Kotlin编译目标

如果新依赖或插件要求Java 17,就让构建链升级到能够支持Java 17的版本;如果只是老项目偶然引入了新版本组件,则可以优先回退到兼容版本。

只要按照“定位产生Java 17字节码的组件 → 检查JDK → 检查Gradle → 检查AGP → 检查依赖 → 清理缓存重新构建”的顺序处理,通常就能准确解决Android项目中的 Unsupported class file major version 61 错误。