要用 maven 的 maven-assembly-plugin 打出可执行 fat jar,关键不是“加插件就完事”,而是明确两件事:把所有依赖合并进 jar、并在 meta-inf/manifest.mf 里正确写入 main-class;它默认不做这两点,必须手动配:1. 在 pom.xml 中声明插件并绑定到 package 阶段;2. 提供 assembly 描述文件(如 src/main/assembly/package.xml);3. 确保 manifest 正确生成且类路径无冲突;4. 打包与验证命令别跳过 clean。

要用 Maven 的 maven-assembly-plugin 打出可执行的 Fat Jar,关键不是“加插件就完事”,而是明确两件事:把所有依赖合并进 jar、并在 META-INF/MANIFEST.MF 里正确写入 Main-Class。它默认不做这两点,必须手动配。
1. 在 pom.xml 中声明插件并绑定到 package 阶段
插件需显式配置执行时机(single goal)和生命周期阶段(package),否则不会触发打包:
- 用
<executions></executions>指定在package阶段运行single目标 - 推荐指定稳定版本(如
3.6.0),避免依赖变量引发冲突 -
<configuration></configuration>中至少要指定描述文件路径或使用内置 descriptor
2. 提供 assembly 描述文件(如 src/main/assembly/package.xml)
这是控制“怎么打”的核心。哪怕只打一个可执行 jar,也建议用自定义描述文件,而不是依赖 jar-with-dependencies——后者不自动写 Main-Class:
提供端到端的高端代理设置和使用指导,包括代理类型选择、地区定向、访问配置、API密钥验证和监控。
- 根节点
<assembly></assembly>下定义<id></id>和<formats></formats>(设为jar) - 用
<dependencysets></dependencysets>把 runtime 依赖解压后合并进 classpath(<unpack>true</unpack>) - 用
<filesets></filesets>包含自己代码的classes目录(确保源码类被复制) - 必须配置
<manifestentries></manifestentries>,显式写入Main-Class(完整类名,如com.example.Main)
3. 确保 MANIFEST 正确生成且类路径无冲突
Assembly 不重定位类(不像 shade),所以如果多个依赖含同名类(比如不同版本的 slf4j),会覆盖或报错:
- 检查 target/classes/META-INF/MANIFEST.MF 是否真有
Main-Class: xxx行 - 确认
<unpack>true</unpack>已启用,否则依赖仍以 jar 形式留在 lib/ 下,不会被加载 - 若遇类冲突,要么排除冗余依赖,要么换用 maven-shade-plugin 做 relocations
4. 打包与验证命令
别跳过 clean,旧产物可能干扰新 manifest:
- 执行
mvn clean package - 检查
target/下生成的 jar 文件名是否符合finalName设置(建议区别于原始 jar) - 运行
java -jar your-app-1.0.jar,观察是否直接启动,而非报no main manifest attribute或ClassNotFoundException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










