Java多项目同时执行Proguard混淆并保留接口关联定义的实现方案
需求可行性结论
你描述的全量混淆需求完全可以实现,不需要保留被引用的应用代码不混淆,两种你设想的方案都有成熟的实现方式。
方案1:顶层POM统一全量混淆(更推荐)
这是适配你现有多模块Maven结构成本最低的方案,操作步骤如下:
- 调整子模块构建顺序:先完成所有应用、插件子模块的编译打包,输出未混淆的class/jar文件
- 在顶层POM中配置
proguard-maven-plugin,将执行阶段绑定到所有子模块打包完成后的verify或install阶段,一次性传入所有应用、插件的类文件与依赖执行统一混淆 - Proguard规则添加以下配置适配ServiceLoader场景,即可实现全量混淆(包括接口、入参类、实现类):
# 自动同步META-INF/services配置文件中的类名为混淆后名称 -adaptresourcefilenames META-INF/services/** -adaptresourcefilecontents META-INF/services/** # 仅保留插件实现类的无参构造方法供ServiceLoader反射实例化 -keepclassmembers class * implements com.project.app.RunPlugin { <init>(); }
统一混淆模式下Proguard会自动同步所有类、方法、参数的混淆命名,不会出现接口与实现类签名不匹配的问题。
方案2:应用混淆映射复用方案
如果你需要分开构建应用与插件,可使用该方案,操作步骤如下:
- 应用模块先执行混淆,开启以下配置:
- 输出混淆后的应用jar包
- 添加
-printmapping app.map配置导出混淆映射表
- 插件模块编译阶段,直接依赖第一步输出的混淆后应用jar包,而非未混淆的应用模块
- 插件模块执行Proguard混淆时,添加
-applymapping app.map配置,直接复用应用的混淆命名规则,Proguard会自动沿用已有的类、方法映射关系,保证插件实现类的方法签名与应用混淆后的接口签名完全一致。
报错原因说明
你当前遇到的AbstractMethodError是因为插件编译时依赖的是未混淆的应用接口,方法入参为原始的AppClass1、AppClass2类,与应用混淆后的com.project.app.o、com.project.app.b类签名不匹配导致,采用上述任意一种方案即可解决该问题。
内容的提问来源于stack exchange,提问作者bias
相关产品推荐
相关产品推荐

