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

文章目录

  • Pre
  • 概述
  • 方案思路
  • 构建流程图
  • 工作机制说明
  • 目录结构示例
  • POM 配置模板
  • 构建与验证
  • 注意事项
  • 方案优缺点

在这里插入图片描述


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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/918981.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/918981.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

平替 Claude Code,API接入 GPT-5,Codex CLI 国内直接使用教程

最新升级接入GPT-5的 Codex 拥有可以媲美 Claude Code 的AI编码能力&#xff0c;本文将指导你在 Windows系统上部署原生的 Codex CLI程序&#xff0c;并且接入超低价中转API&#xff0c;让你在国内直接用上超高性价比的 OpenAI Codex CLI 应用。关于 CodexCodex 是 OpenAI 开发…

kubernertes (K8S)部署

参考&#xff1a; https://blog.csdn.net/yu33575/article/details/135387548 二进制安装k8s&#xff1a; https://blog.csdn.net/qq_73990369/article/details/143217084 K8S二进制安装与部署 &#xff1a;https://blog.csdn.net/fantuan_sss/article/details/139073366 k8s…

LeetCode 简单JS刷题

目录 返回数组最后一个元素 2787.将一个数字表示成幂的和的方案数 326.3的幂 1780.判断一个数字是否可以表示成三的幂的和 342.4的幂 返回数组最后一个元素 1.请你编写一段代码实现一个数组方法&#xff0c;使任何数组都可以调用 array.last() 方法&#xff0c;这个方法将…

七大排序算法全解析:从入门到精通

目录 一.排序的概念 二.常见排序算法的实现 2.1 插入排序 &#xff08;1&#xff09;直接插入排序&#xff1a; 当插入第i(i>1)个元素时&#xff0c;前面的array[0],array[1],…,array[i-1]已经排好序&#xff0c;此时用array[i]的排序码与array[i-1],array[i-2],…的排序…

20250814在荣品RD-RK3588开发板的Android13下解决卡迪的LCD屏在开机的时候brightness最暗【背光的pwm信号的极性反了】

20250814在荣品RD-RK3588开发板的Android13下解决卡迪的LCD屏在开机的时候brightness最暗【背光的pwm信号的极性反了】 2025/8/14 11:33缘起&#xff1a;在荣品RD-RK3588开发板的Android13下&#xff0c;卡迪的LCD屏在开机的时候很暗&#xff0c;几乎看不见。 在命令行查看亮度…

Flink的状态管理

一、状态的概念Flink的状态其实你就可以将其想象为中间结果就可以了。在Flink中&#xff0c;算子的任务可以分为无状态和有状态两种情况。无状态算子任务在计算过程中是不依赖于其他数据的&#xff0c;只根据当前的输入数据就可以得到结果输出。比如之前讲到的Map、FlatMap、Fi…

GoLand 项目从 0 到 1:第八天 ——GORM 命名策略陷阱与 Go 项目启动慢问题攻坚

第八天核心任务&#xff1a;解决开发中的两大技术卡点今天的开发不仅聚焦于代码层面的数据库字段映射问题&#xff0c;还遭遇了一个困扰团队许久的环境难题 ——Go 项目启动异常缓慢。经过多维度排查&#xff0c;我们不仅理清了 GORM 命名策略的设计逻辑&#xff0c;还找到了影…

在Ubuntu上安装Google Chrome的详细教程

步骤 1&#xff1a;下载 Google Chrome 安装包 打开浏览器输入https://www.google.cn/chrome/&#xff0c;然后进入Chrome浏览器官方网站 点击下载选择Debian/Ubuntu版本 google-chrome-stable_current_amd64.deb步骤 2&#xff1a;安装下载的.deb 包 sudo dpkg -i google-chro…

el-table合并相同名称的行

el-table合并相同名称的行 <template><el-table:data"tableData":span-method"objectSpanMethod"border><el-table-columnprop"name"label"名称"width"180"></el-table-column><el-table-column…

解决 VSCode 无法从右键菜单“通过 Code 打开”文件夹的问题

