【Developer Log】ProGuard扰码可执行JAR包

在项目上线之前需要通过ProGuard来对java的class进行混淆,以避免反编译方式,来保护自己的代码。ProGuard网上有很多资料,可以参考:http://blog.csdn.net/zhangdaiscott/article/details/45368261。在此,记录扰码可执行JAR包出现的问题,已经相关的解决方式。

1、引用第三方库的处理方式

引用第三方库,应避免修改第三方库的类名和public的方法、参数,否则在proguard回报很多warning,而执行失败。在Eclipse打包为可执行jar包时有以下的几个选择。

Extract方式是缺省的方式,会将第三方jar包解压成为具体的*.class ,然后和我们自己的*.class一起封装成为jar。Proguard会对所有class进行扰码,因此包括了第三方jar包。

最直接的方式就是让第三方jar包不参与proguard的混淆,因此我们可以选择余下两种方式,这里我选择了Package方式。我们用7Zip对jar包进行解压,会看到第三方jar包仍以jar包的方式存在。

2、可执行main要保留

我们需要保留jar包中的资源,特别是MANIFEST.MF文件,下面是这个文件的例子:

Rsrc-Class-Path: ./ log4j-core-2.4.1.jar log4j-api-2.4.1.jar gson-2.4. jar  mysql-connector-java-5.1.37.jar
Class-Path: .
Rsrc-Main-Class: MyPackage.App
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader

这里设计两个具有Main的可执行类MyPackage.App,和org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader(顾名思义,load第三方库的)。我们必须确保能够找到这两个类的main,也就是这两个类的全名(包名和类名)以及mian的方法名字都必须保留正确。增加一下配置即可:

-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF

-whyareyoukeeping class *

-keep public class MyPackage.App {
    public static void main(java.lang.String[]);
}

-keep public class org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader {
    public static void main(java.lang.String[]);
}

对应与GUI中,如下几图:

有些参数是可以调整的,例如可以不选择Keep parameter

3、关于Gson

如果我们采用Gson来进行Json的处理,由于Gson和类中定义的成员名字有关,如果对这些名字进行混淆,则无法正确进行Json的解析,有两种方法处理:

1)在上图中右下方的“Keep additional names and class membe names”中选择相关的类和成员。一般这些成员都是private的。

2)更合适的方式如下,在代码中加入@SerializedName

    @SerializedName("clientName")
    private String clientName;
    @SerializedName("ServerName")
    private String ServerName;

 此外,对于要封装成JSON字符串的属性,必须提供getter方法,例如上面如果不提供getClientName,则json字符串中没有该属性。对应的,如果进行解析,则必须提供setter方法。

出现一个奇怪的现象待查。如果定义一个数组Vector<String> urls,当然也给出@SerializedName("urls")。如果我们将此定义在继承类,在运行的时候会报错,如下所示。需要将此定义在基类来解决,有些奇怪,先记录下来

  1. 错误:java.lang.IllegalArgumentException: class c.d declares multiple JSON fields named h  
  2. java.lang.IllegalArgumentException: class c.d declares multiple JSON fields named h  
  3.         at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:167) ~[gson-2.4.jar:?]  
  4.         at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97) ~[gson-2.4.jar:?]  
  5.         at com.google.gson.Gson.getAdapter(Gson.java:360) ~[gson-2.4.jar:?]  
  6.         at com.google.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:48) ~[gson-2.4.jar:?]  
  7.         at com.google.gson.Gson.getAdapter(Gson.java:360) ~[gson-2.4.jar:?]  
  8.         at com.google.gson.Gson.fromJson(Gson.java:813) ~[gson-2.4.jar:?]  
  9.         at com.google.gson.Gson.fromJson(Gson.java:752) ~[gson-2.4.jar:?]  

相关链接:开发日志

原文地址:https://www.cnblogs.com/jpfss/p/9150951.html