纯Kotlin服务端项目配置ProGuard遇问题求助
纯Kotlin非Android项目ProGuard配置问题解决方案
一、baseCoordinates参数含义
这个变量就是用来定义混淆后输出Jar包的基础名称。比如你设置成my-kserver,最终生成的混淆Jar会是build/libs/my-kserver-minified.jar。直接替换成你的项目名称就行,比如项目叫kotlin-toolkit,就改成val baseCoordinates = "kotlin-toolkit"。
二、"所有类均缺失"警告的解决方法
这个问题基本是因为ProGuard规则太严、输入Jar配置不对,或者Java依赖模块没引全导致的,按下面步骤排查:
1. 补全ProGuard规则文件(proguard-rules.pro)
纯Kotlin项目必须保留Kotlin核心类、项目入口类,以及你不想被混淆/删除的类,添加以下基础规则:
# 保留Kotlin核心类与合成类,避免Kotlin特性失效 -keep class kotlin.** { *; } -keep class kotlin.Metadata { *; } -keepclassmembers class ** { @kotlin.Metadata <fields>; } # 保留项目主入口类,替换成你自己的主类全路径 -keep class com.example.yourproject.MainKt { *; } # 按需保留自定义类/接口,比如业务服务、仓储层 -keep class com.example.yourproject.service.** { *; } -keep interface com.example.yourproject.repository.** { *; } # 保留反射或静态调用的类成员 -keepclassmembers class * { @kotlin.jvm.JvmStatic <methods>; } # 保留枚举类 -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
2. 确认输入Jar的正确性
检查tasks.named<Jar>("jar")是否指向正确的Jar任务:
- 如果是普通单模块项目,默认
jar任务没问题,先执行./gradlew jar确认build/libs下生成了正常的Jar包; - 如果用了ShadowJar这类自定义打包任务,要改成对应的任务名,比如
injars(tasks.named<Jar>("shadowJar").flatMap { it.archiveFile })。
3. 补充Java 9+的依赖模块
如果用Java 9+,只引java.base.jmod可能不够,项目用到的IO、日志、网络等功能对应的模块也要加上:
libraryjars( mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), "${System.getProperty("java.home")}/jmods/java.base.jmod", "${System.getProperty("java.home")}/jmods/java.logging.jmod", "${System.getProperty("java.home")}/jmods/java.net.http.jmod" )
根据项目实际用到的Java模块添加,避免基础类缺失导致ProGuard误判。
4. 验证任务执行顺序
当前配置里tasks.build.get().finalizedBy(tasks.getByName("proguard"))是对的,但可以手动先跑./gradlew jar再跑./gradlew proguard,确认警告是否消失。
三、调整后的完整配置示例
tasks.register<ProGuardTask>("proguard") { configuration("proguard-rules.pro") // 确认输入Jar任务正确 injars(tasks.named<Jar>("jar").flatMap { it.archiveFile }) // Java版本适配,补充必要模块 if (System.getProperty("java.version").startsWith("1.")) { libraryjars("${System.getProperty("java.home")}/lib/rt.jar") } else { libraryjars( mapOf("jarfilter" to "!**.jar", "filter" to "!module-info.class"), "${System.getProperty("java.home")}/jmods/java.base.jmod", "${System.getProperty("java.home")}/jmods/java.logging.jmod" ) } verbose() val baseCoordinates = "my-kserver" // 替换为你的项目名称 outjars(layout.buildDirectory.file("libs/${baseCoordinates}-minified.jar")) } tasks.build.get().finalizedBy(tasks.getByName("proguard"))
内容的提问来源于stack exchange,提问作者Psijic
相关产品推荐
相关产品推荐

