You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:34:59