JAR 包的打包方式
目录
JAR 包的打包方式
普通JAR vs Fat JAR vs WAR
1. 普通 JAR(默认)-不包含依赖
<packaging>jar</packaging>
会生成普通jar包:xx-1.0-SNAPSHOT.jar - 普通JAR
这种打包方式确实只包含你项目的编译代码,不包含项目pom文件里导入的任何依赖。运行时需要的依赖需要额外提供。
2. Fat JAR - 包含所有依赖
Spring Boot、Quarkus 等框架项目的常见做法
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.0</version> <!-- 添加明确的版本号 -->
</plugin>
</plugins>
</build>
这种 JAR 包会包含所有依赖(除了 provided 范围的),可以直接运行:
java -jar your-app.jar
会生成两个JAR:
your-app.jar# Spring Boot 可执行JAR(包含依赖)your-app.jar.original# 原始JAR(不包含依赖)
普通项目使用 maven-assembly-plugin 或 maven-shade-plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<!-- 需要指定 <mainClass>:否则无法直接运行 java -jar -->
<manifest>
<mainClass>DruidExample</mainClass>
</manifest>
</archive>
</configuration>
<!-- 没有执行配置,插件不会自动运行 -->
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
这种也会创建包含所有依赖的 Fat JAR。会生成两个JAR:
xx-1.0-SNAPSHOT.jar- 普通JARxx-1.0-SNAPSHOT-jar-with-dependencies.jar- 包含依赖的Fat JAR
对比总结
| 特性 | Spring Boot 插件 | Maven Assembly 插件 |
|---|---|---|
| 输出数量 | 1个JAR(新JAR)+ 1个jar.original(原始JAR改名) | 2个JAR(新JAR+原始JAR) |
| 原始JAR | 重命名为 .original |
保留原样 |
| 默认行为 | 替换主JAR | 创建附加JAR |
| 文件命名 | your-app.jar |
your-app-jar-with-dependencies.jar |
如果你想让 Assembly 插件也只生成一个JAR,添加配置:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId> <!-- 关键配置 -->
</configuration>
</plugin>
为什么 Spring Boot 插件更好?
- 标准的Spring Boot结构:包含
BOOT-INF/classes和BOOT-INF/lib - 更好的类加载:使用Spring Boot的类加载器
- 启动性能优化:支持JAR包索引
- 生产就绪:包含Spring Boot的启动器
所以如果你在用Spring Boot,强烈推荐使用Spring Boot插件,它专门为Spring Boot应用优化过。
3.WAR 包的特殊性
WAR 包确实会自动包含 compile 范围的依赖,但排除 provided 范围的依赖。
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
<scope>provided</scope> <!-- 不会打包进 WAR -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.0</version>
<!-- 默认 compile,会打包进 WAR -->
</dependency>
</dependencies>
作用域对打包的影响总结
| 作用域 | 普通 JAR | Fat JAR | WAR | 说明 |
|---|---|---|---|---|
compile |
❌ 不包含 | ✅ 包含 | ✅ 包含 | 默认作用域 |
provided |
❌ 不包含 | ❌ 不包含 | ❌ 不包含 | 由运行环境提供 |
runtime |
❌ 不包含 | ✅ 包含 | ✅ 包含 | 运行需要,编译不需要 |
test |
❌ 不包含 | ❌ 不包含 | ❌ 不包含 | 仅测试使用 |
浙公网安备 33010602011771号