想的再多,不如行动起来,大家好,我是啊Q,让我们徜徉在常识的海洋里吧。

一同“敞开生长之旅!这是我参加「日新计划 2 月更文应战」的第 4天,点击检查活动概况。

代码混杂

一.基本概念

java的bytecode很简略经过JAD等反编译东西复原出源代码。这样势必不满足安全的界说。如何必定程度上保护需求避免被反编译的源代码呢?混杂(obfuscate)技能。留意:用obfuscate防盗版是根本不或许,连汇编这种东西都能被**掉,而java代码基本上等同于开源的同义词。用obfuscate仅仅为了增加反编译的难度,保护源代码的常识产权。混杂包照旧运转,没有任何问题。能够运用反编译东西如jd-gui检查混杂后的包,验证混杂作用。

二.混杂技能

称号混杂 name obfuscode

将有意义的类,字段、办法称号更改为无意义的字符串。生成的新称号越 短,字节代码越小。在称号混杂的字节代码中,包,类,字段和办法称号已重命名,而且永久不能康复原始称号。

流混杂 Flow Obfuscation

用于if, switch, while,for等关键字,对字节码进行细微的修正,模糊操控流,而不改变代码在运转时的行为。一般情况下,选择和循环等逻辑构造会被更改,因而它们不再具有直接等效的Java源代码。流模糊的字节码一般强制反编译器将一系列标签和不合法的goto语句刺进到它们生成的源代码中。源代码有时会由于反编译过错而变得愈加模糊。

其他

  • 反常混杂 Exception Obfuscation
  • 字符串加密混杂 String Encryption
  • 引证混杂 Reference Obfuscation

三.常用东西

1.proguard

proguard是一个免费的 Java类文件的紧缩,优化,混肴器。它删去没有用的类,字段,办法与特点。使字节码最大程度地优化,运用简短且无意义的姓名来重命名类、字段和办法
官网地址:www.guardsquare.com/en/products…

2.yGuard

yGuard是一款免费的Java混杂器(非开源),它有Java和.NET两个版别。yGuard 完全免费,基于 Ant 使命运转,供给高可装备的混杂规则。
官网地址:www.yworks.com/products/yg…

3.allatori

第二代Java混杂器。所谓第二代混杂器,不只仅能进行字段混杂,还能完成流混杂。
命名混杂,流混杂,调试信息混杂,字符串编码,以及水印技能。关于教育和非商业项目来说这个混杂器是免费的。支撑war和jar格式,支撑对需求混杂代码的应用程序增加有效日期。
官网地址:www.allatori.com/

4.总结

推荐运用 proguard :开源, 运用简略 ,文档丰富完善。

四.东西比照

东西 官网地址 官方文档 开源免费 称号混杂 流混杂 maven支撑 功用
proguard www.guardsquare.com/proguard www.guardsquare.com/manual/home
yGuard www.yworks.com/products/yg… yworks.github.io/yGuard/
allatori allatori.com/ ✕(免费用于教育和非商业项目) 减小包大小;混杂代码;增加水印

五.详细内容

1.yGuard(yworks.github.io/yGuard/)

  • 易于设置:yGuard 是一个 Ant 使命!作为 Ant 使命,yGuard 能够无缝集成到您在 Ant、Maven 和 Gradle 等很多构建系统中的部署进程中
  • 高级缩短:yGuard 经过依靠分析供给精细的代码缩短功用。
  • 可装备/安全代码:yGuard 供给高度可装备的称号混杂,可保护您的常识产权免受逆向工程。
  • 开源:yGuard 是完全开源的!与昂贵的商业产品相反,yGuard 是而且永久都是免费的。
  • Java 兼容性:要运转 yGuard 软件,您需求 JDK 1.7.x 或更高版别以及 Ant 1.5.x 或更高版别(它或许与任一软件的前期版别兼容,但尚未经过测试)。
    yGuard 与一切已发布的 Java 版别(最高 Java 17)兼容。可是,依据运用的版别,功用或许会略有不同。该文档包括不同版别支撑的功用的详细阐明。假如您计划将 yGuard 与 Java 以外的东西一同运用,还有一个关于3rd 方 JVM 支撑的部分。

ProGuard