&#x1f9e9; 一、问题现象 VSCode 已安装&#xff0c;但右键文件夹/桌面空白处无“通过 Code 打开在 VSCode 中执行 Shell Command: Install ‘Open with Code’ 无反应手动添加后菜单显示乱码&#xff08;如 €š‡ Code ‰“€&#xff09;点击右键菜单无响应或提示“找不到…

服务器数据恢复—服务器硬盘状态灯变红,分区数据恢复过程

服务器数据恢复环境&故障&#xff1a; 某公司服务器上有一组由3块硬盘组建的raid5磁盘阵列。 服务器上1块硬盘的状态灯变为红色&#xff0c;磁盘阵列出现故障&#xff0c;分区无法识别。服务器数据恢复过程&#xff1a; 1、将故障服务器上所有磁盘编号后取出。经过初检&…

MySQL → SQL → DDL → 表操作 → 数据类型 知识链整理成一份系统的内容

1. 知识结构MySQL└── SQL&#xff08;结构化查询语言&#xff09;├── DDL&#xff08;数据定义语言&#xff09; → 定义结构│ ├── 表操作&#xff08;创建/修改/删除表&#xff09;│ └── 数据类型&#xff08;列字段类型定义&#xff09;├── DML&…

基于 gRPC 的接口设计、性能优化与生产实践

gRPC 是一种高性能、跨语言的远程过程调用&#xff08;RPC&#xff09;框架&#xff0c;由 Google 开发&#xff0c;基于 HTTP/2 协议和 Protocol Buffers&#xff08;Protobuf&#xff09;序列化机制&#xff0c;广泛应用于微服务架构和分布式系统中。本文将深入解析 gRPC 的底…

如何回答研究过MQ的源码吗

​一、核心回答框架&#xff08;由浅入深&#xff09;​​1️⃣ ​明确研究对象和深度​“我主要研究过 ​​[具体MQ名称&#xff0c;如RocketMQ/Kafka/RabbitMQ]​​ 的核心模块源码&#xff0c;重点关注 ​​[选1-2个核心方向]​​ &#xff0c;比如存储机制、网络通信或事务…

20250815给ubuntu22.04.5的系统缩小/home分区

20250815给ubuntu22.04.5的系统缩小/home分区 2025/8/15 9:42缘起&#xff0c;联想IdeaPad笔记本电脑&#xff0c;换了4TB的SSD固态硬盘。 WIN10和ubuntu22.04.5的双系统。 WIN10系统&#xff1a; C盘 500GB&#xff1f; D盘 500GB&#xff1f;ubuntu22.04.5 /home分区大概 2.7…

Windows 11 首次开机引导(OOBE 阶段)跳过登录微软账户,创建本地账户

今天重装WIN11系统后&#xff0c;发现在首次开机引导&#xff08;OOBE 阶段&#xff09;中&#xff0c;微软默认强制联网并登录微软账户&#xff0c;没有的让你注册什么的就很烦。通过下面方法可以跳过登录微软账户&#xff0c;直接创建本地账户。✅ 方法一&#xff1a;断网&am…

IDE:vscode的vue3模板

快捷键打开配置选项&#xff1a;ctrl shift p选择配置文件&#xff1a;Snippet: Configure Snippets{// Place your snippets for vue here. Each snippet is defined under a snippet name and has a prefix, body and // description. The prefix is what is used to trigg…

C++_390_透传功能中,使用单例模式,管理session透传会话的生命周期,为每个会话记录报警读取状态,监控会话心跳状态,后台线程自动清理超时会话

问题:对接板端,cvms lite 通道管理页面,无法添加和删除多目通道 审核:XXX 根因分析:多通道的刪除和添加需要通过eventcheck上告实现,cvms lite云走的透传没有eventcheck 解决办法:云透传加上eventcheck上告 footer: Closes: #BUG2025052701632 我帮你分两部分解析:先解…

MIPI-csi调试

调试流程1. 硬件连线检查数据线&#xff08;MIPI Data Lanes&#xff09; &#xff1a;确认 IMX415 模组的 4 条数据线 1 条时钟线连接正确。如果是 4-lane 输出&#xff0c;SoC 的 D-PHY 必须也配置成 4-lane 接收。控制线&#xff1a;原理图IC SDA/SCL → &i2c8 控制器管…

Mysql——》提取JSON对象和数组

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…