zoukankan      html  css  js  c++  java
  • 【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:?]  

    相关链接:开发日志

  • 相关阅读:
    面试
    二叉树- 二叉树直径
    排序算法
    JAVA编程
    JAVA编程
    JAVA中break和continue的区别
    HTTP的序列化和反序列化
    PL/SQL基础
    G. Game Design
    hdu 6703 array
  • 原文地址:https://www.cnblogs.com/jpfss/p/9150951.html
Copyright © 2011-2022 走看看