Gradle7.x+Android本地Maven依赖嵌套引发NoClassDefFoundError问题
本地Maven依赖传递缺失导致NoClassDefFoundError问题解决
环境
- Gradle: 7.1.3
- Kotlin: 1.6.10
依赖场景
- 依赖链:
localMavenFirstLib(.aar) →localMavenSecondLib(.aar) →localMavenThirdLibTest(Android应用) - 操作流程:将LocalMavenFirst项目的
localMavenFirstLib作为本地Maven依赖引入LocalMavenSecond的localMavenSecondLib,再将localMavenSecondLib作为本地Maven依赖引入LocalMavenThird的应用模块。
问题现象
localMavenSecondLib中调用了localMavenFirstLib的Kotlin代码,应用调用localMavenSecondLib代码时崩溃,抛出NoClassDefFoundError,无法找到localMavenFirstLib中的类。
已尝试方案
- 切换Gradle的
implementation和api依赖配置,无效果; - 直接在应用模块添加
localMavenFirstLib依赖不可行(该库为第三方提供,无法手动引入)。
需求
无需手动添加第三方依赖,通过配置实现依赖自动传递,比如将依赖库正确纳入本地Maven仓库的方案。
错误栈信息
java.lang.NoClassDefFoundError: Failed resolution of: Lvinit/localMavenFirstLib/LocalMavenFirstLibInfo; at vinit.localMavenSecondLib.LocalMavenSecondLibInfo$Companion.getLocalMavenFirstLibInfoIntoLocalMavenSecondLibInfo(LocalMavenSecondLibInfo.kt:24) at vinit.localMavenThirdLibTest.LocalMavenThirdLibTestActivity.onCreate(LocalMavenThirdLibTestActivity.kt:17) at android.app.Activity.performCreate(Activity.java:8341) at android.app.Activity.performCreate(Activity.java:8320) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1417) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3622) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3778) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:138) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2303) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7884) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) Caused by: java.lang.ClassNotFoundException: Didn't find class "vinit.localMavenFirstLib.LocalMavenFirstLibInfo" on path: DexPathList[[zip file "/data/app/~~KXIedRpTwdDHSm6h915Y0w==/vinit.localMavenThirdLibTest-RPONyniXEE5kgyC8nthweQ==/base.apk"],nativeLibraryDirectories=[/data/app/~~KXIedRpTwdDHSm6h915Y0w==/vinit.localMavenThirdLibTest-RPONyniXEE5kgyC8nthweQ==/lib/arm64, /system/lib64, /system_ext/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) ... 17 more
解决方案
核心问题
localMavenSecondLib发布到本地Maven时,未将依赖的localMavenFirstLib信息写入POM文件,导致下游应用无法自动拉取传递依赖。
具体步骤
配置
localMavenSecondLib的发布脚本:
在localMavenSecondLib的build.gradle(或build.gradle.kts)中,确保发布任务生成包含依赖信息的POM文件:// Groovy版本 publishing { publications { maven(MavenPublication) { from components.release pom.withXml { def dependenciesNode = asNode().appendNode('dependencies') // 处理api依赖(编译期传递) configurations.api.allDependencies.each { dep -> def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', dep.group) dependencyNode.appendNode('artifactId', dep.name) dependencyNode.appendNode('version', dep.version) dependencyNode.appendNode('scope', 'compile') } // 处理implementation依赖(运行期传递) configurations.implementation.allDependencies.each { dep -> def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', dep.group) dependencyNode.appendNode('artifactId', dep.name) dependencyNode.appendNode('version', dep.version) dependencyNode.appendNode('scope', 'runtime') } } } } repositories { mavenLocal() } }Kotlin DSL版本:
// Kotlin DSL版本 publishing { publications { create<MavenPublication>("maven") { from(components["release"]) pom.withXml { val dependenciesNode = asNode().appendNode("dependencies") configurations.api.get().allDependencies.forEach { dep -> val dependencyNode = dependenciesNode.appendNode("dependency") dependencyNode.appendNode("groupId", dep.group) dependencyNode.appendNode("artifactId", dep.name) dependencyNode.appendNode("version", dep.version) dependencyNode.appendNode("scope", "compile") } configurations.implementation.get().allDependencies.forEach { dep -> val dependencyNode = dependenciesNode.appendNode("dependency") dependencyNode.appendNode("groupId", dep.group) dependencyNode.appendNode("artifactId", dep.name) dependencyNode.appendNode("version", dep.version) dependencyNode.appendNode("scope", "runtime") } } } } repositories { mavenLocal() } }使用
api引入localMavenFirstLib:
在localMavenSecondLib的依赖配置中,必须用api引入localMavenFirstLib,确保依赖信息被标记为需要传递:// Groovy api 'vinit.localMavenFirstLib:localMavenFirstLib:1.0.0'// Kotlin DSL api("vinit.localMavenFirstLib:localMavenFirstLib:1.0.0")重新发布并刷新依赖:
- 执行
localMavenFirstLib的publishToMavenLocal任务; - 执行
localMavenSecondLib的publishToMavenLocal任务; - 刷新
localMavenThirdLibTest的Gradle依赖。
- 执行
验证
重新运行应用,localMavenFirstLib的类会被自动纳入应用Dex文件,不再出现NoClassDefFoundError。
内容的提问来源于stack exchange,提问作者Vinit kr28
相关产品推荐
相关产品推荐