是一个开源的 Java 类文件缩短器、优化器、混杂器和预验证器。因而,ProGuard 处理的应用程序和库更小、更快,而且在必定程度上能够抵挡逆向工程。

  • 缩短进程检测并删去未运用的类、字段、办法和特点。
  • 优化器 进程优化字节码并删去未运用的指令。
  • 混杂进程运用简短无意义的称号重命名剩余的类、字段和办法。
  • 最后的预验证进程将预验证信息增加到类中,这是 Java Micro Edition 和 Java 6 及更高版别所必需的。

yGuard

1.maven引证办法

<build>
        <plugins>
            <plugin>
                <!--结合ant run 来运用yguard -->
                <artifactId>maven-antrun-plugin</artifactId>
                <dependencies>
                    <dependency>
                        <groupId>com.yworks</groupId>
                        <artifactId>yguard</artifactId>
                        <version>3.1.0</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <tasks>
                                <property refid="maven.compile.classpath" name="mvn.classpath"/>
                                <!-- <echo message="Using Maven Classpath: ${mvn.classpath}" /> -->
                                <taskdef name="yguard"
                    classname="com.yworks.yguard.YGuardTask"/>
                                <yguard>
                                    <!-- yguard装备 -->
                                </yguard>
                            </tasks>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

2.yguard装备解析

写在前面

  1. yguard共分为两大使命装备:
    1. rename 混杂称号 :首要用于修正类名,特点名,办法名以及参数名等。
    2. shrink 缩短代码 : 首要用于从多个进口点中删去一切无法访问的类、字段和办法。
  1. keep keep是renameshrink的子元素,用于指定从父级renameshrink使命中扫除的元素。

留意事项

  1. 留意事项1假如项目需求shrink, shrink最好是装备在rename之前。即在进行代码混杂之前,先进行代码紧缩。 由于紧缩代码需求指定紧缩的根代码。
    举个比如:比方制定main办法: 。假如先混杂,DplDbtransferApplication类名被修正的话(比方为A.class),该装备将会无效,一切代码都会被 shrink 删去,由于现已找不到DplDbtransferApplication这个类了(类名被修正)。
  2. 其他装备请参阅官方文档。

装备阐明

