本文在 Apache Maven 的官方文档上, 结合自己的一些项目经历: 在 Apache Spark 中使用 springframework 的一次实践, 总结了一些 assembly 插件的使用方式和一些注意事项, 以作备忘;
另外, 由于 assembly 的 核心配置文件中可配置项种类繁多, 为了体现直观性, 文本直接在一段 ‘丰富而典型’ 的配置文件 case 上, 以注释的形式作为每个配置项的释义;
pom.xml 中的配置项
一段典型的 assembly 插件的 mvn 配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>${assembly.plugin.version}</version> <configuration> <appendAssemblyId>false</appendAssemblyId> <outputDirectory>${project.build.directory}/target</outputDirectory> <descriptors> <descriptor>${basedir}/src/main/assembly/client.xml</descriptor> <descriptor>${basedir}/src/main/assembly/server.xml</descriptor> </descriptors> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
|
核心配置文件
以下 assembly 核心配置文件包含了最常用的几种配置项, 该文件习惯上放置在 ${basedir}/src/main/assembly/
目录里, 并如上一节所示, 在 configuration -> descriptors
路径下定义加载:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd"> <id>deploy</id>
<formats> <format>jar</format> </formats> <includeBaseDirectory>false</includeBaseDirectory> <baseDirectory>${project.build.finalName}</baseDirectory> <files> <file> <source>LICENSE.txt</source> <outputDirectory>/</outputDirectory> </file> <file> <source>NOTICE.txt</source> <outputDirectory>/</outputDirectory> <filtered>true</filtered> </file> </files> <fileSets> <fileSet> <directory>${project.basedir}/src/main/resources</directory> <outputDirectory>/</outputDirectory> </fileSet> <fileSet> <directory>${project.basedir}/src/doc</directory> <useDefaultExcludes>true</useDefaultExcludes> <outputDirectory>/doc</outputDirectory> </fileSet> </fileSets> <dependencySets> <dependencySet> <outputDirectory>/lib</outputDirectory> <useProjectArtifact>true</useProjectArtifact> <useProjectAttachments>false</useProjectAttachments> <unpack>false</unpack> <scope>runtime</scope> <useTransitiveDependencies>true</useTransitiveDependencies>
<excludes> <exclude>org.apache.commons:commons-logging:jar</exclude> <exclude>*:war</exclude> </excludes> <useTransitiveFiltering>true</useTransitiveFiltering> </dependencySet> </dependencySets> </assembly>
|
使用 assembly 的一些注意事项
- 使用 assembly 打包成需要独立运行的 jar 时, 若无特殊需要显式定义 CLASSPATH, 则在核心配置文件中不应该定义
baseDirectory
, 并将 includeBaseDirectory
置为 false
;
因为 assembly 生成的 jar 包在 /META-INF/MANIFEST.MF
文件中默认不会定义 Class-Path
, 即 CLASSPATH 默认就是 jar 中的基目录;
1 2 3 4
| Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: 25.151-b12 (Oracle Corporation)
|
- 核心配置文件中的
outputDirectory
皆是以目标打包文件的根为相对路径的; 无论是否在路径最前面添加 /
, 都不会有影响;
- assembly 2.2 之前的版本, 在涉及到一些复杂第三方依赖, 多个不同的 jar 包中含有同名的文件 (如 org.springframework) 时, 使用 assembly 打包时会遇到一个 bug:
assembly 只把第一次遇到的同名文件加入目标打包文件, 其后遇到的同名文件, 则被 skip 掉 ( 详见官方 issue: When using mulitple Spring dependencies, the files from META-INF (from the Spring jars) overwrite each other in an executable jar-with-dependencies );
当然, 在这个 issue 当中, 触发此 bug 还有一个必要条件是将 dependencySet 中的 unpack 置为 true, 这样多个 spring artifact META-INF/ 中的 spring.handlers / spring.schemas / spring.tooling 等文件才会同名冲突;
关于 assembly 命令
除了上述以 配置文件 + maven core phase 回调的形式使用 assembly 插件之外, assembly 插件的 goals 也可以命令的形式执行:
1 2
| mvn clean assembly:single mvn assembly:help
|
由于使用 assembly 命令的场景不多见, 此处不再详述, 详见 maven 官方介绍: assembly:single
站内相关文章
参考链接