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 友好 需搭建和维护私服 多人协作,长期依赖

相关推荐
摇滚侠12 分钟前
Spring Boot3零基础教程,Reactive-Stream 发布订阅写法,笔记104 笔记105
java·spring boot·笔记
Q_Q5110082857 小时前
python+django/flask的眼科患者随访管理系统 AI智能模型
spring boot·python·django·flask·node.js·php
韩立学长9 小时前
基于Springboot的旧时月历史论坛4099k6s9(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
Q_Q5110082859 小时前
python+django/flask的在线学习系统的设计与实现 积分兑换礼物
spring boot·python·django·flask·node.js·php
Q_Q51100828510 小时前
python+django/flask的车辆尾气检测排放系统-可视化大屏展示
spring boot·python·django·flask·node.js·php
汤姆yu10 小时前
基于SpringBoot的动漫周边商场系统的设计与开发
java·spring boot·后端
皮皮林55110 小时前
快速解决 Maven 版本冲突指南 !
java·maven
摇滚侠12 小时前
Spring Boot3零基础教程,响应式编程的模型,笔记109
java·spring boot·笔记
Q_Q196328847512 小时前
python+django/flask基于Echarts+Python的图书零售监测系统设计与实现(带大屏)
spring boot·python·django·flask·node.js·php
拾荒的小海螺13 小时前
JAVA:Spring Boot3 新特性解析的技术指南
java·开发语言·spring boot