根底装备

 <!-- yguard 是共用装备和rename以及shrink装备的容器标签 -->
 <yguard>
    <!-- 有必要至少指定一个inoutpair元素或一个非空inoutpairs元素才干运转yguard使命。此元素指定输入和输出 jar 文件的途径 
    in out 有必要指定设置值,不指定报错
    1.in 指定一个现有的jar/war文件,其间包括未缩短和未混杂的 .class文件。
    2.out 指定一个 jar/war文件的途径,该文件将被创立并用于放置缩短和混杂进程的成果。
    3.resources 如何处理资源文件,支撑三种值:copy,auto,none。 默许装备copy。
		    1.copy 直接仿制资源文件 默许情况下,只需将一切资源文件仿制到输出 jar 中
		    2.auto 仅仿制那些在紧缩后仍包括一个或多个 .class 文件的目录中的资源文件。
 		   3.none 丢弃一切资源文件。-->
    <inoutpair 
    in="${project.build.directory}/${project.build.finalName}.${project.packaging}" 
	out="${project.build.directory}/${project.build.finalName}.${project.packaging}" />     
	<externalclasses>
	</externalclasses>
	<!-- 用于装备一些特点 ,保存类的调试信息:比方 LineNumberTable:行号表;LocalVariableTable:本地变量表等。  -->
	<attribute name="SourceFile, LineNumberTable, LocalVariableTable">
  		<patternset>
    		<include name="com.ewa.pipe.**"/>
  		</patternset>	
	</attribute>
	<!-- shrink 用于缩短代码装备。 
		1.logfile  shrink进程的日志文件
		2.在shrink进程中,假如有过错代码,代码将会被替换为: throw new InternalError("Badly shrinked")。
		比方:当某些类的private特点被删去,可是public办法中有引证该特点,而特点被删去了,即会输出该反常过错。
	-->
	<shrink logfile="${project.build.directory}/yshrink.log.xml" createStubs="true">
		<!-- shrink中的keep和rename中的keep一致。 -->
        <keep>			
            <method name="void main(java.lang.String[])" class="${mainclass}" />
        </keep>
    </shrink>
    <!-- 用于自界说某些装备和特点更改。
	    1.mainclass 用于设置主程序发动方位,该文件将不会被混杂。
	    2.logfile 混杂进程中的日志文件保存地址。称号以“.gz”结束,yGuard 将主动创立文件的 gzip 紧缩版别,默许为yguardlog.xml
	    3.conservemanifest 当为false时,重新生成 MANIFEST.MF的内容。默许为false。
	    4.replaceClassNameStrings  是否混杂代码中某些字符串跟类名相关的东西。默许为true
	    比方源码: System.out.print("com.ewa.pipe.dbtransfer.dpl.mapper.BlendMapper");混杂后: System.out.print("com.ewa.pipe.dbtransfer.dpl.A.B");
	    5.scramble 是否随机混杂代码,默许false。假如为true即每次打包生成的类名将随机替换。比方Test.class 第一次混杂为A.class,第二次就为B.class
	    6.annotationClass 某些不必要混杂的数据,比方如下装备为Test注解,当装备到类上时,类中的一切东西不会被混杂;当装备到特点时,特点称号不会被混杂。
	    -->
    <rename 
        mainclass="com.ewa.pipe.dbtransfer.dpl.DplDbtransferApplication"
        logfile="${project.build.directory}/yguard.log.xml"
        conservemanifest = "false"
        replaceClassNameStrings="true"
        scramble = "false"
        annotationClass="com.ewa.pipe.dbtransfer.dpl.Test"
    	>   
        	<!--  -->
        	<keep>
        	</keep>	
		    <!-- 1.error-checking 用于检测过错,检测到过错就失利中止。 -->
	       	<property name="error-checking" value="pedantic"/>
			<!-- 2.error-checking 可用于告知重命名引擎在混杂期间运用不同的命名计划。目前能够将此特点设置为以下值之一(默许small,一般运用small就行了):
			small:将发生非常短的称号,即生成的 jar 文件将尽或许小。
			best:会发生很或许被反编译器和反汇编器误解的称号。运用这种命名计划,在大多数文件系统上甚至不或许成功解紧缩或解紧缩生成的 jar 文件(Windows、Standard Unix、Standard Linux、MacOS)。然而,这种计划占用了很多空间,而且生成的 jar 或许会变大(一般大约是两倍大小)。
			mix:是其他两个值的混合,这会导致合理的小但仍然难以反编译 jar 文件。
			 -->
			 <!-- 其他特点( language-conformity	,overload-enabled,obfuscation-prefix,digests,expose-attributes)请参阅官方文档。 -->
	       	<property name="naming-scheme" value="small"/>	
    </rename>
 </yguard>

keep装备阐明

class元素

class用于在rename和shrink进程中扫除某些类,字段和办法。其是keep的子元素。以下是装备阐明(- 表明会被缩短,即被删去 ):

可见性(是否被缩短) public protected friendly private
none
public *
protected * *
friendly * * *
private * * * *

特点阐明

  1. name 指定要保存的类名。 在shrink中,只会保存类称号,类中的特点和办法都会被删去掉。
  2. classes 坚持类的可见性 :其值是上述:none , public , protected , friendly , private 。默许为none
  3. methods 保存办法的可见性 , 值同classes的描绘。默许为none
  4. fields 保存特点的可见性 , 值同classes的描绘。默许为none
  5. extends 保存对承继了该类的可见性 。1.在shrink中但凡承继了该类的子类都不会被删去。 2.在rename中但凡承继了该类的子类都不会被修正称号。
  6. implements 保存对完成该接口的可见性 。1.在shrink中但凡完成该接口的类都不会被删去。 2.在rename中但凡完成该接口的类都不会被修正称号。

留意事项

  1. 以上特点能够独自运用,一能够混合运用。其 extends/implements 能够和classes, methods,fields混合运用。参阅列2阐明。

列1:

    <shrink logfile="${project.build.directory}/yshrink.log.xml">
       <keep>
            <!-- 保存NameTest类不被删去,可是内部的办法和会特点会被删去,不管私有还是共有。 -->
            <class name="com.arm.code.mix.base.NameTest"/>
			<!-- 保存一切共用的类,办法和特点。其关联的类,办法和特点会被保存,不会被删去  -->
       		<class classes="public" methods="public" fields="public"/>
			<!-- 保存一切承继了BaseClass的类不被删去,可是内部的办法和会特点会被删去,不管私有还是共有。  -->
			<class extends="com.arm.code.mix.base.BaseClass"/>
       </keep>
    </shrink>

