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 - 普通JAR
  • xx-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 插件更好?

  1. 标准的Spring Boot结构:包含 BOOT-INF/classesBOOT-INF/lib
  2. 更好的类加载:使用Spring Boot的类加载器
  3. 启动性能优化:支持JAR包索引
  4. 生产就绪:包含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 ❌ 不包含 ❌ 不包含 ❌ 不包含 仅测试使用
posted @ 2025-11-27 20:29  deyang  阅读(129)  评论(0)    收藏  举报