- A+
背景
本篇文章记录下如何使用Maven插件将核心代码包和依赖包分离的方法,最近在公司业务代码的加密工作,使用加密工具针对SpringBoot工程代码进行加密的时候,发现各种报错。无法进行加密,询问了开发加密客户端的同学,反馈说应用程序依赖包太多,导致打包失败,要求去除所依赖的包,只对“核心代码”进行加密,所以就有了本篇文章。
这里分两种方案进行实现,其实就是基于Maven插件的配置实现
- Maven打包后出现两个jar文件,一个是包含核心代码的jar包,一个是包含依赖包以及核心代码的jar包。
- Maven打包后只有一个jar文件,该jar文件只包含核心代码,应用所有依赖包都将导出到本地lib目录下。
我们先看下演示项目目录,如下图:
可以看到,这是一个很简单的SpirngBoot工程
第一种方案
先来演示配置maven插件最终打包生成两个jar文件,maven配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mengxi</groupId>
<artifactId>maven-plugin-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>maven-plugin-test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<encoding>UTF-8</encoding>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<version>3.3</version>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<encoding>UTF-8</encoding><!-- 指定编码格式,否则在DOS下运行mvn命令时当发生文件资源copy时将使用系统默认使用GBK编码 -->
</configuration>
</plugin>
</plugins>
</build>
</project>
通过上述pom可以看出,这里的dependency只有简单的spring-boot-starter-web、mysql-connector-java、lombok、spring-boot-starter-test 四个依赖,通过上述pom打包完成会产生两个Jar文件,如下图
maven-plugin-test-0.0.1-SNAPSHOT.jar ---> 核心代码文件,我们可以通过反编译工具具体查看下这个文件,如果需要下载反编译工具可参考反编译工具下载
可以看出来,这个jar文件并没有依赖包
接下来,我们再来看maven-plugin-test-0.0.1-SNAPSHOT-jar-with-dependencies.jar,如下图,红圈圈住的地方就是引用的依赖包。
使用上述pom文件,打包可以实现核心代码与依赖文件分离。
第二种方案
这种方案其实就是打一个核心代码的jar,然后把该jar所依赖的文件,通过maven插件落地到本地文件夹中,然后通过修改META-INF.MANIFEST.MF文件,在访问的时候可以通过Class-Path去加载依赖包。
老套路,先上pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mengxi</groupId>
<artifactId>maven-plugin-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>maven-plugin-test</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/mysql-connector-java-5.1.46.jar</systemPath>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 指定启动类,将依赖打成外部jar包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<!-- 添加classpath缺少的内容-->
<manifestEntries>
<Class-Path>lib/mysql-connector-java-5.1.46.jar
</Class-Path>
</manifestEntries>
<!-- 生成的jar中,不要包含pom.xml和pom.properties这两个文件 -->
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<!-- 是否要把第三方jar加入到类构建路径 -->
<addClasspath>true</addClasspath>
<!-- 外部依赖jar包的最终位置 -->
<classpathPrefix>lib/</classpathPrefix>
<!-- 项目启动类 -->
<mainClass>com.mengxi.maven.plugin.test.MavenPluginTestApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!--拷贝依赖到jar外面的lib目录-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-lib</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>target/lib</outputDirectory>
<excludeTransitive>false</excludeTransitive>
<stripVersion>false</stripVersion>
<includeScope>compile</includeScope>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
通过pom文件,看到利用maven-jar-plugin插件,将依赖包导出到target/lib目录中,这里需要指定下主方法,最终输出的jar文件是没有依赖的,可以将lib目录上传到服务器上,与当前jar文件同级目录即可,使用java -jar maven-plugin-test-0.0.1-SHAPSHOT.jar 运行。
使用如下命令进行打包
mvn clean package -Dmaven.test.skip=true
如上图,最终将依赖包输出到lib目录下,并且输出无依赖的jar文件 maven-plugin-test-0.0.1-SNAPSHOT.jar
再来使用反编译工具验证一下 maven-plugin-test-0.0.1-SNAPSHOT.jar 文件
如上图,已经标记的很清楚了,最终把没有依赖的jar文件和lib文件夹丢到服务器上,直接运行就可以了,如果下次在没有修改依赖文件的情况下,我们只需要更新核心代码的jar文件就可以了,这样jar文件也变得很轻量级。
- 我的微信
- 加好友一起交流!
-
- 微信公众号
- 关注公众号获取分享资源!
-