列2:

    <shrink logfile="${project.build.directory}/yshrink.log.xml">
       <keep>
            <!-- 保存NameTest类不被删去,并保存其private等级的办法和特点 -->
            <class name="com.arm.code.mix.base.NameTest" methods="private" fields="private"/>
			<!-- 保存一切承继了BaseClass的类不被删去,并保存其private等级的办法和特点  -->
			<class extends="com.arm.code.mix.base.BaseClass" methods="private" fields="private"/>
       </keep>
    </shrink>

列3:

一下举列几个形式集的列子,形式集能够参阅ant。
<!--  include shrink:不需求被删去的类,保存的类。rename:不需求被混杂的类名 -->
<class>
  <patternset>
    <include name="com.mycompany.**.*Bean"/>
    <exclude name="com.mycompany.secretpackage.*"/>
    <exclude name="com.mycompany.myapp.SecretBean"/>
	<!-- 由于 Ant'$'用作转义字符,因而假如您想将一个作为参数传递给使命,则有必要运用两个接连的'$'s( )。'$$'-->
	<exclude name="org.w3c.sax?.**.*$$*"/> 
  </patternset>
</class>
method

method 用于在rename和shrink进程中扫除办法。其是keep的子元素。以下是装备阐明(- 表明会被缩短,即被删去 ):

<!-- 这将保存MyClass类的main和foo办法。此外,一切readObject和writeObject办法(用于序列化)都将保存在com.mycompany.myapp.data包的一切类中。
	请留意,您有必要指定回来参数的类型,即使它是 void,而且您有必要为一切类运用完全限制称号,即使是java.lang package. -->
<method class="com.mycompany.myapp.MyClass"
  name="void main(java.lang.String[])"/>
<method class="com.mycompany.myapp.MyClass"
  name="int foo(double[][], java.lang.Object)"/>
<method name="void writeObject(java.io.ObjectOutputStream)">
  <patternset>
    <include name="com.mycompany.myapp.data.*"/>
  </patternset>
</method>
<method name="void readObject(java.io.ObjectInputStream)">
  <patternset>
    <include name="com.mycompany.myapp.data.*"/>
  </patternset>
</method>
field

field 您能够按称号指定应从缩短或称号混杂中要保存的字段

<!-- 保存MyClass类中的一切字段。
	此外,一切serialVersionUID字段(用于序列化)都将保存在com.mycompany.myapp.data包的一切类中。 -->
<field class="com.mycompany.myapp.MyClass" name="field"/>
<field name="serialVersionUID">
  <patternset>
    <include name="com.mycompany.myapp.data.*"/>
  </patternset>
</field>
package

package 用于从重命名进程中扫除某些包的称号。它不能用于缩短(shrink)进程 。这对类、办法或字段称号没有影响。

    <package>
      <patternset>
		<!-- com.mycompany.myapp不被混杂。myapp下的包名还是会被混杂 -->
        <include name="com.mycompany.myapp.*"/>
		<!-- com.mycompany.myapp不被混杂。myapp下的包名也不会被混杂 -->
		<include name="com.mycompany.myapp.**"/>
      </patternset>
    </package>

3.几种情况下的运用办法

springboot项目

1.留意事项

  1. yguard插件履行要放在 spring boot打包项目之前,由于反置的话,会形成jar中的springboot的发动相关类被混杂,而形成发动项目失利。

2.项目运用失利的问题搜集总结

  1. 本地打包之后发动项目失利:由于是本地idea将jdk设置成jdk17了,导致打包失利。 设置为jdk8后成功发动。
  2. 项目运用mybaties plus,项目里只有一个接口:public interface TimePullLogMapper extends BaseMapper{} , 形成混杂后打包报错:spring至少一个bean完成。后边加上: 后正常。==
  3. service的接口和完成都要露出,否则spring的注入和nacos的服务发现都会存在问题。

3.装备模版

