java代码混淆打包可执行jar包,并添加第三方依赖
先看疗效
- 执行
mvn clean package
maven命令即可生成两个插件对应的*jar-with-dependencies.jar
和 代码混淆*jar-with-dependencies-pg.jar
包. - 生成的
*-jar-with-dependencies-pg.jar
包指定了main方法,可通过java -jar 执行.
Maven 配置
pom.xml maven-assembly-plugin
打包插件和proguard-maven-plugin
代码混淆插件具体配置如下:
<build>
<plugins>
<plugin><!--将所有的依赖达到一个jar包里-->
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<!--这里要替换成jar包main方法所在类-->
<mainClass>pub.qingyun.AppMain</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- 指定在打包节点执行jar包合并操作 -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin><!--用混淆插件混淆代码-->
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<attach>true</attach>
<attachArtifactClassifier>pg</attachArtifactClassifier>
<!-- attach 的作用是在 install 与 deploy 时将生成的 pg 文件也安装与部署 -->
<options> <!-- 详细配置方式参考 ProGuard 官方文档 -->
<option>-ignorewarnings</option> <!--忽略所有告警-->
<option>-dontshrink</option> <!--不做 shrink -->
<option>-dontoptimize</option> <!--不做 optimize -->
<option>-dontskipnonpubliclibraryclasses</option>
<option>-dontskipnonpubliclibraryclassmembers</option>
<option>-dontnote</option>
<option>-keepattributes Signature</option>
<!--保持源码名与行号(异常时有明确的栈信息),注解(默认会过滤掉所有注解,会影响框架的注解)-->
<option>-keepattributes Exceptions,InnerClasses,*Annotation*,Signature,LineNumberTable</option>
<!-- 保持bean类名与属性名不变不变 -->
<option>-keep class pub.qingyun.model.**</option>
<option>-keepclassmembers class pub.qingyun.model.** { *;}</option>
<!-- 保持对外的接口性质类对外的类名与方法名不变 -->
<option>-keep class pub.qingyun.core.**</option>
<option>-keepclassmembers class pub.qingyun.core.** { *;}</option>
<option>-keep class pub.qingyun.exception.**</option>
<option>-keepclassmembers class pub.qingyun.exception.** { *;}</option>
<!--以下配置第三方包不参与混淆-->
<option>-keepclassmembers class com.hopechart.dcroute.** { *;}</option>
<option>-dontwarn com.hopechart.dcroute.**</option>
<option>-keep class com.hopechart.dcroute.** {*;}</option>
<option>-keepclassmembers class com.hopechart.cloud.** { *;}</option>
<option>-dontwarn com.hopechart.cloud.**</option>
<option>-keep class com.hopechart.cloud.** {*;}</option>
<option>-keepclassmembers class com.hopechart.jcc.** { *;}</option>
<option>-dontwarn com.hopechart.jcc.**</option>
<option>-keep class com.hopechart.jcc.** {*;}</option>
<option>-keepclassmembers class oracle.** { *;}</option>
<option>-dontwarn oracle.**</option>
<option>-keep class oracle.**</option>
<option>-keepclassmembers class org.aopalliance.** { *;}</option>
<option>-dontwarn org.aopalliance.**</option>
<option>-keep class org.aopalliance.**</option>
<option>-keepclassmembers class org.apache.commons.** { *;}</option>
<option>-dontwarn org.apache.commons.**</option>
<option>-keep class org.apache.commons.**</option>
<option>-keepclassmembers class org.apache.log4j.** { *;}</option>
<option>-dontwarn org.apache.log4j.**</option>
<option>-keep class org.apache.log4j.**</option>
<option>-keepclassmembers class org.slf4j.** { *;}</option>
<option>-dontwarn org.slf4j.**</option>
<option>-keep class org.slf4j.**</option>
<option>-keepclassmembers class org.springframework.** { *;}</option>
<option>-dontwarn org.springframework.**</option>
<option>-keep class org.springframework.**</option>
<!--!!!!!!!!!非常重要,AppMain不能代码混淆,否则将无法正常启动Main方法.如生成的jar包仅做其它项目依赖使用,可不配置-->
<option>-keep public class pub.qingyun.AppMain {
public static void main(java.lang.String[]);
}
</option>
</options>
<!--指定混淆的jar包,我这里是将上一步输出的jar包进行混淆-->
<injar>code-confusion-demo-1.0-SNAPSHOT-jar-with-dependencies.jar</injar>
<!--指定输出的jar包名-->
<outjar>${project.build.finalName}-pg.jar</outjar>
<obfuscate>true</obfuscate>
<!-- 添加依赖,必须添加,不然会报一些莫名错误-->
<libs>
<!--<lib>${java.home}/lib/rt.jar</lib>-->
<!--<lib>${java.home}/lib/jce.jar</lib>-->
<!--需要配置,由于我使用的openjdk,需要手动配置下路径-->
<lib>C:/Program Files/Java/corretto-1.8.0_332/jre/lib/rt.jar</lib>
<lib>C:/Program Files/Java/corretto-1.8.0_332/jre/lib/jce.jar</lib>
<!--实测,如下两项如不做配置-->
<!-- <lib>${project.basedir}/lib/apache-axiom-api-1.2.7.jar</lib>
<lib>${project.basedir}/lib//axis2-kernel-1.7.1.jar</lib>-->
</libs>
</configuration>
</plugin>
</plugins>
</build>
proguard-maven-plugin
代码混淆插件也可通过配置文件配置.
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
...
<proguardInclude>${project.basedir}/proguard.cfg</proguardInclude>
...
</configuration>
</plugin>
proguard.cfg配置文件
# 指定Java的版本
-target 11
# proguard会对代码进行优化压缩,他会删除从未使用的类或者类成员变量等
-dontshrink
# 是否关闭字节码级别的优化,如果不开启则设置如下配置
-dontoptimize
# 混淆时不生成大小写混合的类名,默认是可以大小写混合
-dontusemixedcaseclassnames
# 对于类成员的命名的混淆采取唯一策略
-useuniqueclassmembernames
# 混淆时不生成大小写混合的类名,默认是可以大小写混合
-dontusemixedcaseclassnames
# 混淆类名之后,对使用Class.forName('className')之类的地方进行相应替代
-adaptclassstrings
# 对异常、注解信息予以保留
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
# 此选项将保存接口中的所有原始名称(不混淆)-->
-keepnames interface ** { *; }
# 此选项将保存所有软件包中的所有原始接口文件(不进行混淆)
#-keep interface * extends * { *; }
# 保留参数名,因为控制器,或者Mybatis等接口的参数如果混淆会导致无法接受参数,xml文件找不到参数
-keepparameternames
# 保留枚举成员及方法
-keepclassmembers enum * { *; }
# 不混淆所有类,保存原始定义的注释-
#-keepclassmembers class * {
# @org.springframework.context.annotation.Bean *;
# @org.springframework.beans.factory.annotation.Autowired *;
# @org.springframework.beans.factory.annotation.Value *;
# @org.springframework.stereotype.Service *;
# @org.springframework.stereotype.Component *;
# }
# 忽略warn消息
-ignorewarnings
# 忽略note消息
-dontnote
# 打印配置信息
-printconfiguration
-keep public class pub.qingyun.AppMain {
public static void main(java.lang.String[]);
}