答案是:需从零编写精细的assembly descriptor XML文件,通过fileSet精确映射目录结构与权限、dependencySet分离依赖至指定子目录,并配置formats、includeBaseDirectory及id等核心元素实现高度定制化打包。

用 maven-assembly-plugin 实现高度定制化的打包结构,核心不在插件本身有多“强大”,而在于精准控制 assembly descriptor(装配描述文件)的每个细节。它不靠写 Java 代码,而是靠 XML 描述“把哪些东西、以什么路径、用什么权限、放在最终包的哪个位置”。只要 descriptor 写得够细,目录结构可以任意嵌套、重命名、过滤、甚至按 profile 动态切换。
写一个精细到子目录层级的 assembly descriptor
别依赖默认的 bin 或 jar-with-dependencies 模板。新建 src/assembly/dist.xml,从零定义结构:
- 根节点
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">必须带完整命名空间 - 用
<id>dist</id>命名该组装方案,后续通过-Pdist或-Dassembly.id=dist触发 -
<formats>指定输出格式:<format>tar.gz</format>、<format>zip</format>,支持多个 -
<includeBaseDirectory>true</includeBaseDirectory>控制是否在压缩包里再套一层顶层目录(通常设为true,避免解压污染当前目录)
用 <fileSet> 精确映射每一个目录和文件
这是控制结构的关键。每个 <fileSet> 定义一组源文件如何被复制进目标位置:
-
<directory>src/main/scripts</directory>指定源路径(相对于项目根) -
<outputDirectory>bin/</outputDirectory>指定打进包里的相对路径,注意结尾斜杠表示目录 -
<fileMode>0755</fileMode>设置 Linux 权限(仅对 tar.gz 生效),0644给配置文件 -
<includes><include>*.sh</include></includes>白名单过滤;<excludes><exclude>dev.sh</exclude></excludes>黑名单排除 - 可重复多个
<fileSet>:一个放启动脚本到bin/,一个放配置模板到conf/,一个放静态资源到webapp/
用 <dependencySet> 分离依赖并重定位 JAR
避免所有依赖挤在 lib/ 下。按用途拆开:
立即学习“Java免费学习笔记(深入)”;
- 主程序依赖(必须):
<outputDirectory>lib/app/</outputDirectory>,配合<useProjectArtifact>true</useProjectArtifact>把自己打成 JAR 放进去 - 第三方库:
<outputDirectory>lib/ext/</outputDirectory>,用<scope>runtime</scope>过滤掉 compile-only 的 - 可选插件:
<outputDirectory>plugins/</outputDirectory>,用<includes><include>com.example:plugin-*/includes>精确匹配坐标 - 排除传递依赖干扰:
<useTransitiveDependencies>false</useTransitiveDependencies>,只取直接声明的
用 <files> 和 <file> 注入单个关键文件
适合放 license、version.txt、自动生成的 manifest 等无法用 fileSet 批量处理的文件:
-
<file><source>LICENSE</source><outputDirectory></outputDirectory><fileMode>0644</fileMode></file>—— 放到包根目录 -
<file><source>target/version.properties</source><outputDirectory>conf/</outputDirectory><destName>release.properties</destName></file>—— 重命名并放入子目录 - 结合 Maven Resource Filtering:
<filtered>true</filtered>让${project.version}在打包时替换
不复杂但容易忽略:descriptor 文件里所有路径都是相对路径,<outputDirectory> 的起点是压缩包内部的根;Maven 构建生命周期中,assembly 是在 package 阶段之后执行的,确保你 mvn clean package assembly:single 或绑定到 install;调试时加 -X 查看插件实际拷贝了哪些路径。真正灵活的结构,90% 功夫在 XML 描述的严密性上。


















