非Android Kotlin应用Gradle配置ProGuard遇大量未解析引用警告
解决ProGuard未解析引用警告的方案
核心问题分析
你的ProGuard任务配置存在几个关键问题,直接导致了大量未解析引用警告:
- 错误将
distZip(包含所有依赖的完整应用包)作为输入jar,ProGuard会尝试处理第三方依赖代码,而这些依赖的内部引用往往无法被完整解析 - 依赖类路径使用
compileClasspath,缺失了runtimeOnly类型的依赖 - Kotlin相关的ProGuard规则不完整,缺少对Kotlin标准库的必要保留配置
分步修复
1. 修正输入范围:仅处理自身业务代码
不要用distZip作为ProGuard的输入,而是直接使用项目编译后的类文件或打包的jar(jar任务产物),确保ProGuard只处理你的代码,第三方依赖以libraryjars形式引入:
tasks.register<ProGuardTask>("proguard") { configuration("proguard.pro") verbose() printconfiguration("$buildDir/proguard/configuration.txt") printseeds("$buildDir/proguard/seeds.txt") // 替换injars,仅处理自身编译的jar injars(tasks.jar) outjars("$buildDir/proguard/minified-app.jar") // JDK模块配置 val javaHome = System.getProperty("java.home") libraryjars( mapOf( "jarfilter" to "!**.jar", "filter" to "!module-info.class", ), "$javaHome/jmods/java.base.jmod", // 根据应用实际依赖添加其他JDK模块,比如java.logging.jmod、java.io.jmod等 ) // 改用runtimeClasspath,包含所有运行时依赖 libraryjars(sourceSets["main"].runtimeClasspath) }
2. 完善Kotlin相关ProGuard规则
在proguard.pro中补充Kotlin标准库的必要规则,避免内部类引用警告:
-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod # Kotlin核心元数据与标准库保留 -keep class kotlin.Metadata { *; } -keep class kotlin.** { *; } -dontwarn kotlin.** # 保留Kotlin when表达式映射类 -keepclassmembers class **$WhenMappings { <fields>; } # 保留Kotlin反射类(如果应用用到反射) -keep class kotlin.reflect.** { *; } # 应用入口点保留 -keep class com.foo.bar.MainKt { *; } # 已有忽略规则 -dontwarn java.awt.** -dontwarn javax.swing.** -dontwarn java.lang.instrument.ClassFileTransformer -dontwarn sun.misc.SignalHandler -dontwarn java.lang.instrument.Instrumentation -dontwarn sun.misc.Signal
3. 针对性处理第三方依赖警告
如果仍有特定第三方依赖的未解析警告,且确认不影响运行,可以添加对应的-dontwarn规则。比如使用kotlinx.coroutines时,补充:
-dontwarn kotlinx.coroutines.**
混淆产物集成到原有发布流程
修复后,可将混淆后的jar替换到installDist或distZip的产物中,保持原有发布流程不变:
tasks.named("installDist") { dependsOn("proguard") doLast { val appJarName = "${project.name}-${project.version}.jar" val originalJar = file("$buildDir/install/${project.name}/lib/$appJarName") val minifiedJar = file("$buildDir/proguard/minified-app.jar") originalJar.delete() minifiedJar.copyTo(originalJar) } } // 同理处理distZip任务 tasks.named("distZip") { dependsOn("proguard") // 可以解压zip、替换jar、重新打包,或者修改distZip的输入源 }
内容的提问来源于stack exchange,提问作者Maddin
相关产品推荐
相关产品推荐

