直接依赖场景
工作中经常遇到需要给老客户打补丁,老客户安装的版本各不相同,升级后有的方法参数变了、有的方法甚至移除了,导致代码退回去打包经常报错,这里记录一种较方便且灵活的方式来适应经常要给老客户打补丁的情况。
假设项目 ruleplan 中有个 pos.jar 依赖:
<dependency> <groupId>com.sec.npm</groupId> <artifactId>pos</artifactId> <version>1.2.14-SNAPSHOT</version> <scope>provided</scope> </dependency>
Maven 默认对于 -SNAPSHOT 版本,每次构建都会去检查远程仓库元数据,然后选择最新的时间戳版本,下面讲一种强制使用旧版本的方式。
当要给客户打包老版本的 ruleplan.jar 时,依赖的 pos.jar 包里部分接口已升级或删除了,导致打包失败,下面提供一种快速有效的打包方式,步骤如下:
(1)根据客户的版本找到对应时间点,根据时间点去 Sonatype Nexus 里找到 pos-1.2.14-20240902.103802-929.jar、pos-1.2.14-20240902.103802-929.pom
,下载下来后放本地的 maven 仓库下( 目录位置:com/sec/npm/pos/1.2.14-SNAPSHOT
),如图:

本地 Maven 仓库 pos 项目目录:

(2)修改 ruleplan pom.xml 里的 pos.jar 依赖,将 1.2.14-SNAPSHOT 直接改成指定时间戳版本,如:
<dependency> <groupId>com.sec.npm</groupId> <artifactId>pos</artifactId> <version>1.2.14-20240902.103802-929</version> <scope>provided</scope> </dependency>
(3)开始打包 mvn clean package,打包完成改回 1.2.14-SNAPSHOT 即可。
间接依赖场景
在直接依赖场景,ruleplan依赖pos,其实pos还依赖 server,server还依赖 common。一般情况下,我们无需关心间接依赖的库,ruleplan打包时不会包含它们的版本信息。
但如果 rulepan项目用了 OSGI
这种框架就不一样了,必须考虑了,因为打包时候插件会在 META-INF/MANIFEST.MF
里塞入类似如下信息:
Implementation-Title: Sec rulePlan Bundle for Pos Implementation-Vendor: Sec Implementation-Vendor-Id: com.sec.npm.bundle.ruleplan Implementation-Version: 1.0.1-SNAPSHOT Import-Package: com.fasterxml.jackson.annotation;version="[2.15,3)",com. fasterxml.jackson.core;version="[2.15,3)",com.fasterxml.jackson.databin d;version="[2.15,3)",com.sec.npm.common.domain,com.sec.npm.common .util,com.sec.npm.core.beans,com.sec.npm.core.service, ......
可以看到 Import-Package
里包含了 common 项目依赖的 jackson库版本信息,但却用的当前开发环境最新的版本,这就不对了,应该用旧的 jackson 版本才对。
解决这个问题有个非常快的办法:
(1)先把客户那的旧 ruleplan.jar 拿过来,解压得到旧的 MANIFEST.MF
(2)将新打的 ruleplan.jar补丁也解压,把旧的 MANIFEST.MF 替换进去
(3)再用命令手动打 ruleplan.jar 给客户:cd ruleplan-1.0.1-SNAPSHOT && jar -cvfm ruleplan-1.0.1-SNAPSHOT.jar META-INF/MANIFEST.MF *
如果拿不到客户的 ruleplan.jar,可以考虑修改pos的pom.xml,将server的依赖改成指定时间戳版本后本地打个包,rulepan也指定时间戳版本指向这个pos。