在项目上线之前需要通过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.lang.IllegalArgumentException: class c.d declares multiple JSON fields named h
java.lang.IllegalArgumentException: class c.d declares multiple JSON fields named h
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:167) ~[gson-2.4.jar:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:97) ~[gson-2.4.jar:?]
at com.google.gson.Gson.getAdapter(Gson.java:360) ~[gson-2.4.jar:?]
at com.google.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:48) ~[gson-2.4.jar:?]
at com.google.gson.Gson.getAdapter(Gson.java:360) ~[gson-2.4.jar:?]
at com.google.gson.Gson.fromJson(Gson.java:813) ~[gson-2.4.jar:?]
at com.google.gson.Gson.fromJson(Gson.java:752) ~[gson-2.4.jar:?]

相关链接:开发日志

【Developer Log】ProGuard扰码可执行JAR包的更多相关文章

  1. Spring Boot 怎么打一个可执行 Jar 包?

    传统的 Java 应用程序都需要打一个 war 包,并到到 Tomcat webapps 目录下运行. Java 支持打 Jar 包,但没有提供一个标准的方式在一个 Jar 包内再加载嵌入别的 Jar ...

  2. 使用eclipse创建java程序可执行jar包

    一.eclipse中,在要打成jar包的项目名上右击,出现如下弹出框,选择“export”: 二.在接下来出现的界面中点击“jar file”,然后next: 三.在接下来出现的界面中,如图所示勾选上 ...

  3. 使用原生Java代码生成可执行Jar包

    最近想做一个功能,就是把我们编译后的字节码及其资源文件打包成一个可执行的jar包,在装有jre的机器上双击就能运行. 首先是我们需要选择哪些字节码和文件需要打包到文件中,这个我们用JFileChoos ...

  4. 将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class、缺少 xsd、重复打包依赖)

    最近在看 spring boot 的东西,觉得很方便,很好用.对于一个简单的REST服务,都不要自己部署Tomcat了,直接在 IDE 里 run 一个包含 main 函数的主类就可以了. 但是,转念 ...

  5. SpringBoot小技巧:修改java可执行jar包内容

    SpringBoot小技巧:修改java可执行jar包内容 情景描述 在生产环境中,有时候我们发现了个小bug,开发迅速修改代码后,很多时候我们不得不重新发布一个新的可执行jar包上去替换掉.但是这样 ...

  6. java 执行 jar 包中的 main 方法

    java 执行 jar 包中的 main 方法 通过 OneJar 或 Maven 打包后 jar 文件,用命令: java -jar ****.jar执行后总是运行指定的主方法,如果 jar 中有多 ...

  7. 用Intellij打可执行jar包

    1.添加maven-assembly-plugin和maven-dependency-plugin assembly:用于打可执行jar包 dependency: 导出依赖包 <plugin&g ...

  8. Maven打包可执行Jar包方式

    第一步:pom.xm中的build标签下加入maven插件配置,打包生成可执行jar包方式Maven中的打包方式更换为 <packaging>jar</packaging> b ...

  9. NetBeans IDE 7.4 Beta版本build JavaFX时生成的可执行jar包执行时找不到依赖的jar包

    现象,执行时抛出java.lang.ClassNotFoundException异常: Executing E:\secondegg\secondegg-reversi\dist\run8022211 ...

随机推荐

  1. sql 语句NVL()用法

    一NVL函数是一个空值转换函数 NVL(表达式1,表达式2) 如果表达式1为空值,NVL返回值为表达式2的值,否则返回表达式1的值. 该函数的目的是把一个空值(null)转换成一个实际的值.其表达式的 ...

  2. E20170705-hm

    bubble   n. 泡,水泡; 冒泡,起泡; 泡影,妄想; (欲表达的) 一点感情;

  3. [Swift通天遁地]三、手势与图表-(9)制作五彩缤纷的气泡图表

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  4. [Swift通天遁地]九、拔剑吧-(4)使用开源类库创建可滑动的Segment分段控件

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  5. python配置文件编写

    from configparser import ConfigParser # 配置类,专门来读取配置文件# 配置文件结尾:.ini .conf .config .properties .xml# 配 ...

  6. akka设计模式系列-Aggregate模式

    所谓的Aggregate模式,其实就是聚合模式,跟masterWorker模式有点类似,但其出发点不同.masterWorker模式是指master向worker发送命令,worker完成某种业务逻辑 ...

  7. linux 如何查看进程的执行时间

    ps  -ef|grep wo.php 得到 程序的pid 如 123 ps -p 123 -o etime

  8. NS2学习笔记(四)

    这几天学习NS2,虽然国内很多人使用,但系统的教材资料不多,只能一边看中文教材,一边看英文手册,知识点也是零零散散.过段时间等能将所有知识点串上,再总结总结.现只讲一些零碎的点记录一下. 添加新的协议 ...

  9. 【NOIP2016】DAY1 T2 天天爱跑步

    [NOIP2016]DAY1 T2 天天爱跑步 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要玩家每天按时 ...

  10. 参加2016华为codecraft编程精英挑战赛后感

    2016年4月参加了华为的软件比赛. 关于比赛:给了一道图论的np-hard问题.刚开始完全不知道怎么入手,请教过师兄,自己也琢磨过,没有什么万全的解决方法.注意,这里说的是万全的办法.本科搞算法时候 ...