【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")。如果我们将此定义在继承类,在运行的时候会报错,如下所示。需要将此定义在基类来解决,有些奇怪,先记录下来
- 错误: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:?]
错误: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包的更多相关文章
- Spring Boot 怎么打一个可执行 Jar 包?
传统的 Java 应用程序都需要打一个 war 包,并到到 Tomcat webapps 目录下运行. Java 支持打 Jar 包,但没有提供一个标准的方式在一个 Jar 包内再加载嵌入别的 Jar ...
- 使用eclipse创建java程序可执行jar包
一.eclipse中,在要打成jar包的项目名上右击,出现如下弹出框,选择“export”: 二.在接下来出现的界面中点击“jar file”,然后next: 三.在接下来出现的界面中,如图所示勾选上 ...
- 使用原生Java代码生成可执行Jar包
最近想做一个功能,就是把我们编译后的字节码及其资源文件打包成一个可执行的jar包,在装有jre的机器上双击就能运行. 首先是我们需要选择哪些字节码和文件需要打包到文件中,这个我们用JFileChoos ...
- 将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class、缺少 xsd、重复打包依赖)
最近在看 spring boot 的东西,觉得很方便,很好用.对于一个简单的REST服务,都不要自己部署Tomcat了,直接在 IDE 里 run 一个包含 main 函数的主类就可以了. 但是,转念 ...
- SpringBoot小技巧:修改java可执行jar包内容
SpringBoot小技巧:修改java可执行jar包内容 情景描述 在生产环境中,有时候我们发现了个小bug,开发迅速修改代码后,很多时候我们不得不重新发布一个新的可执行jar包上去替换掉.但是这样 ...
- java 执行 jar 包中的 main 方法
java 执行 jar 包中的 main 方法 通过 OneJar 或 Maven 打包后 jar 文件,用命令: java -jar ****.jar执行后总是运行指定的主方法,如果 jar 中有多 ...
- 用Intellij打可执行jar包
1.添加maven-assembly-plugin和maven-dependency-plugin assembly:用于打可执行jar包 dependency: 导出依赖包 <plugin&g ...
- Maven打包可执行Jar包方式
第一步:pom.xm中的build标签下加入maven插件配置,打包生成可执行jar包方式Maven中的打包方式更换为 <packaging>jar</packaging> b ...
- NetBeans IDE 7.4 Beta版本build JavaFX时生成的可执行jar包执行时找不到依赖的jar包
现象,执行时抛出java.lang.ClassNotFoundException异常: Executing E:\secondegg\secondegg-reversi\dist\run8022211 ...
随机推荐
- java事件处理机制(自定义事件)
java中的事件机制的参与者有3种角色: 1.event object:事件状态对象,用于listener的相应的方法之中,作为参数,一般存在与listerner的方法之中 2.event sourc ...
- mysql中 groupby分组
引用自http://www.cnblogs.com/mo-beifeng/archive/2012/02/07/2341886.html#2341105 --按某一字段分组取最大(小)值所在行的数据 ...
- [Swift通天遁地]五、高级扩展-(1)快速检测设备属性:版本、类型、屏幕尺寸
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- hadoop一主一从部署(1)
一.安装前说明 主机IP:192.168.132.128 从机IP:192.168.132.129 1. 所有的安装包我放在了/root/这个目录下,你要根据自己情况去修改,这点必须注意 2. 采用的 ...
- python django简单操作
准备: pip3 install django==1.10.3 cmd django-admin startproject guest 创建一个guest的项目 cd guest manage. ...
- 【Leetcode146】LRU Cache
问题描述: 设计一个LRU Cache . LRU cache 有两个操作函数. 1.get(key). 返回cache 中的key对应的 val 值: 2.set(key, value). 用伪代码 ...
- Kibana里No Marvel Data Found问题解决(图文详解)
问题详情 http://192.168.80.145:5601/app/marvel#/no-data?_g=(refreshInterval:(display:'10%20seconds',paus ...
- SQL Sever语言 事务
事务:保障流程的完整执行保证程序某些程序在运行时同时成功同时失败,保证程序的安全性 begin tran --在流程开始的位置加 --此处写SQL语句 if @@error>0 --ERRORS ...
- Java Controller下兼容xls和xlsx且可识别合并单元格的excel导入功能
1.工具类,读取单元格数据的时候,如果当前单元格是合并单元格,会自动读取合并单元格的值 package com.shjh.core.util; import java.io.IOException; ...
- NSNotificationCenter 的使用详解
通常我们在 iOS 中发生什么事件时该做什么是由 Delegate 实现的,例如 View 加载完后会触发 viewDidLoad.Apple 还为我们提供了另一种通知响应方式,那就是 NSNotif ...