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

发布于:2025-08-16 ⋅ 阅读:(15) ⋅ 点赞:(0)


在这里插入图片描述


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,使它们在运行时可用。

目录结构示例

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

POM 配置模板

<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>

构建与验证

mvn clean package

验证 jar 是否被打入:

jar tf target/my-project-0.0.1-SNAPSHOT.jar | grep BOOT-INF/lib

应能看到 your.jar 记录。


注意事项

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

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

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

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到