答案是:需从零编写精细的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"></assembly>必须带完整命名空间 - 用
<id>dist</id>命名该组装方案,后续通过-Pdist或-Dassembly.id=dist触发 -
<formats></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></fileset>:一个放启动脚本到bin/,一个放配置模板到conf/,一个放静态资源到webapp/
用 分离依赖并重定位 JAR
避免所有依赖挤在 lib/ 下。按用途拆开:
- 主程序依赖(必须):
<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-*</include></includes>精确匹配坐标 - 排除传递依赖干扰:
<usetransitivedependencies>false</usetransitivedependencies>,只取直接声明的
用 和 注入单个关键文件
适合放 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></outputdirectory> 的起点是压缩包内部的根;Maven 构建生命周期中,assembly 是在 package 阶段之后执行的,确保你 mvn clean package assembly:single 或绑定到 install;调试时加 -X 查看插件实际拷贝了哪些路径。真正灵活的结构,90% 功夫在 XML 描述的严密性上。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











