ProGuard使用简介

背景简介:

ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具,它可以删除无用的类、字段、方法和属性。可以删除没用的注释,最大限度地优化字节码文件。它还可以使用简短的无意义的名称来重命名已经存在的类、字段、方法和属性,增加项目被反编译的难度。

用法简介

命令:

java -jar proguard.jar options ...

常用选项说明:

Input/Output 选项

-include filename

简写:@filename

递归读取指定的文件名的配置选项,文件名支持

示例:-include lib/annotations.pro;

该名称可以包含Java系统属性(或Ant属性,使用Ant时),由尖括号,“”分隔。

例如, /lib/rt.jar会自动扩展为类似/usr/local/java/jdk/jre/lib/rt.jar。

同样,扩展到用户的主目录,而被扩展为当前工作目录

-injars class_path

指定即将被混淆的jar文件(或者aars, wars, ears, zips, apks, 或者文件目录)的路径

示例:

-in.jar(!images/**)      #匹配jar包中所有非images目录下的文件

-injars  project(.class)     #匹配project目录下的所有class文件

-outjars class_path

指定混淆后输出的jar文件(或者aars, wars, ears, zips, apks, 或者文件目录)的路径

指定输出路径时,必须避免覆盖输入文件。

-libraryjars class_path

指定injar依赖的库文件,可以是jar文件(或者aars, wars, ears, zips, apks, 或者文件目录),这些文件不会包含到outjars中。

-skipnonpubliclibraryclasses

配置此选项将在读取library jar时跳过non-public classes ,会让proguard在执行过程中效率更快,如果跳过的非公共类对injars文件有影响,proguard会打出警告。

-dontskipnonpubliclibraryclasses

指定不去忽略非公共的库类。

-dontskipnonpubliclibraryclassmembers

指定不去忽略非公共的库类的成员。

-keepdirectories[directory_filter]

保留输出jar文件(或者aars, wars, ears, zips, apks, 或者文件目录)的目录信息,默认情况下,proguard为了减小文件大小,目录信息会被删除。单数如果class需要以类似“mypackage.MyClass.class.getResource("")”的方法查找,则必须保留相应包下的目录信息。例如:-keepdirectories mydirectory/**表示保留mydirectory目录及其子目录下的所有类的目录信息。

Keep 选项

指定不不混淆的类,成员或方法

-keepclassmembers {modifier} {class_specification}

保护指定类的成员,如果此类受到保护他们会保护的更好

-keepclasseswithmembers {class_specification}

保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。

-keepnames {class_specification}

保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)

-keepclassmembernames {class_specification}

保护指定的类的成员的名称(如果他们没有在压缩步骤中删除)

-keepclasseswithmembernames {class_specification}

保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)

-printseeds {filename}

列出类和类的成员-keep选项的清单,标准输出到给定的文件

Shrinking 选项

-dontshrink

不压缩输入的类文件,不配置的话默认压缩,除了在keep选项中设置的类和成员外,所有的类和类成员都将被移除。

-printusage {filename}

在压缩有效的情况下,将输入类文件中的僵尸代码列表打印到标准输出文件中。

-whyareyoukeeping {class_specification}

配置该选项后会在压缩步时,打印出配置类或成员被保留的原因的细节

Optimization 选项

-dontoptimize

不优化输入的类文件,默认开启优化

-optimizationpassesn

制定优化执行的次数,默认一次,多次优化执行时,发现没有可改进的,则优化结束。

-assumenosideeffects {class_specification}

指定不被调用的的方法,优化时会删除该方法。例如:

指定System.currentTimeMillis()方法,不被调用的情况下可以删除。

-allowaccessmodification

优化时允许访问并修改有修饰符的类和类的成员

Obfuscation 选项

-dontobfuscate

不混淆输入的类文件

-printmapping {filename}

将混淆前和混淆后的类和类成员打印到制定文件中

-applymapping {filename}

重用映射文件,一般用于增量混淆,例如:

-injars       proguardgui.jar

-outjars      proguardgui_out.jar

-libraryjars  proguard.jar

-libraryjars  /lib/rt.jar

-applymapping proguard.map

-keep public class proguard.gui.ProGuardGUI {

public static void main(java.lang.String[]);

}

-obfuscationdictionary {filename}

使用给定文件中的关键字作为要混淆方法的名称

-overloadaggressively

混淆时应用侵入式重载

-useuniqueclassmembernames

确定统一的混淆类的成员名称来增加混淆

-flattenpackagehierarchy {package_name}

重新包装所有重命名的包并放在给定的单一包中

-repackageclass {package_name}

重新包装所有重命名的类文件中放在给定的单一包中

-dontusemixedcaseclassnames

混淆时不会产生形形色色的类名

-keepattributes {attribute_name,...}

保护给定的可选属性,例如

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,

SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

LineNumberTable:保留方法的行号

LocalVariableTable:保留局部变量的名称和类型

SourceFile:保留被编译源文件的名称,在堆栈追踪时会显示

Deprecated:表明方法,成员或类已经过期

Signature: 保留类,字段或方法的签名,编译器可能需要这些信息来正确编译使用泛型的编译库类。代码可以通过反射来访问此签名

*Annotation*:保留被注解过的类或成员

InnerClasses:保留内部类信息

Exceptions:保留类捕获的异常

-renamesourcefileattribute[string]

指定一个字符串常量被放入的SourceFile属性的类文件(和SourceDir属性)。请注意,属性必须存在,该属性必须显式的使用-keepattributes指令被保留。例如,你想保留异常,源文件行数信息时,设置-renamesourcefileattribute SourceFile。只有当混淆时适用。

-keepparameternames

保留参数的名称和方法,该选项可以保留调试级别的属性。

Overview of Keep Options

-keep 选项之间的关联:

保留

不被删除或者重命名

不被重命名

Classes and class members

Classes and class members, if class members present

如果你不知道使用哪个选项,你应该简单地使用-keep。这将确保指定的类和类成员在压缩步骤不会被删除,并在混淆步骤不被重命名。

注意:

·         当你值指定了一个类,没有指定其下的的成员,那么,Proguard只会类和器无参数构造函数,这个类下未被指定的成员变量任然会被删除,优化,混淆。

·         如果你只指定一个方法,proguard只会保留其方法,但是方法中的代码任然会白优化和调整。

Class Specifications

[@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname[extends|implements [@annotationtype] classname]

[{

[@annotationtype] [[!]public|private|protected|static|volatile|transient ...] | (fieldtype fieldname);

[@annotationtype] [!]public|private|protected|static|synchronized|native|abstract|strictfp ...] | (argumenttype,...) | classname(argumenttype,...) |                                                                                         (returntype methodname(argumenttype,...));

[@annotationtype] [[!]public|private|protected|static ... ] *;

...

}]

说明:

"[]”表示它里面的内容是可选的;

"…"表示其前面的参数可以有任意多个;

"|"表示分隔两个备选项;

"()"只是为了将写好的属于一组的规范括起来;

"class"关键字代表任意接口或类;

"interface"关键字限制只能匹配接口;

"enum"关键字限制只能匹配枚举类;

"!"加载关键字前代表不匹配此类或接口;

"classname"必须指定全称,例如:java.lang.string;

"$"指定内部类是需要用到"$",例如java.lang.Thread$state

指定classname时可以用正则表达式:

"?":匹配任意单个字符(不包括包名分隔符),例如,"com.test? "匹配"com.test1", "com.test2",但是不匹配"com.test12";

"*":匹配类名的任意字符,例如,"mypackage.*Test*"匹配 "mypackage.Test"

"mypackage.YourTestApplication", 但是不匹配 "mypackage. subpackage.MyTest".

通常情况下"mypackage.*" 匹配所有在"mypackage"包下的类, 但不匹配在其

子包下的类;

"**":匹配类名的任意部分,并且可以包含包分隔符的任意个数,例如:"**.Test"

匹配除了根包下的所有包内的 Test类. "mypackage.**" 所有在mypackage包

及其子包下的所有类。

"extends","implements" 关键字通常使用通配符来限制类,指定只有继承或实现关键字后的类才匹配;

"@"限制只有被指定annotationtype注解的类或者类成员才匹配,annotationtype指定类似于classname,例如:@org.springframework.beans.factory.annotation.Autowired;

属性和方法的规范和java语言很类似,唯一不同的是方法的参数列表在指定时只需要指定类型,不需要包含参数名,其常用匹配符如下:

匹配任意构造函数

匹配任意属性

匹配任意方法

*  匹配任属性或方法

以上匹配符都不包含返回类型,只有匹配符包含参数列表。

属性和方法也可以使用正则表发是匹配,例如:

%

匹配所有原始类型,例如 ("boolean", "int", 不包括 "void").

?

匹配任意单个自读.

*

匹配任意单个字符(不包括包名分隔符)

**

匹配类名的任意部分,或许会包含任意个数的包名分隔符

***

匹配任意类型(原始或者给原始类型,数组或非数组类型)

...

匹配任意数量,任意类型的参数.

注意:

?, *, 和** 不会匹配primitive types. *** 可以匹配任意长度的数组. 例如, "** get*()" 匹配 "java.lang.Object getObject()", 但是不匹配 "float getFloat()", 也不匹配"java.lang.Object[] getObjects()".

支持Ant编译

版本要求

Jdk1.8+;

ant 1.8+

官方说明:

ProGuard can be run as a task in the Java-based build tool Ant (version 1.8 or higher)

配置文件示例

build.xml

classpath="lib/proguard.jar" />

applications.pro

#

# This ProGuard configuration file illustrates how to process applications.

# Usage:

#     java -jar proguard.jar @applications.pro

#

# Specify the input jars, output jars, and library jars.

-injars  in.jar

-outjars out.jar

-libraryjars /lib/rt.jar

#-libraryjars junit.jar

#-libraryjars servlet.jar

#-libraryjars jai_core.jar

#...

# Save the obfuscation mapping to a file, so you can de-obfuscate any stack

# traces later on. Keep a fixed source file attribute and all line number

# tables to get line numbers in the stack traces.

# You can comment this out if you're not interested in stack traces.

-printmapping out.map

-renamesourcefileattribute SourceFile

-keepattributes SourceFile,LineNumberTable

# Preserve all annotations.

-keepattributes *Annotation*

# You can print out the seeds that are matching the keep options below.

#-printseeds out.seeds

# Preserve all public applications.

-keepclasseswithmembers public class * {

public static void main(java.lang.String[]);

}

# Preserve all native method names and the names of their classes.

-keepclasseswithmembernames,includedescriptorclasses class * {

native ;

}

# Preserve the special static methods that are required in all enumeration

# classes.

-keepclassmembers,allowoptimization enum * {

public static **[] values();

public static ** valueOf(java.lang.String);

}

# Explicitly preserve all serialization members. The Serializable interface

# is only a marker interface, so it wouldn't save them.

# You can comment this out if your application doesn't use serialization.

# If your code contains serializable classes that have to be backward

# compatible, please refer to the manual.

-keepclassmembers class * implements java.io.Serializable {

static final long serialVersionUID;

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();

}

# Your application may contain more items that need to be preserved;

# typically classes that are dynamically created using Class.forName:

# -keep public class mypackage.MyClass

# -keep public interface mypackage.MyInterface

# -keep public class * implements mypackage.MyInterface

支持Maven编译

Maven支持proguard需要用到第三方插件,proguard官方推荐:

版本要求

Maven 3.1

Jdk版本根据依赖的proguard版本决定

配置文件示例

在pom.xml文件中加入proguard插件配置:

com.idfconnect.devtools

idfc-proguard-maven-plugin

1.0.1

package

obfuscate

${project.build.outputDirectory}

${java.home}/lib/rt.jar

false

false

< file>${project.build.finalName}.${project.packaging}

net.sf.proguard

proguard-base

4.9

Pro文件示例:

除了plugin之外的配置,还有一个.pro的配置文件(存放在${basedir}/src/main/config/${project.artifactId}-maven.pro)。

如果需要指定配置文件目录,则通过以下配置实现:

${basedir}/src/main/config/${project.artifactId}-maven.pro

Pro文件示例:

#保留调试信息(异常信息源码行数)

-renamesourcefileattribute SourceFile

-keepattributes SourceFile,LineNumberTable

#混淆时不要形成混合大小写类名

-dontusemixedcaseclassnames

#保留调试级别的属性

-keepparameternames

# 保留注解信息,签名信息,异常信息,内部类信息

-keepattributes *Annotation*,Signature,Exceptions,InnerClasses

#指定混淆时方法和属性名替换字典文件

-obfuscationdictionary shakespeare.txt

# 保留所有共有和保护类型的属性和方法

-keep public class * {

public protected *;

}

#保留枚举类方法

-keepclassmembers,allowoptimization enum * {

public static **[] values();

public static ** valueOf(java.lang.String);

}

#保留所有实现序列化的类的素有属性

-keepclassmembers class * implements java.io.Serializable {

private ;

}

#保留com.coship.oms.web包下所有条件了@Autowired注解的素有属性

-keepclassmembers class com.coship.oms.web.** {

@org.springframework.beans.factory.annotation.Autowired ;

}

配置异常及解决

原因:

这个错误主要是因为action的参数标注默认是debug级别,比如

@RequestMapping(value = "/security/login", method = RequestMethod.POST)

public ModelAndView login(@RequestParam String userName, @RequestParam String password,

HttpServletRequest request) {

此时userName的级别时debug级别,而在proguard编译时是忽略了这些标注,导致请求时就会找不到userName的参数。

解决方法:

编译脚本中添加-keepparameternames保留调试属性

2.       找不到使用@Autowired注入的service类

混淆时  proguard会对jar包进行优化,以期减少其大小。默认情况下,proguard会删除jar中的目录元素,导致ClassLoader().getResource()方法找不到对应的资源。只需要在使用时 加上 -keepdirectories 选项即可。

proguard java enum,ProGuard使用简介相关推荐

  1. proguard java enum,Proguard没有这么说就不会混淆课堂

    我正在构建一个android库,我使用的是一个实用程序类,其中所有方法都是静态的 . 此类在内部使用,不应由库用户使用 . 我正在使用proguard来混淆代码,我不想暴露实用程序类 . 当我使用pr ...

  2. proguard java 教程,ProGuard 初探,新手入门必知必会

    1. Start up 下载并安装proguard,当前是5.3.3,解压并将bin所在目录设置到系统环境变量中,接着你就可以使用命令行工具开始ProGuard之旅了. 1.1 @myconfig.p ...

  3. 【Android 安全】DEX 加密 ( Proguard 简介 | Proguard 相关网址 | Proguard 混淆配置 )

    文章目录 一.Proguard 简介 二.Proguard 相关网址 三.Proguard 混淆配置 一.Proguard 简介 Android 开发中 Proguard 主要作用是对 Java 代码 ...

  4. proguard java 教程,[Gradle中文教程系列]-跟我学Gradle-使用proguard混淆你的spring boot应用...

    使用proguard混淆你的spring boot应用 Proguard介绍 安卓开发的同学想必对Proguard都是十分熟悉的,由于java的反编译实在是太容易,使用它可以对java源码进行混淆处理 ...

  5. 如何使用Java Enum

    简单的用法:JavaEnum简单的用法一般用于代表一组常用常量,可用来代表一类相同类型的常量值.如: 性别: public enum SexEnum {male, female;}颜色: public ...

  6. android enum java包_Android @IntDef注解取代Java enum枚举提高性能详解

    Android @IntDef注解取代Java enum枚举提高性能 为提高Android性能,Android官方建议使用@IntDef注解替代Java的enum枚举.@IntDef的使用给出一个例子 ...

  7. Java开源项目EZMorph简介

    http://hi.baidu.com/glfbin/blog/item/1302747e8722852e0cd7daaf.html Java开源项目EZMorph简介 2011-04-30 9:40 ...

  8. Java Enum 枚举

    Java Enum(枚举)是一个Java类 enum TestEnum{     a("Foo1"),b("Foo2"),c("Foo3") ...

  9. java.util.Stack类简介

    转载自  java.util.Stack类简介 Stack是一个后进先出(last in first out,LIFO)的堆栈,在Vector类的基础上扩展5个方法而来 Deque(双端队列)比起St ...

最新文章

  1. 技嘉G31主板学习笔记
  2. java解锁_Java 姿势解锁 —— Lists.transform
  3. Android之自定义标题
  4. 2010年8月和9月成果
  5. 游戏编程新手教程:怪物AI设计简述
  6. .NET下实现分布式缓存系统Memcached
  7. qt5连接sqlite数据库实例
  8. 拓展卡尔曼滤波器(EKF)的数学推导
  9. 吴恩达机器学习笔记-非监督学习
  10. 知乎上的44条神回复,针针见血,看完整个人通透多了
  11. 安装运行okvis odometry
  12. 【LA4992】Jungle Outpost(半平面交+二分)
  13. 什么是微网格?微网格规划应考虑哪些因素?
  14. 【论文阅读】Tensor Fusion Network for Multimodal Sentiment Analysis
  15. hta 北京自动挂号器
  16. vue点击按钮打开新页签,并传参
  17. Xilinx_PetaLinux:Failed to generate...
  18. 音乐播放器的滚动歌词的实现
  19. 大家说说房价还会不会涨?
  20. Vero VISI 2021.0.2109

热门文章

  1. 国庆集训1027-1028(未完成)
  2. 人工膜行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  3. idea本地安装gradle
  4. mysql8 servertime_MySql的时区(serverTimezone)引发的血案
  5. Popov超稳定性在模型参考自适应(MRAS)中的应用
  6. Python手撸机器学习系列(四):朴素贝叶斯(华强买瓜版)
  7. magento2国际化相关
  8. 【Linux高频命令专题(5)】rmdir
  9. 语言通计算机怎么设置音乐,录屏大师怎么添加配音 添加音乐教程
  10. VSTS - Code (一)