<keep>
                                            <!--包名不混杂装备-->
                                            <package>
                                                <patternset>
                                                    <include name="com.arm.oceansearch.**"/>
                                                </patternset>
                                            </package>
                                            <!--mybaites 相关的mapper混杂后,会形成boot项目发动失利 -->
                                            <class implements="com.arm.boot.core.base.BaseMapper"/>
                                            <!--mybaites默许生成sql时是运用的实体类的类名,所以不能混杂-->
                                            <class implements="com.arm.oceansearch.entity.BaseEntity"/>
                                            <!-- 本包的controller混杂后,无法读取mapping映射,原因不知道。-->
                                            <class>
                                                <patternset>
                                                    <include name="com.arm.oceansearch.controller.*"/>
                                                </patternset>
                                            </class>
                                            <!-- service的接口和完成都要露出,否则spring的注入和nacos的服务发现都会存在问题。 -->
                                            <class>
                                                <patternset>
                                                    <include name="com.arm.oceansearch.service.**"/>
                                                </patternset>
                                            </class>
                                            <!--main办法装备-->
                                            <method name="void main(java.lang.String[])"
                                                    class="com.arm.oceansearch.OceanSearchApplication"/>
                                        </keep>

简介

ProGuard 是一个开源的 Java 类文件缩短器、优化器、混杂器和预验证器。因而,ProGuard 处理的应用程序和库更小、更快,而且在必定程度上能够抵挡逆向工程。

  • 缩短进程检测并删去未运用的类、字段、办法和特点。
  • 优化器 进程优化字节码并删去未运用的指令。
  • 混杂进程运用简短无意义的称号重命名剩余的类、字段和办法。
  • 最后的预验证进程将预验证信息增加到类中,这是 Java Micro Edition 和 Java 6 及更高版别所必需的。

对反射的处理

反射和内省关于任何代码的主动处理都存在特殊的问题。在 ProGuard 中,代码中动态创立或调用(即按称号)的类或类成员也有必要指定为进口点。例如,Class.forName()构造能够在运转时引证任何类。一般不或许核算有必要保存哪些类(运用它们的原始称号),由于类名或许是从装备文件中读取的,例如。因而,您有必要在 ProGuard 装备中指定它们,同样简略-keep选项

  • Class.forName("SomeClass")
  • SomeClass.class
  • SomeClass.class.getField("someField")
  • SomeClass.class.getDeclaredField("someField")
  • SomeClass.class.getMethod("someMethod", null)
  • SomeClass.class.getMethod("someMethod", new Class[] { A.class,... })
  • SomeClass.class.getDeclaredMethod("someMethod", null)
  • SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class,... })
  • AtomicIntegerFieldUpdater.newUpdater(SomeClass.class, "someField")
  • AtomicLongFieldUpdater.newUpdater(SomeClass.class, "someField")
  • AtomicReferenceFieldUpdater.newUpdater(SomeClass.class, SomeType.class, "someField")

支撑

  1. 可独自运用。首要,下载一个ProGuard 版别或者构建 ProGuard从源头。然后能够经过调用目录中的脚本直接从命令行履行 ProGuardbin
    linux/mac:bin/proguard.sh -injars path/to/my-application.jar \ -outjars path/to/obfuscated-application.jar \ -libraryjars path/to/java/home/lib/rt.jar
    windows:bin\proguard.bat -injars path/to/my-applicati^ -outjars path/to/obfuscated-application.jar ^ -libraryjars path/to/java/home/lib/rt.jar
  2. Gradle 形式
  3. ant形式
  4. Maven形式:(没有正式供给 maven 集成,也无法供给支撑,但有可用的解决计划,但 Guardsquare 不保证它们供给的功用。)来源完成:
    github.com/wvengen/pro…
    github.com/dingxin/pro…

过错解析

  1. [proguard] Error: The input doesn’t contain any classes. Did you specify the proper ‘-injars’ options?
