需求描述
近期在做《Madou® Mysql Client For Java》这款桌面软件的时候,遇见了一个非常复杂的Maven打包流程(如下图:),
软件源代码模块【madou-database-mysql】在打包时需要把依赖的多个模块的代码和当前项目打到一个jar中
模块代码中使用到IDEA GUI设计器,因此打包时需要javac2优先编译代码
编译的代码需要进行「代码混淆」,支持oO0模式或Il1模式混淆代码
混淆后的代码需要进行Rsa加密&隐藏核心代码
混淆&加密完成的代码需要打包生成Windows(生成.exe文件)和Mac(生成.sh文件)系统的安装包,并自动压缩成相关系统的安装压缩包
实现所需使用的Maven插件
插件名称 | 在此插件作用 |
---|---|
madou-maven-plugin | 二次加密 & 核心代码隐蔽 |
ideauidesigner-maven-plugin | 编译idea gui |
maven-resources-plugin | 拷贝项目资源 |
proguard-maven-plugin | 混淆代码,实现oO0模式混淆 |
maven-dependency-plugin | 拷贝项目依赖的jar包 |
maven-jar-plugin | 打包jar |
launch4j-maven-plugin | 生成window下的exe软件 |
maven-assembly-plugin | 分发生成window和mac平台的压缩包 |
打包方案设计
总计实现思路:在不同maven阶段生成相关结果并存到对应资源目录,最终再压缩。
在资源处理(process-resources )合并依赖模块的class文件到当前模块的class中
在编译阶段(compile)代理gui编译、混淆代码。并把项目模块依赖的jar从本地仓库中拷贝到相关目录
在准备打包(prepare-package)阶段对代码进行二次Rsa混淆 并且 隐藏.class文件
在打包阶段(package),导包生成当前项目的jar、exe、zip、tar.gz等压缩包/安装包
打包实现POM配置
1. 拷贝依赖模块class到当前项目模块中
拷贝到当前项目中来的目的主要是:后续混淆代码一并把依赖模块的代码也一起混淆,增加源码的包含范围。
<!-- 拷贝所有的项目资源到一起,准备混淆 -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-project-class</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>
<!-- 依赖的madou-database-common模块的class文件 -->
<resource>
<directory>${basedir}/../madou-database-common/target/classes</directory>
<excludes>
<exclude>**/document/**</exclude>
</excludes>
</resource>
<!-- 依赖的madou-database-gui模块的class文件 -->
<resource>
<directory>${basedir}/../madou-database-gui/target/classes</directory>
</resource>
<!-- 更多依赖的模块...再此增加即可 -->
</resources>
</configuration>
</execution>
</executions>
</plugin>
2. 编译idea gui
ideauidesigner-maven-plugin插件已经多年未更新,并不支持最新的idea版本,这里本人使用的是自己修改源码后的版本,需要的小伙伴可以评论区给我留言。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>ideauidesigner-maven-plugin</artifactId>
<version>${ideauidesigner_maven_plugin_version_version}</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>javac2</goal>
</goals>
</execution>
</executions>
<configuration>
<fork>true&