Maven - Spring Boot 项目打包本地 jar 的 3 种方法

文章目录


Pre

Maven - Manual Maven JAR Installation:用 mvn install:install-file 安装本地 JAR 的实用指南

概述

在 Spring Boot 项目中,通常依赖包会从 Maven 中央仓库或私有仓库获取,并由 spring-boot-maven-plugin 自动打包进最终的可执行 fat jar(BOOT-INF/lib 目录)。

但在实际开发中,有时会遇到无法从公共或私有仓库获取的第三方 jar,例如厂商提供的 SDK、本地编译生成的工具包、未开源的内部依赖等。

如果直接使用 <scope>system</scope> 引入本地 jar,虽然能在编译时解析,但 Maven 默认不会将 system scope 依赖打入 Spring Boot 的 fat jar 中,导致部署后运行时找不到该类。

为了解决这一问题,需要在打包阶段显式将这些 jar 文件复制到 BOOT-INF/lib 目录,确保它们随 Spring Boot 应用一起分发与运行。

这个场景尤其适用于:

  • 快速集成:临时引入无法上传至私服的第三方 jar。
  • 离线部署:运行环境无法访问外部仓库。
  • 封闭式交付:需要将全部依赖打包成一个独立可运行的 jar 文件。

方案思路

  1. 编译期 :使用 <scope>system</scope> 让本地 jar 参与编译。
  2. 打包期 :通过 maven-resources-pluginprocess-resources 阶段将本地 jar 文件复制到 target/classes/BOOT-INF/lib,这样 spring-boot-maven-pluginrepackage 时会将其一并打入 fat jar。
  3. 运行期 :由于 jar 已进入 BOOT-INF/lib,Spring Boot 的类加载器会自动加载。

构建流程图

本地 jar 放到 src/main/resources/lib 执行 mvn package maven-resources-plugin 在 process-resources 阶段执行 复制 *.jar 到 target/classes/BOOT-INF/lib Spring Boot repackage 阶段启动 收集 BOOT-INF/lib 内的 jar 生成可执行 fat jar 部署并运行 Spring Boot 类加载器加载 BOOT-INF/lib 中的 jar

工作机制说明

  1. 资源复制阶段
    maven-resources-pluginprocess-resources 阶段,将 src/main/resources/lib 中的所有 jar 文件复制到 target/classes/BOOT-INF/lib
  2. 打包阶段
    spring-boot-maven-pluginrepackage 阶段会打包所有在 BOOT-INF/lib 的 jar 到最终可执行 jar 中。
  3. 运行阶段
    Spring Boot 启动时会用自带的类加载器加载 BOOT-INF/lib 中的所有 jar,使它们在运行时可用。

目录结构示例

java 复制代码
my-project/
├── src/
│   ├── main/
│   │   ├── java/...         # 源码
│   │   ├── resources/
│   │   │   ├── application.yml
│   │   │   └── lib/
│   │   │       └── your.jar  # 本地 jar
├── pom.xml

POM 配置模板

xml 复制代码
<dependency>
    <groupId>com.xxx</groupId>
    <artifactId>your-artifact</artifactId>
    <version>1.0.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/src/main/resources/lib/your.jar</systemPath>
</dependency>

<build>
    <plugins>
        <!-- 复制本地 jar 到 BOOT-INF/lib -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>copy-system-jars</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.outputDirectory}/BOOT-INF/lib</outputDirectory>
                        <resources>
                            <resource>
                                <directory>${project.basedir}/src/main/resources/lib</directory>
                                <includes>
                                    <include>*.jar</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <!-- Spring Boot 打包插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>
    </plugins>
</build>

构建与验证

bash 复制代码
mvn clean package

验证 jar 是否被打入:

bash 复制代码
jar tf target/my-project-0.0.1-SNAPSHOT.jar | grep BOOT-INF/lib

应能看到 your.jar 记录。


注意事项

  • system scope 在 Maven 官方中不推荐长期使用,不具备依赖冲突检测功能,适合临时方案。

  • 如果 jar 需要长期维护,建议安装到本地仓库:

    bash 复制代码
    mvn install:install-file \
      -Dfile=src/main/resources/lib/your.jar \
      -DgroupId=com.xxx \
      -DartifactId=your-artifact \
      -Dversion=1.0.0 \
      -Dpackaging=jar
  • 团队协作建议使用私服(Nexus / Artifactory)管理。


方案优缺点

方法 核心做法 是否自动打包进 fat jar 优点 缺点 适用场景
方法 1:安装到本地 Maven 仓库 mvn install:install-file 安装到 ~/.m2/repository,pom.xml 正常依赖 ✅ 会打包 - 符合 Maven 规范 - 支持版本管理与冲突检测 - CI/CD 无障碍 - 初次使用需执行安装命令 - jar 更新需重新安装 jar 可长期使用,且团队或构建环境可访问本地/远程仓库
方法 2:上传到私服(Nexus/Artifactory) 上传 jar 到私服仓库,pom.xml 正常依赖 ✅ 会打包 - 团队共享方便 - 支持版本管理与依赖分析 - CI/CD 最友好 - 需要搭建和维护私服 - 上传步骤比本地仓库多 多人协作项目,需稳定依赖和自动化构建
方法 3:直接内嵌 jar(system scope) 把 jar 放到 src/main/resources/lib<scope>system</scope> ❌ 默认不会打包(可用 includeSystemScope=true 或 maven-resources-plugin 手动复制) - 无需上传仓库 - 依赖文件随项目走 - 不走 Maven 依赖管理 - 无版本冲突检测 - CI/CD 需额外处理 - jar 升级需手动替换 临时测试或快速 PoC,构建环境固定且可直接带 jar

方法 是否打包进 fat jar 优点 缺点 适用场景
本方案(system + 手动复制) 快速接入,适合临时调试或离线部署 维护成本高,不做依赖冲突检测 临时/封闭环境
本地 Maven 仓库安装 符合 Maven 规范,支持版本管理 jar 更新需重新安装 长期使用,本地构建
上传私服 团队共享方便,CI/CD 友好 需搭建和维护私服 多人协作,长期依赖

相关推荐
不倒翁玩偶7 小时前
IDEA导入新的SpringBoot项目没有启动按钮
java·spring boot·intellij-idea
Elieal8 小时前
SpringBoot 数据层开发与企业信息管理系统实战
java·spring boot·后端
识君啊8 小时前
MyBatis-Plus 逻辑删除导致唯一索引冲突的解决方案
java·spring boot·mybatis·mybatis-plus·唯一索引·逻辑删除
Coder_Boy_8 小时前
Java开发者破局指南:跳出内卷,借AI赋能,搭建系统化知识体系
java·开发语言·人工智能·spring boot·后端·spring
Aric_Jones9 小时前
idea使用.env运行SpringBoot项目
java·spring boot·intellij-idea
代码栈上的思考9 小时前
SpringBoot 拦截器
java·spring boot·spring
jbtianci9 小时前
Spring Boot管理用户数据
java·spring boot·后端
编程彩机9 小时前
互联网大厂Java面试:从Jakarta EE到微服务架构的技术场景深度解读
spring boot·分布式事务·微服务架构·java面试·jakarta ee
biyezuopinvip10 小时前
基于Spring Boot的企业网盘的设计与实现(毕业论文)
java·spring boot·vue·毕业设计·论文·毕业论文·企业网盘的设计与实现
szhf7810 小时前
SpringBoot Test详解
spring boot·后端·log4j