多模块Android项目集成SonarQube时遭遇NoClassDefFoundError异常求解决方案
多模块Android项目集成SonarQube时遭遇NoClassDefFoundError异常求解决方案
我来帮你搞定这个问题!我之前在多模块Android项目集成SonarQube时也踩过几乎一模一样的坑,咱们一步步拆解解决:
先把你的问题核心点理清楚
你碰到的异常是典型的版本兼容性问题,先把异常信息明确列出来方便定位:
java.lang.NoClassDefFoundError: com/android/build/gradle/api/BaseVariant at org.sonarqube.gradle.SonarQubePlugin.lambda$getAndroidCompileTasks$16(SonarQubePlugin.java:179) Caused by: java.lang.ClassNotFoundException: com.android.build.gradle.api.BaseVariant at org.gradle.internal.classloader.VisitableURLClassLoader$InstrumentingVisitableURLClassLoader.findClass(VisitableURLClassLoader.java:186)
简单说就是:SonarQube插件要找的AGP(Android Gradle插件)内部类BaseVariant找不到了——这100%是SonarQube插件版本和你项目的AGP版本不兼容导致的,不同版本的AGP对内部API的包路径、访问权限做了调整,比如AGP 8.x甚至直接重构了Variant相关的核心API。
具体解决方案(结合你的配置来改)
步骤1:先确认你项目的AGP和Gradle版本
先打开项目根目录的build.gradle,找到你的AGP版本:
// 如果你用的是旧的buildscript写法 buildscript { dependencies { classpath "com.android.tools.build:gradle:7.4.2" // 这行里的版本就是AGP版本 } } // 如果你用的是Gradle推荐的plugins DSL写法 plugins { id 'com.android.application' version '8.1.0' apply false // 这里的版本就是AGP版本 }
再看gradle/wrapper/gradle-wrapper.properties里的Gradle版本:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip // 这是Gradle版本
步骤2:给SonarQube插件配个兼容的版本
我整理了目前最常用的AGP和SonarQube插件的兼容组合,你对应着改就行:
| AGP版本范围 | 推荐SonarQube插件版本 |
|---|---|
| 7.0.x - 7.3.x | 4.4.1.3373 |
| 7.4.x - 8.0.x | 5.0.0.4638 及以上 |
| 8.1.x 及以上 | 5.2.0.5212 及以上(最新稳定版) |
比如你现在用的是5.1.0.4882,如果你的AGP是8.1+,就升级到5.2.0.5212;如果你的AGP是7.3及以下,就降级到4.4.1.3373。修改你的sonar.gradle里的依赖:
buildscript { repositories { google() mavenCentral() maven { url "https://plugins.gradle.org/m2/" } } dependencies { // 替换成对应兼容的版本号 classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:5.2.0.5212" } }
步骤3:优化你的SonarQube配置(省得以后再踩坑)
看你的配置里有不少冗余项,新版本的SonarQube插件已经能自动识别Android项目的结构了,我帮你简化下:
// 你的sonar.gradle可以改成这样 buildscript { repositories { google() mavenCentral() maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:5.2.0.5212" } } apply plugin: org.sonarqube.gradle.SonarQubePlugin sonarqube { properties { property "sonar.sourceEncoding", "UTF-8" property "sonar.projectKey", "********" property "sonar.projectName", "*******" // 以下3行可以删掉!插件会自动识别Android项目的源码、测试目录和语言 // property "sonar.sources", "src/main/java" // property "sonar.tests", "src/test/java" // property "sonar.language", "kotlin" property("sonar.branch.name", "test") property("sonar.host.url", "************") property("sonar.token", "*********") } }
另外,多模块项目其实不用每个模块都apply from,可以在根项目的build.gradle里全局配置,省得重复操作:
// 根build.gradle plugins { id "org.sonarqube" version "5.2.0.5212" apply false } subprojects { apply plugin: "org.sonarqube" // 这里放所有模块共享的配置,比如host、token、编码 sonarqube { properties { property "sonar.sourceEncoding", "UTF-8" property("sonar.host.url", "************") property("sonar.token", "*********") } } } // 然后在需要单独设置项目Key/Name的模块(比如app模块)里补充: // app/build.gradle sonarqube { properties { property "sonar.projectKey", "********" property "sonar.projectName", "*******" property("sonar.branch.name", "test") } }
步骤4:清理缓存重新扫描
改完配置后,一定要先清缓存再跑SonarQube,不然可能还有旧缓存的问题:
./gradlew clean sonarqube
额外提醒
- 如果你用的是AGP 8.0+,Gradle版本必须至少是7.5+,不然还会出其他兼容性问题
- 尽量用Gradle推荐的
plugins DSL方式引入插件,别用buildscript,兼容性会好很多
内容来源于stack exchange
相关产品推荐
相关产品推荐

