文章目录

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 文件。
方案思路
- 编译期 :使用
<scope>system</scope>
让本地 jar 参与编译。 - 打包期 :通过
maven-resources-plugin
在process-resources
阶段将本地 jar 文件复制到target/classes/BOOT-INF/lib
,这样spring-boot-maven-plugin
在repackage
时会将其一并打入 fat jar。 - 运行期 :由于 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
工作机制说明
- 资源复制阶段
maven-resources-plugin
在process-resources
阶段,将src/main/resources/lib
中的所有 jar 文件复制到target/classes/BOOT-INF/lib
。 - 打包阶段
spring-boot-maven-plugin
在repackage
阶段会打包所有在BOOT-INF/lib
的 jar 到最终可执行 jar 中。 - 运行阶段
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 需要长期维护,建议安装到本地仓库:
bashmvn 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 友好 | 需搭建和维护私服 | 多人协作,长期依赖 |
