proguard 混淆 使用JDK17 的 springboot4 + JPA

可运行配置

pom.xml 的配置

重点是proguard插件需要在spring-boot打包插件之前。

<skip>${proguard.skip}</skip> 这里可选,配置一个变量方便控制是否混淆。

<proguardInclude>${project.basedir}/proguard.cfg</proguardInclude> 这里配置了具体的proguard 文件,后面给出具体内容。

xml 复制代码
<plugins>
    <plugin>
        <groupId>com.github.wvengen</groupId>
        <artifactId>proguard-maven-plugin</artifactId>
        <version>2.7.0</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>proguard</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <skip>${proguard.skip}</skip>
            <injar>${project.build.finalName}.jar</injar>
            <outjar>${project.build.finalName}.jar</outjar>
            <obfuscate>true</obfuscate>
            <proguardInclude>${project.basedir}/proguard.cfg</proguardInclude>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <excludes>
                <exclude>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                </exclude>
            </excludes>
        </configuration>
    </plugin>
</plugins>

proguard.cfg 配置文件

和pom.xml同目录下,需要一个proguard.cfg配置文件,内容如下。

复制代码
# 忽略警告和提示
-dontwarn
-dontnote

# 不做优化(Java SE 不需要)
-dontoptimize

# 保留调试信息和注解(Spring 依赖注解做组件扫描和自动装配)
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,Record


# ============================================
# 保留 Spring 托管的 Bean(类名/方法名不能混淆)
# ============================================
-keep @org.springframework.stereotype.Component class com.company.project.** { *; }
-keep @org.springframework.core.annotation.Order class com.company.project.** { *; }
-keep @org.springframework.stereotype.Service class com.company.project.** { *; }
-keep @org.springframework.stereotype.Repository class com.company.project.** { *; }
-keep @org.springframework.context.annotation.Configuration class com.company.project.** { *; }
-keep @org.springframework.web.bind.annotation.RestController class com.company.project.** { *; }
-keep @org.springframework.web.bind.annotation.Controller class com.company.project.** { *; }
-keep @org.springframework.web.bind.annotation.RestControllerAdvice class com.company.project.** { *; }
-keep @org.springframework.web.bind.annotation.ControllerAdvice class com.company.project.** { *; }


# ============================================
# 保留 JPA Entity(Hibernate 依赖字段名和 getter/setter 映射)
# ============================================
-keep @jakarta.persistence.Entity class com.company.project.** { *; }
-keep @jakarta.persistence.Table class com.company.project.** { *; }


-keep class com.company.project.dto.** { *; }
-keep interface com.company.project.dao.repository.** { *; }

# ============================================
# 保留所有 Spring Bean 的公开构造器(依赖注入需要)
# ============================================
-keepclassmembers class com.company.project.** {
    public <init>(...);
}

# ============================================
# 保留枚举
# ============================================
-keepclassmembers enum com.company.project.** {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# ============================================
# 保留主启动类
# ============================================
-keep public class com.company.project.YourApplication {
    public static void main(java.lang.String[]);
}

踩的坑

运行时stackmap验证失败,虽然可以用 -noverify 参数跳过。

解决办法是:移除配置文件中的 -dontpreverify 选项

为什么如此配置

让AI进行了整理

分类 核心标识 / 注解 处理规则 核心原因
SpringBoot 启动类 @SpringBootApplication、main 方法 保留类、main 方法 程序入口,Spring 反射加载启动类,混淆后无法找到入口
控制器层 @RestController/@Controller、@RequestMapping 等请求注解 保留类、公共方法、参数 SpringMVC 反射解析请求映射,混淆后请求 404
Service 业务层 @Service、@Autowired 保留类、方法、注入字段 Spring 依赖注入基于反射,混淆后 Bean 无法注入
JPA 持久层 @Repository、JpaRepository/CrudRepository、@Query 保留接口、所有方法 JPA 动态代理生成实现类,方法名是查询规则,混淆后代理 / 查询失效
JPA 实体类 @Entity/@Table/@Id/@Column(JPA 映射注解) 保留类、所有字段、getter/setter JPA 反射映射实体与数据库,混淆后 ORM 映射失败、数据库操作报错
Spring 配置类 @Configuration/@Bean/@Component 保留类、@Bean 方法 Spring 反射加载配置类,混淆后配置失效、Bean 无法创建
数据传输对象 DTO/VO/BO、@JsonProperty(Jackson 序列化) 保留类、所有字段 前后端数据序列化 / 反序列化基于反射,混淆后字段名不匹配
枚举 / 常量类 @Enumerated(JPA 枚举)、static final 常量 保留类、所有枚举值 / 常量 JPA 映射枚举、系统常量依赖固定值,混淆后数据错乱
自定义 AOP 切面 @Aspect/@Pointcut/@Around 保留切面类、切点方法 Spring AOP 基于动态代理,混淆后切点无法匹配
相关推荐
Pniubi1 小时前
HashMap的扩容和树化边界
java·开发语言
Mikko71 小时前
用 Java 复刻了高中时在塞班上玩的「熔岩矿车」:纯 Swing、零依赖、没有一张图片,一个 jar 双击就能玩
java·游戏开发·swing
知了学历孙老师1 小时前
小自考的校考和统考,出题方和难度差在哪
java·大数据·前端
Java爱好狂.2 小时前
Java初学者如何一周速通SpringBoot!
java·spring boot·后端·spring·高并发·架构师·java面试
秋饼2 小时前
LLM API密钥动态轮换实战:Spring Vault + Spring AI + 多Provider路由
java·ai·技术分享·后端开发
福兮说4 小时前
JSON 格式正确,数据就可靠吗?我用一份自编配置检查类型与空值
java·前端·json
紧跟先前的步伐5 小时前
Go AI Agent 实战 03|Token、上下文窗口与模型调用成本
java·人工智能·golang
const_qiu6 小时前
第四章 00:开篇 —— 从「会聊天」到「记得住、会干活、能协作」
java·开发语言·人工智能·python
Wang's Blog6 小时前
Java 项目实战: 交友项目 - 个人资料管理的更新接口实现与坑
java·开发语言·交友
Promising_GEO6 小时前
GEE实战02期:从卫星波段开始:利用 Sentinel-2 自己计算 NDVI
java·sentinel·遥感·空间分析