一. 介绍
maven提供的打包插件有如下三种:
plugin |
function |
maven-jar-plugin |
maven 默认打包插件,用来创建 project jar |
maven-shade-plugin |
用来打可执行包,executable(fat) jar |
maven-assembly-plugin | 支持定制化打包方式,例如 apache 项目的打包方式 |
二. 打包准备
1). 需要设定文件的编码格式(如果不设定,将会以系统的默认编码进行处理)与JDK版本版本变量,代码如下:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
2). 需要确定依赖的scope:默认的scope包括如下
scope |
说明 |
compile |
默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath 中可用,同时它们也会被打包 |
provided |
依赖只有在当JDK 或者一个容器已提供该依赖之后才使用。例如, 如果你开发了一个web 应用,你可能在编译 classpath 中需要可用的Servlet API 来编译一个servlet,但是你不会想要在打包好的WAR 中包含这个Servlet API;这个Servlet API JAR 由你的应用服务器或者servlet 容器提供。已提供范围的依赖在编译classpath (不是运行时)可用。它们不是传递性的,也不会被打包。 |
runtime | 依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。 |
test | test范围依赖 在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用 |
system | system范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。如果你将一个依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或定制的 Maven 仓库中引用依赖) |
build分为两种:
a. base build
(既为project的子元素)
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<filters>
<filter>filters/filter1.properties</filter>
</filters>
...
</build>
上述例子中:
defaultGoal:
执行build任务时,如果没有指定目标,将使用的默认值,上述例子犹如 mvn install.
directory:build目标文件的存放目录,默认在${basedir}/target目录;
finalName:build目标文件的文件名,默认情况下为${artifactId}-${version};
b. 指定一个特定的resource位置。例如
2、targetPath:指定build后的resource存放的文件夹。该路径默认是basedir。通常被打包在JAR中的resources的目标路径为META-INF;
3、filtering:true/false,表示为这个resource,filter是否激活。
4、directory:定义resource所在的文件夹,默认为${basedir}/src/main/resources;
5、includes:指定作为resource的文件的匹配模式,用*作为通配符;
6、excludes:指定哪些文件被忽略,如果一个文件同时符合includes和excludes,则excludes生效;
7、testResources:定义和resource类似,但只在test时使用,默认的test resource文件夹路径是${basedir}/src/test/resources,test resource不被部署。
<build>
...
<resources>
<resource>
<targetPath>META-INF/plexus</targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/plexus</directory>
<includes>
<include>configuration.xml</include>
</includes>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
<testResources>
...
</testResources>
...
</build>
1、resources:一个resource元素的列表,每一个都描述与项目关联的文件是什么和在哪里;
2、targetPath:指定build后的resource存放的文件夹。该路径默认是basedir。通常被打包在JAR中的resources的目标路径为META-INF;
3、filtering:true/false,表示为这个resource,filter是否激活。
4、directory:定义resource所在的文件夹,默认为${basedir}/src/main/resources;
5、includes:指定作为resource的文件的匹配模式,用*作为通配符;
6、excludes:指定哪些文件被忽略,如果一个文件同时符合includes和excludes,则excludes生效;
7、testResources:定义和resource类似,但只在test时使用,默认的test resource文件夹路径是${basedir}/src/test/resources,test resource不被部署。
c. plugins,如下代码所示:
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.0</version>
<extensions>false</extensions>
<inherited>true</inherited>
<configuration>
<classifier>test</classifier>
</configuration>
<dependencies>...</dependencies>
<executions>...</executions>
</plugin>
</plugins>
</build>
除了groupId:artifactId:version标准坐标,plugin还需要如下属性:
1、extensions:true/false,是否加载plugin的extensions,默认为false;
2、inherited:true/false,这个plugin是否应用到该POM的孩子POM,默认true;
3、configuration:配置该plugin期望得到的properies,如上面的例子,我们为maven-jar-plugin的Mojo设置了classifier属性; 如果你的POM有一个parent,它可以从parent的build/plugins或者pluginManagement集成plugin配置。
三. maven-jar-plugin插件
该插件为pom默认的打包插件。
使用 Maven 构建一个 JAR 文件比较容易:只要定义项目包装为 “jar”,然后执行包装生命周期阶段即可。但是定义一个可执行 JAR 文件却比较麻烦。采取以下步骤可以更高效:
- a. 在您定义可执行类的 JAR 的 MANIFEST.MF 文件中定义一个
main
类。(MANIFEST.MF 是包装您的应用程序时 Maven 生成的。) - b. 找到您项目依赖的所有库。
- c. 在您的 MANIFEST.MF 文件中包含那些库,便于您的应用程序找到它们。
您可以手工进行这些操作,或者要想更高效,您可以使用两个 Maven 插件帮助您完成:maven-jar-plugin
和 maven-dependency-plugin
。
01.指定manfestFile位置:具体配置如下:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
...
</plugin>
</plugins>
</build>
...
</project>
02. 使用
maven-jar-plugin 修改 MANIFEST.MF文件,具体代码如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.mypackage.MyClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
所有 Maven 插件通过一个 <configuration>
元素公布了其配置,在本例中,maven-jar-plugin
修改它的 archive
属性,特别是存档文件的 manifest
属性,它控制 MANIFEST.MF 文件的内容。包括 3 个元素:
-
addClassPath
:将该元素设置为 true 告知maven-jar-plugin
添加一个Class-Path
元素到 MANIFEST.MF 文件,以及在Class-Path
元素中包括所有依赖项。 -
classpathPrefix
:如果您计划在同一目录下包含有您的所有依赖项,作为您将构建的 JAR,那么您可以忽略它;否则使用classpathPrefix
来指定所有依赖 JAR 文件的前缀。在清单 1 中,classpathPrefix
指出,相对存档文件,所有的依赖项应该位于 “lib
” 文件夹。 -
mainClass
:当用户使用lib
命令执行 JAR 文件时,使用该元素定义将要执行的类名。上述可以通过是用maven-dependency-plugin将依赖包添加进去
maven-dependency-plugin:
当您使用这 3 个元素配置好了 MANIFEST.MF 文件之后,下一步是将所有的依赖项复制到
lib
文件夹。为此,使用
maven-dependency-plugin。代码如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
maven-dependency-plugin
有一个 copy-dependencies
,目标是将您的依赖项复制到您所选择的目录。本例中,我将依赖项复制到 build
目录下的 lib
目录(project-home/target/lib
)。
将您的依赖项和修改的 MANIFEST.MF 放在适当的位置后,您就可以用一个简单的命令启动应用程序:
java -jar jarfilename.jar
四.
maven-shade-plugin
(备注:以下内容参考:https://www.jianshu.com/p/7a0e20b30401
通过 maven-shade-plugin 生成一个 uber-jar,它包含所有的依赖 jar 包。也可以使用该插件解决包冲突问题。用法如下:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.codehaus.plexus.util</pattern>
<shadedPattern>org.shaded.plexus.util</shadedPattern>
<excludes>
<exclude>org.codehaus.plexus.util.xml.Xpp3Dom</exclude>
<exclude>org.codehaus.plexus.util.xml.pull.*</exclude>
</excludes>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
上面的配置
将 org.codehaus.plexus.util jar 包重命名为 org.shaded.plexus.util。
第二个例子:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<outputFile>../target/ddstutorial.jar</outputFile>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>
XX.XXX.XXX.XXX.XXXMainclass
</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
i implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
上述列子中:注意
transformer标签:主要作用为了防止classes/resource标签出现重叠,而导致混乱,引入了transfirner标签:其主要包括:
1. org.apache.maven.plugins.shade.resource.ManifestResourceTransformer(重复的main不被合并):
2.
org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer(例如可以避免META-INF/read.me被合并)
3.
org.apache.maven.plugins.shade.resource.AppendingTransformer(例如
META-INF/spring.handlers与
META-INF/spring.schemas
)如下代码所示
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
五.
maven-assembly-plugin
将相关文件打包一起分发出去,常见的例如apache的分发包以及常用的zip等包信息。配置说明:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<outputDirectory>D:/testfolder</outputDirectory>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest> <mainClass>mainclass</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
若需要将按照一定的目录进行发布的话,需要配置对应的
assembly配置信息:配置信息内容如下:
<?xml version="1.0"?>
-<assembly xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/ASSEMBLY/2.0.0">
<id>bin</id>
-<formats>
<format>zip</format>
</formats>
-<dependencySets>
-<dependencySet>
<useProjectArtifact>true</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
-<fileSets>
-<fileSet>
<outputDirectory>${file.separator}</outputDirectory>
-<includes>
<include>README.txt</include>
</includes>
</fileSet>
-<fileSet>
<directory>src/main/resources</directory>
<outputDirectory>${file.separator}bin</outputDirectory>
-<includes>
<include>start.sh</include>
<include>start.bat</include>
</includes>
</fileSet>
-<fileSet>
<directory>logs</directory>
<outputDirectory>${file.separator}logs</outputDirectory>
</fileSet>
-<fileSet>
<directory>datas</directory>
<outputDirectory>${file.separator}datas</outputDirectory>
</fileSet>
-<fileSet>
<directory>doc</directory>
<outputDirectory>${file.separator}doc</outputDirectory>
</fileSet>
</fileSets>
</assembly>
在POM中加入如下配置:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<outputDirectory>D:/testfolder</outputDirectory>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>XXXXMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
自此,介绍完毕