处理:<inFilter>com/ewa/pipe/**</inFilter>, inFilter标签设置为包途径地址,把‘.’换成‘/’。
injar : 指定target中的一个方针地址:这儿指定编译后的 classes文件夹。  inFilter 指定的是 classes的内部的文件夹(package)地址。
<!-- 加载文件的过滤器,便是你的工程目录了-->
                    <inFilter>com/arm/code/**</inFilter>
                    <!-- 对什么东西进行加载,这儿仅有classes成功,究竟你也不或许对装备文件及JSP混杂吧-->
                    <injar>classes</injar>

以下是一个比如阐明,假如你想更多的有用信息,请检查文档(www.guardsquare.com/manual/conf…)

<configuration>
                    <!-- 是否将生成的PG文件装置部署-->
                    <attach>false</attach>
                    <!-- 是否混杂 -->
                    <obfuscate>true</obfuscate>
                    <!-- 指定生成文件分类 -->
                    <!--<attachArtifactClassifier>pg</attachArtifactClassifier>-->
                    <!-- 加载文件的过滤器,便是你的工程目录了-->
                    <inFilter>com/arm/code/**</inFilter>
                    <!-- 对什么东西进行加载,这儿仅有classes成功,究竟你也不或许对装备文件及JSP混杂吧-->
                    <injar>classes</injar>
                    <!-- 输出目录-->
                    <outputDirectory>${project.build.directory}</outputDirectory>
                    <outjar>${project.build.finalName}.${project.packaging}</outjar>
                    <options>
                        <!-- JDK方针版别1.7-->
                        <option>-target 1.8</option>
                        <!-- 不做缩短(删去注释、未被引证代码)-->
                        <option>-dontshrink</option>
                        <!-- 不做优化(改变代码完成逻辑)-->
                        <option>-dontoptimize</option>
                        <!-- 不疏忽非共用类文件及成员-->
                        <option>-dontskipnonpubliclibraryclasses</option>
                        <option>-dontskipnonpubliclibraryclassmembers</option>
                        <!-- 优化时答应访问并修正有修饰符的类和类的成员 -->
                        <option>-allowaccessmodification</option>
                        <!-- 确定统一的混杂类的成员称号来增加混杂,避免冲突-->
                        <option>-useuniqueclassmembernames</option>
                        <!-- 不混杂一切包名,Spring装备中有很多固定写法的包名-->
                        <option>-keeppackagenames</option>
                        <!-- 不混杂一切特殊的类-->
                        <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod</option>
                        <!-- 不混杂一切的set/get办法,究竟项目中运用的部分第三方结构(例如Shiro)会用到很多的set/get映射-->
                        <option>-keepclassmembers public class * {void set*(***);*** get*();}</option>
                        <!-- 不混杂的SpringBoot类及其间的办法 -->
                        <option>-keep class com.arm.code.mix.base.SpringBoot{ &lt;methods&gt;; }</option>
                        <!-- 不混杂job包下的一切类名,且类中的办法也不混杂-->
                        <!--<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.job.** { &lt;methods&gt;; }</option> -->
                        <!-- 不混杂filter包下的一切类名,这儿首要是对Shiro的路踢人过滤器混杂,对类的特点和办法进行了混杂-->
                        <!--<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.filter.** </option> -->
                        <!-- 不混杂model包中的一切类以及类的特点及办法,实体包,混杂了会导致ORM结构及前端无法识别-->
                        <!--<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.model.** {*;}</option>-->
                        <!-- com.test.prog.util, util包不混杂的类的特点及办法,实体包  -->
                        <!--<option>-keep class com.test.prog.util.finals.Const{ *; }</option>-->
                        <!-- 不混杂凭证包下的一切类名,但对类中的特点、办法进行混杂,原因是Spring装备中用到了这个类名-->
                        <!--<option>-keep class com.test.prog.util.SecCode</option>-->
                        <!--<option>-keep class com.test.prog.util.exception.HihSoftHandlerException</option>-->
                        <!-- 不混杂job包下的一切类名,且类中的办法也不混杂-->
                        <!--<option>-keep class com.test.prog.controller.** { &lt;methods&gt;; }</option>-->
                    </options>
                    <!-- 增加依靠,这儿你能够按你的需求修正,这儿测试只需求一个JRE的Runtime包就行了 -->
                    <libs>
                        <lib>${java.home}/lib/rt.jar</lib>
                        <lib>${java.home}/lib/jce.jar</lib>
                        <!--<lib>${java.home}/lib/security/local_policy.jar</lib>-->
                        <!--<lib>${java.home}/lib/security/US_export_policy.jar</lib>-->
                        <lib>${java.home}/lib/ext/sunjce_provider.jar</lib>
                    </libs>
                </configuration>