一,混淆文件一般设置
#输出log
-verbose
#略过warning,不输出warning(有warning时无法继续)
-ignorewarnings
#不输出warning,这里可以限定某些类不要warning
-dontwarn
#不校验.校验可以提高java虚拟机的加载效率(java6)
-dontpreverify
#不混淆
#-dontobfuscate
#需要混淆的目录
#-obfuscationdictionary
#统一混淆.避免情况:两个有同样签名的接口. 一个类实现了上述的两个接口.如果两个接口签名混淆之后不同,那么是有问题的.所以一开始就混淆为相同的
-useuniqueclassmembernames
#指定在混淆时应用主动重载。即一个类zhongyingg不同签名的方法. 可以混淆为同一个名称(只要签名不一样)
-overloadaggressively
#不混用大小写(即把大写和小写字母当成同一个), 在一些不分辨大小写的系统打开类是有用的
-dontusemixedcaseclassnames
#将所有重命名的包移动到指定包, 无参数或空串则移动到根包,会使混淆更加难以理解. 类似的还有 -repackageclasses(针对class)
#-flattenpackagehierarchy [package_name]
#########优化
#不优化
#-dontoptimize
#优化等级
#-optimizationpasses 3
#优化时允许访问并修改有修饰符的类和类的成员,(可配合repackageclasses使用). (作为lib的不应该使用)
#-allowaccessmodification
#合并接口
#-mergeinterfacesaggressively
#############压缩
#不压缩
-dontshrink
##########输入输出#######
#目标版本1.0, 1.1, 1.2, 1.3, 1.4, 1.5 (or just 5), 1.6 (or just 6), or 1.7 (or just 7)
-target 1.7
#指定lib,在maven中一般只需要${java.home}/lib/rt.jar
#-libraryjars class_path
#指定输出jar
#-outjars class_path
#指定输入jar
-injars class_path
#指定基础路径
#-basedirectory directoryname
#指定在读取库jar时跳过非公共类,以加快处理速度并减少ProGuard的内存使用。某些情况可能出错,因此不使用
#-skipnonpubliclibraryclasses
#指定不忽略非公共图书馆类。默认配置
#-dontskipnonpubliclibraryclasses
#指定不忽略包可见库类成员(字段和方法)。
-dontskipnonpubliclibraryclassmembers
二, keep相关
通配符和关键字
- 类通配符
? # 表示一个字符
* # 多个字符, 如. pac1.*Test* 则 pac1.MyTest12 符合 , pac2.* 则表示包下pac2的类都符合,但不包括子包
** # 通配多个字符和路径. 如 **.Test 则表示所有包的Test类, pac3.** 则表示pac3的类和子包下的类.
- 字段和方法通配符
? #单个字符
* #多个字符
- 类型通配符
% # 不包含void的基本类型.void直接用void表示即可.
? #单个字符
* #多个字符,不包含类路径. (不包括基础类型)
** #多个字符,包括类路径. (不包括基础类型),即用这个可以表示所有非基础类型的值类型
*** # 通配所有类型
... # 所有数量所有类型参数.
- 否定和与
! #表示否定
, #可以表示与的含义,如 !foobar,*bar 表示以bar结尾但是除了foobar. foo,*bar 表示匹配foo和bar结尾的(空)
- 描述通配符
<init> # 通配所有构造函数
<fields> # 通配所有字段
<methods> # 通配所有方法
* # 字段或方法.(与上面三个处于同一级时)
- 其他描述符基本上和我们看到的意义一样, 简单挑几个解释一下
extends 和 implements # 目前是等价的.注意,这个限定不包含自身,如果需要自身,则增加一条keep即可.
class # 所有class和interface
interface # 限制为interface . 可以和否定 ! 一起使用
enum # 枚举. 可以和否定 ! 一起使用
- 完整的类和类型,方法
[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
[extends|implements [@annotationtype] classname]
[{
[@annotationtype] [[!]public|private|protected|static|volatile|transient ...] <fields> |
(fieldtype fieldname);
[@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> |
<init>(argumenttype,...) |
classname(argumenttype,...) |
(returntype methodname(argumenttype,...));
[@annotationtype] [[!]public|private|protected|static ... ] *;
...
}]
类和类型,方法keep说明
- 对类和成员都生效的
-keep
和keepnames
- 只对成员生效的
-keepclassmembers
和-keepclassmembernames
- 对类和成员生效,如果类成员存在(前提).
-keepclasseswithmembers
和-keepclasseswithmembernames
其他keep
-keeppackagenames [package_filter]
: 指定不混淆的包名, 可用通配符? * ** !
-keepattributes [attribute_filter] :
指定要保留的属性(方法类型和参数, 注释也属于属性), 例如Exception, 可以用多个或",
"分割, 一般为如下:
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
-keepparameternames
: 保留方法参数名和类型. 相当于-keepattributes LocalVariableTable,LocalVariableTypeTable
-keepdirectories [directory_filter]
:指定要保存在输出jar(或war、ear或目录)中的目录。如果没有指定, 则保留全部目录- p.s
-adaptclassstrings [class_filter]
-adaptxxxxxxx
有点和-keepXXX
相反的意思. 过滤掉keep中的特殊.
三,maven中使用
- 常用配置说明
<!-- ProGuard混淆插件-->
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<!-- 混淆时刻,这里是打包的时候混淆,还可以选择compile,process-class,取决于injar配置-->
<phase>package</phase>
<goals>
<!-- 使用插件的混淆功能-->
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 是否另外创建构件,默认为false,true则在target目录产生 同名_small.jar文件,后缀取决于另一配置-->
<attach>false</attach>
<!-- 另外产生的构件 后缀名,attach为true时才有用, 不指定时为small-->
<attachArtifactClassifier>proguard</attachArtifactClassifier>
<!-- 是否混淆,默认为true-->
<obfuscate>true</obfuscate>
<!-- 混淆配置文件,可选,不配置的话只需要在configuration下配置相关的配置即可-->
<proguardInclude>${basedir}/proguard.conf</proguardInclude>
<!-- 可放 proguard的配置 -->
<!-- <options></options> -->
<!-- 依赖,按需修改,一般一个JRE的Runtime包就行了 -->
<libs>
<lib>${java.home}/lib/rt.jar</lib>
</libs>
<!-- 指定要处理的jar|war|zip包,默认${project.build.finalName}.jar
<!-- 即,该插件默认是在package产生原始jar包后,对输出jar包进行处理的. 这里也可以指定为classes--对产生原始jar的class输入进行处理,但是这样子要生效,则必须修改插件作用的生命周期,将package改为 compile 或 process-classes -->
<injar>${project.build.finalName}.jar</injar>
<!-- 指定多生成jar包名称(原始名称的jar还是混淆的),在attach为true时不生效(attach本身就会多产生jar包)-->
<!-- <outjar>${project.build.finalName}-proguard.jar</outjar> -->
<!-- 输出目录,默认即为${project.build.directory}-->
<!-- <outputDirectory>${project.build.directory}</outputDirectory> -->
</configuration>
</plugin>
- 简单配置如下, 该配置会使生成的 jar已经混淆, 同时在 target下产生一个 同名_proguard_base.jar , 这个文件为未混淆前的jar.
<build>
<plugins>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals><goal>proguard</goal></goals>
</execution>
</executions>
<configuration>
<proguardInclude>${basedir}/proguard.conf</proguardInclude>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
</libs>
</configuration>
</plugin>
</plugins>
</build>
- 详细配置内容可参考.proguard的maven配置
四,例子
- 混淆文件
-target 1.7
-dontshrink
-dontoptimize
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-useuniqueclassmembernames
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
-verbose
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
#-repackageclasses ''
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# servlet和filter或者其他配置在bean上需要保留类名的
-keepnames class * implements javax.servlet.Filter
-keep public class * implements javax.servlet.Servlet
-keepnames class * extends org.springframework.web.servlet.handler.HandlerInterceptorAdapter
-keepnames class com.jt.base.web.servlet.JTFreeMarkerView
-keepnames class com.jt.crm.common.helper.FreeMarkerStaticExtImpl
-keepnames class net.bull.javamelody.SpringDataSourceFactoryBean
# 保留事务和缓存切面的包路径
-keeppackagenames com.jt.*.*.domain.*
-keeppackagenames **.service.*
-keeppackagenames **.repository.*
# 拦截器不要修改其公共方法
-keep public class * extends org.springframework.web.servlet.handler.HandlerInterceptorAdapter{
public *;
}
# 事务类read事务不改变方法名
-keepclassmembernames class com.jt.*.*.domain.*{
*** get*(***);
*** is*(***);
*** find*(***);
*** query*(***);
}
# 事务类read事务不改变方法名
-keepclassmembernames class com.jt.*.*.service.*{
*** get*(***);
*** is*(***);
*** find*(***);
*** query*(***);
}
# filter不修改其重写的方法
-keepclassmembers class * implements javax.servlet.Filter {
public void init(javax.servlet.FilterConfig);
public void doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,javax.servlet.FilterChain);
public void destroy();
}
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
!static !transient <fields>;
!private <fields>;
!private <methods>;
}
-keepnames class * implements java.io.Serializable
-keepattributes *Annotation*
-keep class * implements java.sql.Driver
-adaptresourcefilenames **.properties,**.gif,**.jpg
-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF,WEB-INF/conf
# 特定包需要保留的类名等
-keepnames class com.jt.components.upload.*
-keepnames class com.jt.components.upload.constants.**
-keepnames class com.jt.components.upload.local.controller.**
-keepnames class com.jt.components.upload.download.**
-keepnames class com.jt.components.upload.mongodb.helper.MGFileHelper
-keepnames class com.jt.components.upload.mongodb.util.**
-keepnames class com.jt.components.cloud.aliyunoss.**
-keepclassmembernames class com.jt.components.upload.*** {
public *;
}
主要是能够理解上面提到的三个方面(keep是重点) , 就能根据自己的需要进行相应的修改.
参考: