使用idfc-proguard-maven-plugin混淆优化Jave Web工程二

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 上篇文章说了下大致流程和我们要达到的效果。本文主要讲一下详细配置。 其实只要弄过一次,就觉得很简单了。只需要配置两个文件。 pom.xml和${project.artifactId}-maven.pro 这两个文件即可。


上篇文章说了下大致流程和我们要达到的效果。本文主要讲一下详细配置。

其实只要弄过一次,就觉得很简单了。只需要配置两个文件。

pom.xml和${project.artifactId}-maven.pro 这两个文件即可。 其中pom.xml配置插件的使用,真正的优化选项 在${project.artifactId}-maven.pro  文件里配置。

先来看一下完整的pom.xml。

<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>Struts2Spring4Hibernate4XML</groupId>
  <artifactId>Struts2Spring4Hibernate4XML</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Struts2Spring4Hibernate4</name>
	<description>Integration of Struts 2, Spring 4 and Hibernate 4 frameworks</description>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java-version>1.8</java-version>
		<org.springframework-version>4.1.4.RELEASE</org.springframework-version>
		<org.strutsframework-version>2.3.20</org.strutsframework-version>
		<org.hibernateframework-version>4.3.8.Final</org.hibernateframework-version>
		<org.mysqlconnector-version>5.1.34</org.mysqlconnector-version>
	</properties>

	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${org.springframework-version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>

		<!-- Struts -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>${org.strutsframework-version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-spring-plugin</artifactId>
			<version>${org.strutsframework-version}</version>
		</dependency>

		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${org.hibernateframework-version}</version>
		</dependency>

		<!-- Apache Commons DBCP -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-dbcp2</artifactId>
			<version>2.0</version>
		</dependency>

		<!-- MySQL Connector-Java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${org.mysqlconnector-version}</version>
		</dependency>
		
		<!-- jstl -->
		<dependency> 
			<groupId>jstl</groupId> 
			<artifactId>jstl</artifactId> 
			<version>1.2</version> 
		</dependency> 

		<dependency> 
			<groupId>taglibs</groupId> 
			<artifactId>standard</artifactId> 
			<version>1.1.2</version> 
		</dependency>

	</dependencies>

	<build>
		<sourceDirectory>src</sourceDirectory>
		<finalName>abc</finalName>
		<resources>
			<resource>
				<!--打包时排除资源文件-->
				<directory>resources</directory>
				<excludes>
					<exclude>*.*</exclude>
				</excludes>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.4</version>
				<configuration>
					<warSourceDirectory>WebContent</warSourceDirectory>
					<failOnMissingWebXml>false</failOnMissingWebXml>
					<packagingExcludes>WEB-INF/lib/${project.artifactId}-${version}.jar</packagingExcludes>
					<!--将类文件打成jar包-->
					<archiveClasses>true</archiveClasses>
					<!--将资源文件打到classes目录下-->
					<webResources>
						<resource>
							<directory>resources</directory>
							<targetPath>WEB-INF/classes</targetPath>
							<filtering>true</filtering>
						</resource>
					</webResources>
				</configuration>
			</plugin>
			<!-- BEGIN OBFUSCATE -->
			<plugin>
				<groupId>com.idfconnect.devtools</groupId>
				<artifactId>idfc-proguard-maven-plugin</artifactId>
				<version>1.0.1</version>
				<executions>
					<execution>
						<phase>prepare-package</phase>
						<goals>
							<goal>obfuscate</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<options>
						<repackageclasses>com.idfconnect.sample.obfuscated</repackageclasses>
					</options>
					<inputFile>${project.build.outputDirectory}</inputFile>
					<inputFileFilter>**.class</inputFileFilter>
					<outputArtifacts>
						<outputArtifact>
							<file>${project.build.finalName}/WEB-INF/lib/${project.build.finalName}.jar</file>
							<type>jar</type>
						</outputArtifact>
					</outputArtifacts>
					<libraryArtifacts>
						<libraryArtifact>junit:junit:4.11</libraryArtifact>
					</libraryArtifacts>
					<libraryJarPaths>
						<libraryJarPath>${java.home}/lib/jsse.jar</libraryJarPath>
					</libraryJarPaths>
						<proguardIncludeFile>${basedir}/resources/${project.artifactId}-maven.pro</proguardIncludeFile>
				</configuration>
				<dependencies>
					<dependency>
						<groupId>net.sf.proguard</groupId>
						<artifactId>proguard-base</artifactId>
						<version>5.0</version>
					</dependency>
				</dependencies>
			</plugin>
				
			<!-- END OBFUSCATE -->
		</plugins>
	</build>
</project>


pom.xml里配置三个插件如上所示:

1.maven-compiler-plugin: 就是配置一下项目用到的编译器版本,没什么好说的。

2.idfc-proguard-maven-plugin: 就是proguard在maven下的一个插件。注意,这个插件只能混淆.class文件。只能生成jar包不能生成war包。就是说我们只能先把.class文件混淆优化后打成一个jar包,然后利用maven-war-plugin插件将项目打成一个war包。 所以execution里的<phase>要配置成prepare-package而不是package。<outputArtifact>里要配置输出的文件类型是jar包。prepare-package 在真正的打包之前,执行一些准备打包必要的操作,这里就是做混淆优化处理。注意<inputFileFilter>是过滤出哪些文件打包到jar包里。此时我们的项目里.hbm.xml是放在resources文件夹下的。我们希望生成的 jar包里只有.class文件里。资源文件都在WEB-INF/classes下同级目录里。 所以这里配置成**.class。表示任意包下的所有.class文件都打包进jar包里。 如果.hbm.xml文件和Java文件在一个地方。这里就不能配置inputFileFilter为**.class了。

注意我们要用<proguardIncludeFile>${basedir}/resources/${project.artifactId}-maven.pro</proguardIncludeFile>指出优化选项文件所在的位置。 它有默认的位置,但是我们的maven文件结构是精简后的,所以需要明确指出。

我们这个项目的artifactId 是

<artifactId>Struts2Spring4Hibernate4XML</artifactId>

所以${project.artifactId}-maven.pro 就是Struts2Spring4Hibernate4XML-maven.pro。 当然也可以改成其他名字,这里这样写是防止项目的artifactId改名字了。

<inputFile> :输入文件,表示哪个路径下的.class文件要被混淆优化,就是maven编译后的输出路径。

<libraryArtifact>: generate additional injars input entries to ProGuard from the project artifacts.(我的理解是通过artifactId的方式指出需要加入混淆的jar包)

<InputJarPaths>: Additional external (e.g. non-artifact) input to include to Proguard as injars parameters (我的理解是通过指定路径的方式指出需要加入混淆的jar包)

这个插件的相关配置选项请看官网的说明: http://mavenproguard.sourceforge.net/obfuscate-mojo.html


3.maven-war-plugin: 下面的这几个配置至关重要。

<packagingExcludes>WEB-INF/lib/${project.artifactId}-${version}.jar</packagingExcludes>
指定打war包时排除的某些jar包。

将我们的.class文件打成一个jar包。

<archiveClasses>true</archiveClasses>

将资源文件放在WEB-INF/classes目录下。

<webResources>
	</span><resource>
		</span><directory>resources</directory>
		</span><targetPath>WEB-INF/classes</targetPath>
		</span><filtering>true</filtering>
	</span></resource>
</webResources>


打jar包时,忽略掉resources文件夹下的所有文件。 这个是为了实现jar包里只有.class文件。配置文件都在WEB-INF/class下的同级目录里。

<sourceDirectory>src</sourceDirectory>
<finalName>abc</finalName>
<resources>
	<resource>
		</span><!--打包时排除资源文件-->
		</span><directory>resources</directory>
		</span><excludes>
			</span><exclude>*.*</exclude>
		</span></excludes>
	</resource>
</resources>

但是为什么要排除掉WEB-INF/lib/${project.artifactId}-${version}.jar 这个jar包呢? idfc-proguard-maven-plugin已经为我们生成了一个abc.jar了,为什么还要在maven-war-plugin里设置archiveClasses为true呢?


如果不设置这些,我们看看是什么效果:



看到没有,如果不设置archiveClasses为true. maven只会把混淆前的文件直接部署到WEB-INF/classes目录下。但是lib里已经有一个abc.jar了。abc.jar就是混淆后的.class文件。这跟WEB-INF/classes下的.class文件重复了。


注意,注意,如果没有配置archiveClasses为true。maven只会把编译后的文件部署到WEB-INF/classes目录下,不会生成Struts2Spring4Hibernate4XML-0.0.1-SNAPSHOT.jar 这个jar包。 上图中之所以会出现,应该是我没有maven update,clean的原因。 我在这里卡了很长时间。 所以强烈建议大家。每改一次 pom.xml就maven >> update project一下,然后 project >> clean.  每次mvn clean, mvn package要 刷新下项目。 切记,这些操作看似烦人,但是不能省。我就是因为这个原因,结果第二天重启机器再次尝试时才发现的。我以为自己固态硬盘,速度快,反复读写也不会有事,事实上并不是这样。反编译工具jd-gui最好每次用完就关闭,然后重新打开。 不要嫌麻烦,嫌慢。 慢是机器的原因,我就是受不了自己的笔记本速度慢,才买了个台式机的。


所以我们要设置archiveClasses为true。这样就会把混淆优化前的.class文件打成一个jar包(Struts2Spring4Hibernate4XML-0.0.1-SNAPSHOT.jar), 而不是把这些.class文件部署到WEB-INF/classes目录下。


但是lib里已经有一个abc.jar了。所以我们要配置packagingExcludes把Struts2Spring4Hibernate4XML-0.0.1-SNAPSHOT.jar这个Jar包排除掉,因为我们只需要一个混淆后的abc.jar就行了。


可能说的比较啰嗦,小结上面的一小段话: 配置<archiveClasses>true</archiveClasses>就是不让WEB-INF/classes下出现未经过混淆优化的.class文件。配置 packagingExcludes是为了把Struts2Spring4Hibernate4XML-0.0.1-SNAPSHOT.jar这个jar包排除掉。因为我们只需要经过混淆优化后的文件abc.jar 就行了。

最终的效果就是这样的:



pom.xml里说的差不多了,下面就说说我们的优化配置文件 .pro文件

#保留调试信息(异常信息源码行数)
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
#混淆时不要形成混合大小写类名
-dontusemixedcaseclassnames
#保留调试级别的属性
#-keepparameternames

# 保留注解信息,签名信息,异常信息,内部类信息

-keepattributes *Annotation*,Signature,Exceptions,InnerClasses
#指定混淆时方法和属性名替换字典文件
#-obfuscationdictionary shakespeare.txt


#-keep class net.codejava.framework.action.**{*;}
#-keep class net.codejava.framework.dao.**{*;}
#-keep class net.codejava.framework.model.**{*;}

-keep public class * {
    public protected *;
}

-keepnames class net.codejava.framework.action.**{
	<fields>;
	<methods>;
}

-keepnames class net.codejava.framework.dao.**{
	<fields>;
	<methods>;
}

-keepnames class net.codejava.framework.model.**{
	<fields>;
	<methods>;
}

#保留枚举类方法
-keepclassmembers,allowoptimization enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
#保留所有实现序列化的类的素有属性
-keepclassmembers class * implements java.io.Serializable {
   private <fields>;
}



-printusage aaa.txt
#优化时允许访问并修改有修饰符的类和类的成员
-allowaccessmodification 
#混淆时应用侵入式重载   
-overloadaggressively
#确定统一的混淆类的成员名称来增加混淆   
-useuniqueclassmembernames 


这里每一句上都有注释,比较简单。 我就说下注意点: keepnames和keepattributes


names:就是我们熟知的方法名,field名等。

attritutes:我的理解就是文件的 描 述 性 属性。 官方解释在这里:http://proguard.sourceforge.net/manual/attributes.html 


keepattributes,官网里有说明,一般都加上的。 如何配置.pro文件,请参考官网文档: http://proguard.sourceforge.net/

keepnames表示哪些name不需要改名字。 这个根据你的需求决定要不要保留原有的名称。


有些字段,比如action里的userService属性。JSP里EL表达式引用的一些字段。  它们的名字被改掉时, 只要getter和setter没有变。就可以保证代码的正确运行。

一定要注意,这些名称跟xml文件或者jsp页面有互动。所以优化它们时要特别小心。


下面举个例子,看看优化效果到底如何。这是我故意加的垃圾代码:



私有变量和方法都被优化掉了。






看方法cde里。变量j直接用立即数来替换了,方法里的参数名也被换掉了。 注意因为配置了-keepnames class net.codejava.framework.action.**{
<fields>;
<methods>;
}

所以action里的变量名没有被混淆成a,b,c...。




总结:

现在混淆和优化的程度取决于你对.pro文件配置的理解程度。 多动手写一些垃圾代码试一试,看看到底能优化到什么程度,别忘了经常update,clean,refresh。

这个配置理解起来比较简单,主要是多尝试。 个人觉得难点就是 打war包的时候会有些小麻烦。网上关于这个的文章比较少,说的也不清楚。总结了一下个人经验,希望对你有帮助。希望你能成为一个会精简maven项目文件结构,会做混淆优化的猿儿而不只是编码。


demo1地址(.java,.hbm.xml在一块儿): http://download.csdn.net/detail/ahau10/9500953

demo2地址(.java,.hbm.xml不在一块儿): http://download.csdn.net/detail/ahau10/9500960

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
Web App开发 前端开发 JavaScript
探索Python科学计算的边界:利用Selenium进行Web应用性能测试与优化
【10月更文挑战第6天】随着互联网技术的发展,Web应用程序已经成为人们日常生活和工作中不可或缺的一部分。这些应用不仅需要提供丰富的功能,还必须具备良好的性能表现以保证用户体验。性能测试是确保Web应用能够快速响应用户请求并处理大量并发访问的关键步骤之一。本文将探讨如何使用Python结合Selenium来进行Web应用的性能测试,并通过实际代码示例展示如何识别瓶颈及优化应用。
127 5
|
2月前
|
机器学习/深度学习 缓存 监控
利用机器学习优化Web性能和用户体验
【10月更文挑战第16天】本文探讨了如何利用机器学习技术优化Web性能和用户体验。通过分析用户行为和性能数据,机器学习可以实现动态资源优化、预测性缓存、性能瓶颈检测和自适应用户体验。文章还介绍了实施步骤和实战技巧,帮助开发者更有效地提升Web应用的速度和用户满意度。
|
23天前
|
Java 持续交付 项目管理
使用Maven进行项目管理:提高Java Web开发的效率
Maven 是一款强大的项目管理和构建自动化工具,广泛应用于Java社区。它通过依赖管理、构建生命周期管理、插件机制和多模块项目支持等功能,简化了项目的构建过程,提高了开发效率。本文将介绍Maven的核心功能及其在Java Web开发中的应用。
51 0
|
2月前
|
SQL 关系型数据库 数据库
优化Web开发流程:Python ORM的优势与实现细节
【10月更文挑战第4天】在Web开发中,数据库操作至关重要,但直接编写SQL语句既繁琐又易错。对象关系映射(ORM)技术应运而生,让开发者以面向对象的方式操作数据库,显著提升了开发效率和代码可维护性。本文探讨Python ORM的优势及其实现细节,并通过Django ORM的示例展示其应用。ORM提供高级抽象层,简化数据库操作,提高代码可读性,并支持多种数据库后端,防止SQL注入。Django内置强大的ORM系统,通过定义模型、生成数据库表、插入和查询数据等步骤,展示了如何利用ORM简化复杂的数据库操作。
61 6
|
2月前
|
缓存 前端开发 JavaScript
探索现代Web开发中的前端性能优化策略
【10月更文挑战第5天】探索现代Web开发中的前端性能优化策略
|
2月前
|
缓存 前端开发 JavaScript
构建高性能Web应用:优化前端性能的策略
构建高性能Web应用:优化前端性能的策略
|
3月前
|
数据库 开发者 Python
实战指南:用Python协程与异步函数优化高性能Web应用
在快速发展的Web开发领域,高性能与高效响应是衡量应用质量的重要标准。随着Python在Web开发中的广泛应用,如何利用Python的协程(Coroutine)与异步函数(Async Functions)特性来优化Web应用的性能,成为了许多开发者关注的焦点。本文将从实战角度出发,通过具体案例展示如何运用这些技术来提升Web应用的响应速度和吞吐量。
30 1
|
3月前
|
网络协议 Windows
[收藏]优化基于Win 2000系统的Web服务器性能
[收藏]优化基于Win 2000系统的Web服务器性能
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
126 3
|
28天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
139 45

推荐镜像

更多