前言
上一章,我们介绍了Maven内的常见插件.Maven的主要作用是用于包的管理和依赖.其次,根据Maven的生命周期可以知道, 它还可以作为一个运维和打包、部署的工具而存在.
本章我们将详细的介绍Maven打包以及打包的各种情况.
PS: 本文所用的Maven例子可以在我的Github仓库内找到
https://github.com/SeanYanxml/maven-train
Jar包
所谓Jar包
,其实就是Java文件的压缩包.我们在整理文件的时候,经常会将其压缩为.rar / .zip / .tar / .tar.gz
等待诸如此类的压缩包.其实Jar包
也不例外,它其实就是用于Java程序进行压缩发布的一种格式包.
- Eclipse打包
经常使用Eclipse
的朋友们肯定会知道,Eclipse自带了Export
功能,可以将项目导出为Jar
包
如果发布工具包的话,可以选择JAR file
.但是,如果想要发布应用程序,也就是可运行Jar
包的话,我们一般选择Runnable JAR file
.
我们选择可运行Jar包,可以看到下方的几种选项:
- 刨除需要的其他非项目内的
Jar包
; - 将需要的Jar包一起打包;
- 拷贝需要的Jar包一起(一般是
. tar.gz
)
我们分别试验和查看下这2种方式的区别:
localhost:Desktop Sean$ java -jar hello1.jar
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
String is not null.
localhost:Desktop Sean$ java -jar hello2.jar
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
String is not null.
localhost:Desktop Sean$ java -jar hello3.jar
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
String is not null.
从试验的结果来看,三种Jar包
都可以运行.下面我们通过反编译jd-gui.jar
程序依次查看下我们打的三种包的不同
-
第一种 压成一个Jar包
可以看到,所有的程序.包括依赖的common-lang3.jar
内的所有内容,包括Maven
的pom.xml
文件都被压在了一起.
这种做法适合,小型工具类发布,依赖的Jar包较少切Jar包冲突
较少的情况. -
第二种 Jar包内包含Jar包
由上图可以看到,我们hello2.jar
Jar包内还包含了Jar包
.并且,Manifest.mf
文件要加载common-lang.jar
jar包 -
第三种 依赖Jar包另外存储
这种方法适用于,迭代发布时,Jar包经常会出现冲突的问题.但是这个的依赖位置基本上不能够更改.
有时,我们可以手动的去加载这些我们需要的Jar包到运行的classpath
目录下.学习下zookeeper
的Jar包加载脚本
#!/bin/bash
for i in ./lib/*.jar
do
CLASSPATH="$i:$CLASSPATH"
done
MainJar="hello3.jar"
MainClass="com.yanxml.parent.son.HelloMain"
CLASSPATH="$MainJar:$CLASSPATH"
echo "$CLASSPATH"
java -cp "$CLASSPATH" "$MainClass"
java -cp ./lib/commons-lang3-3.7.jar:hello3.jar com.yanxml.parent.son.HelloMain
Maven 插件
相比较而言,前文介绍的插件中
maven-shade-plugin
类比第一种插件打包方式maven-source-plugin
打源码包maven-dependency-plugin
类比第三种打包方式spring-boot-maven-plugin
类比第二种打包方式,但是根据SpringBoot的需求又进行了一定的封装.
当然,我们自动化的过程中是不能用界面进行操作的,于是本章节.我们将使用maven对于这3种方式进行实现.
(注:第二种打包方式略微特殊,需要第三方的启动类,我们举一个使用SpringBoot插件的例子进行替换.(使用FatJar可以实现这样的效果))
- 合并打包(
maven-shade-plugin
)
#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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.yanxml</groupId>
<artifactId>maven-train-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>maven-train-parent-son</artifactId>
<dependencies>
<!-- dependency -->
<dependency>
<groupId>com.yanxml</groupId>
<artifactId>maven-train-parent-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- all in one jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.yanxml.parent.son.HelloMain</Main-Class>
<X-Compile-Source-JDK>1.7</X-Compile-Source-JDK>
<X-Compile-Target-JDK>1.7</X-Compile-Target-JDK>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
注意 因为此父项目的子项目,所以需要在父亲路径运行mvn clean package -pl maven-train-parent-son -am
命令进行打包.打包时可以选择是否将依赖模块重新打包.
localhost:maven-train-parent Sean$ pwd
/Users/Sean/Documents/Gitrep/maven-train/maven-train-parent
localhost:maven-train-parent Sean$ mvn clean package -pl maven-train-parent-son -am
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] maven-train-parent
[INFO] maven-train-parent-util
[INFO] maven-train-parent-son
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-train-parent 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven-train-parent ---
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-train-parent-util 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven-train-parent-util ---
[INFO] Deleting /Users/Sean/Documents/Gitrep/maven-train/maven-train-parent/maven-train-parent-util/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-train-parent-util ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-train-parent-util ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/Sean/Documents/Gitrep/maven-train/maven-train-parent/maven-train-parent-util/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-train-parent-util ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-train-parent-util ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-train-parent-util ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-train-parent-util ---
[INFO] Building jar: /Users/Sean/Documents/Gitrep/maven-train/maven-train-parent/maven-train-parent-util/target/maven-train-parent-util-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-train-parent-son 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven-train-parent-son ---
[INFO] Deleting /Users/Sean/Documents/Gitrep/maven-train/maven-train-parent/maven-train-parent-son/target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-train-parent-son ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-train-parent-son ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /Users/Sean/Documents/Gitrep/maven-train/maven-train-parent/maven-train-parent-son/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-train-parent-son ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-train-parent-son ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-train-parent-son ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-train-parent-son ---
[INFO] Building jar: /Users/Sean/Documents/Gitrep/maven-train/maven-train-parent/maven-train-parent-son/target/maven-train-parent-son-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- maven-shade-plugin:2.4.3:shade (default) @ maven-train-parent-son ---
[INFO] Including com.yanxml:maven-train-parent-util:jar:0.0.1-SNAPSHOT in the shaded jar.
[INFO] Including org.apache.commons:commons-lang3:jar:3.7 in the shaded jar.
[INFO] Replacing original artifact with shaded artifact.
[INFO] Replacing /Users/Sean/Documents/Gitrep/maven-train/maven-train-parent/maven-train-parent-son/target/maven-train-parent-son-0.0.1-SNAPSHOT.jar with /Users/Sean/Documents/Gitrep/maven-train/maven-train-parent/maven-train-parent-son/target/maven-train-parent-son-0.0.1-SNAPSHOT-shaded.jar
[INFO] Dependency-reduced POM written at: /Users/Sean/Documents/Gitrep/maven-train/maven-train-parent/maven-train-parent-son/dependency-reduced-pom.xml
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] maven-train-parent ................................. SUCCESS [ 0.223 s]
[INFO] maven-train-parent-util ............................ SUCCESS [ 1.968 s]
[INFO] maven-train-parent-son ............................. SUCCESS [ 0.671 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.994 s
[INFO] Finished at: 2019-03-13T18:36:12+08:00
[INFO] Final Memory: 20M/172M
[INFO] ------------------------------------------------------------------------
包运行完成后,会放置在/target
子目录内.反编译后,可以看到,和Eclipse打包基本一致.
- 运行包与依赖包分开打包(
maven-dependency-plugin
)
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.yanxml</groupId>
<artifactId>maven-train-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>maven-train-parent-son</artifactId>
<dependencies>
<!-- dependency -->
<dependency>
<groupId>com.yanxml</groupId>
<artifactId>maven-train-parent-util</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>./lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
由上可以看到,我们将源码打入一个包内.所有依赖的包都放置在配置的指定目录下.
但是,我们运行时候,需要特定的脚本将其加载进入classpath
下.
- Jar In Jar(
spring-boot-maven-plugin
)
在本教程的Github上,我们有一个现成的SpringBoot
项目.下面两节,我们使用这个项目,完成下面两节.
#pom.xml
localhost:maven-train-springboot Sean$ mvn package
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.yanxml:maven-train-springboot:jar:1.0
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 55, column 12
[WARNING] 'build.plugins.plugin.version' for org.springframework.boot:spring-boot-maven-plugin is missing. @ line 63, column 12
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building maven-train-springboot 1.0
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for org.apache.logging.log4j:log4j-core:jar:2.7 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-train-springboot ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven-train-springboot ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-train-springboot ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /Users/Sean/Documents/Gitrep/maven-train/maven-train-springboot/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven-train-springboot ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-train-springboot ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-train-springboot ---
[INFO] Building jar: /Users/Sean/Documents/Gitrep/maven-train/maven-train-springboot/target/maven-train-springboot-1.0.jar
[INFO] META-INF/maven/com.yanxml/maven-train-springboot/pom.xml already added, skipping
[INFO] META-INF/maven/com.yanxml/maven-train-springboot/pom.properties already added, skipping
[INFO]
[INFO] --- spring-boot-maven-plugin:1.5.9.RELEASE:repackage (default) @ maven-train-springboot ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.967 s
[INFO] Finished at: 2019-03-13T19:02:21+08:00
[INFO] Final Memory: 17M/226M
[INFO] ------------------------------------------------------------------------
(依赖的Jar包都放在lib文件夹内)通过java -jar maven-train-springboot-1.0.jar
可以将其进行启动.
- 自定义打包(
maven-assembly-plugin
)
### assembly.xml
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3
http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>0.1</id>
<formats>
<format>tar</format>
</formats>
<fileSets>
<fileSet>
<directory>target/classes</directory>
<outputDirectory>/config</outputDirectory>
<fileMode>0755</fileMode>
<includes>
<include>*.properties</include>
<include>*.xml</include>
<include>banner.txt</include>
<include>*.json</include>
</includes>
</fileSet>
<fileSet>
<directory>target/classes/bin</directory>
<outputDirectory>/config/bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>target/lib</directory>
<outputDirectory>/lib</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
</fileSets>
<files>
<file>
<source>target/${package}-1.0.jar</source>
<outputDirectory>/</outputDirectory>
<destName>${package}-${package.version}.jar</destName>
<fileMode>0755</fileMode>
</file>
</files>
</assembly>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>${package}-${package.version}</finalName>
<ignorePermissions>true</ignorePermissions>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/${package.format}-assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
tar包内的情况如下所示:
localhost:target Sean$ tar -xvf maven-train-springboot-v1.tar
x maven-train-springboot-v1/maven-train-springboot-v1.jar
x maven-train-springboot-v1/config/application.properties
x maven-train-springboot-v1/config/log4j2.xml
Reference
[1]. Maven 常见插件
[2]. java cp命令
[3]. Maven的-pl -am -amd参数学习
[4]. Maven deploy跳过某个module解决办法
[5]. maven 单独构建多模块项目中的单个模块