Maven WEB 项目使用ProGuard进行混淆,最佳解决方案&详解

本文中介绍的项目使用了SSM框架。

项目包结构:
这里写图片描述

该项目是典型的Maven WEB项目

主要混淆对象 对类的名称、属性、方法名都进行混淆
次要混淆对象 对类的名称不混淆,类的属性、方法名选择性混淆
非混淆对象 不进行混淆,混淆后可能出现异常

Maven 配置(pom.xml)

使用Maven集成的ProGuard插件,混淆配置不用单独建立文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.test</groupId>
    <artifactId>prog</artifactId>
    <packaging>war</packaging>
    <version>hx</version>
    <name>prog Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <mybatis.generator.configurationFile>src/test/resources/mybatisGenerator.xml</mybatis.generator.configurationFile>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>com.googlecode.sli4j</groupId>
            <artifactId>sli4j-slf4j-log4j</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>2.6.5</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>3.2.4.RELEASE</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <!-- 阿里巴巴数据源包 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.8</version>
        </dependency>
        <dependency>
            <groupId>google</groupId>
            <artifactId>google-connections</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>
        <!-- cxf.jar -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>2.7.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache</groupId>
            <artifactId>neethi</artifactId>
            <version>3.0.2</version>
        </dependency>
        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
            <version>1.6.3</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.ws</groupId>
            <artifactId>commons.schema</artifactId>
            <version>2.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.ctc</groupId>
            <artifactId>wstx</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus</groupId>
            <artifactId>stax2</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>3.2.5.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.7.4</version>
        </dependency>
        <!-- mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.12</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.jtds</groupId>
            <artifactId>jtds</artifactId>
            <version>1.3.0</version> 
        </dependency>
        <!-- <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc14</artifactId>
            <version>10.2.0.1.0</version>
        </dependency> -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
            <!--  <scope>compile</scope>-->
        </dependency>

        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.clerezza.ext</groupId>
            <artifactId>org.json.simple</artifactId>
            <version>0.3-incubating</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.41</version>
        </dependency>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6</version>
        </dependency>
        <!--二维码-->
        <dependency> 
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.0.1</version>
        </dependency>
        <!--缩略图-->
        <dependency>
            <groupId>net.coobird</groupId> 
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>3.2.5.RELEASE</version>
        </dependency>
         <dependency>
            <groupId>org.unitils</groupId>
            <artifactId>unitils-core</artifactId>
            <version>3.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.unitils</groupId>
            <artifactId>unitils-database</artifactId>
            <version>3.1</version>
            <scope>test</scope>
        </dependency> 
        <dependency>
            <groupId>org.unitils</groupId>
            <artifactId>unitils-dbmaintainer</artifactId>
            <version>3.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.unitils</groupId>
            <artifactId>unitils-dbunit</artifactId>
            <version>3.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.unitils</groupId>
            <artifactId>unitils-spring</artifactId>
            <version>3.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.unitils</groupId>
            <artifactId>unitils-orm</artifactId>
            <version>3.1</version>
            <scope>test</scope>
        </dependency> 
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk14</artifactId>
            <version>1.45</version>
        </dependency>
        <dependency>
            <groupId>sun.misc</groupId>
            <artifactId>BASE64Decoder</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>1.8.5</version>
        </dependency>  
    </dependencies>
    <build>
        <!--  <pluginManagement> -->
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.1</version>
                <configuration>
                    <overwrite>false</overwrite>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <uriEncoding>utf-8</uriEncoding>
                    <port>8888</port>
                    <path>/</path>
                    <contextReloadable>false</contextReloadable>
                    <useTestClasspath>false</useTestClasspath>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>tomcat-maven-plugin</artifactId>
                <version>1.1</version>
                <configuration>
                    <url>http://192.168.200.121:8080/manager/text</url>
                    <username>tomcat</username>
                    <password>password</password>
                    <path>/prog11</path>
                </configuration>
            </plugin>

            <!-- ProGuard混淆插件-->
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>2.0.11</version>
                <executions>
                    <execution>
                        <!-- 混淆时刻,这里是打包的时候混淆-->
                        <phase>package</phase>
                        <goals>
                            <!-- 使用插件的什么功能,当然是混淆-->
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!-- 是否将生成的PG文件安装部署-->
                    <attach>true</attach>
                    <!-- 是否混淆-->
                    <obfuscate>true</obfuscate>
                    <!-- 指定生成文件分类 -->
                    <attachArtifactClassifier>pg</attachArtifactClassifier>
                    <options>
                        <!-- JDK目标版本1.7-->
                        <option>-target 1.7</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>

                        <!-- 不混淆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>
                    <outjar>${project.build.finalName}-pg.jar</outjar>
                    <!-- 添加依赖,这里你可以按你的需要修改,这里测试只需要一个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>
                    <!-- 加载文件的过滤器,就是你的工程目录了-->
                    <inFilter>com/test/prog/**</inFilter>
                    <!-- 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧-->
                    <injar>classes</injar>
                    <!-- 输出目录-->
                    <outputDirectory>${project.build.directory}</outputDirectory>
                </configuration>
            </plugin>
        </plugins>
        <!--   </pluginManagement>   -->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <excludes>
                    <exclude>**/*.java</exclude>
                    <exclude>**/.svn/*</exclude>
                </excludes>
            </resource>
        </resources>
    </build>
</project>

在项目location执行命令

mvn clean package -DskipTests -X

执行命令后,会在target下生成以下文件:
这里写图片描述

  • classes-pg.jar 混淆后的classes文件,里面包含完整的项目结构
  • proguard_map.txt 混淆内容的映射
  • proguard_seed.txt 参与混淆的类
    混淆完成后,将classes-pg.jar解压到应用服务器覆盖原有的classes文件,通常目录为

E:\tomcat7\webapps\项目名\WEB-INF\classes

运行服务,项目运行成功
查看目录下面文件(下面是包括包名的混淆)

这里写图片描述

通过反编译工具查看混淆代码

这里写图片描述

可以看出,混淆成功了!

下面是测试中遇到的部分问题及相关的解决方式:

这里写图片描述

解析:-target 1.7 jdk目标版本的问题

这里写图片描述

解析:-dontskipnonpubliclibraryclasses 不路过非公用类文件及成员

这里写图片描述

解析:-dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers 不路过非公用类文件及成员造成的bug

这里写图片描述

解析:-dontoptimize 变更代码逻辑引起的bug

还有一些其他的关于项目不能混淆的bug,这个需要根据项目而定。

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页