背景
大型公司一般都会对开源软件的生命周期进行管理,产品中的开源软件随着时间的流逝,会不断的爆出漏洞;另外为了减少维护工作,公司会对软件版本做归一,老版本的开源软件在一段时间后也会被禁用。基于以上2点,产品中肯定会面临组件升级。
升级是需要一定的经验的,不是野蛮升级然后测试兼容性,到时候蹦出一堆问题,难以招架。
开源组件版本号解释
最常见的命名规范:
主版本号 . 子版本号 [. 修正版本号 [. 编译版本号 ]]
- 主版本号:第一个数字,产品改动较大,可能无法向后兼容(要看具体项目)
- 子版本号:第二个数字,增加了新功能,向后兼容
- 修正版本号:第三个数字,修复 BUG 或优化代码,一般没有添加新功能,向后兼容
- 编译版本号:通常是系统自动生成,每次代码提交都会导致自动加 1
版本号修饰词:
- alpha: 内部测试版本,BUG 较多,一般用于开发人员内部交流
- beta: 测试版,BUG 较多,一般用于热心群众测试,并向开发人员反馈
- rc: release candidate,即将作为正式版发布,正式版之前的最后一个测试版。
- ga:general availability,首次发行的稳定版
- r/release/或干脆啥都不加:最终释放版,用于一般用户
- lts: 长期维护,官方会指定对这个版本维护到哪一年,会修复所有在这个版本中发现的 BUG
修改POM引入的版本号后,发现没生效
- 使用maven命令(mvn help:effective-pom)展开POM,查询从父POM集成的属性
开源升级不兼容
场景一:jar版本不统一,不配套;导致启动后提示方法不存在
案例一:升级micrometer报错
思路:选择升级目标版本时,有查询spring boot 2.3.11所兼容的版本。理论上来说升级应该不会有问题。
- 去相关jar确认一下是否缺失该类。 – 确认没问题后
- 确认一下打出来的应用包,升级版本号是否生效。 – 发现没有生效,后来定位发现是其他地方引用了低版本,没有修改干净
场景二:新版jar包修改了默认配置,导致功能异常
案例一:cassandra低版本升级到3.7.1报错
定位到问题代码,发现为readonly属性添加了一个非空校验的set方法。一般的ORM系统要么通过getDeclaredField(),要么通过get/set方法获取所有的字段。根据提示应该,是通过get/set来获取的。
为啥老版本没有问题?为了解决这个疑问,只能通过阅读源码来解决了。
public void setReadonlyNotNull(Boolean readonly) {
if (readonly != null) {
this.readonly = readonly;
}
}
顺着堆栈打印的信息,找到应用层报错代码,并追踪底层的源码
public static final MappingConfiguration getMappingConfiguration() {
DefaultPropertyMapper propertyMapper = new DefaultPropertyMapper();
MappingConfiguration configuration = MappingConfiguration.builder().withPropertyMapper(propertyMapper).build();
return configuration;
}
看到可疑点,propertyAccessStrategy。字面意思属性访问策略。而且有三个枚举值 GETTERS_AND_SETTERS,FIELDS,BOTH;
看到这里决定设置一下这个属性为PropertyAccessStrategy.FIELDS。结果尝试成功。
public DefaultPropertyMapper() {
this.propertyAccessStrategy = PropertyAccessStrategy.BOTH;
this.propertyTransienceStrategy = PropertyTransienceStrategy.OPT_OUT;
this.hierarchyScanStrategy = new DefaultHierarchyScanStrategy();
this.namingStrategy = new DefaultNamingStrategy();
this.transientPropertyNames = new HashSet(DEFAULT_TRANSIENT_PROPERTY_NAMES);
}
场景三:新版本干掉了deprecated的方法,导致编译报错
案例一:ES服务端的版本使用的是6.x.x,导致spring-data-ES只能使用3.2.x.当spring boot升级到2.3.11时,版本不兼容
spring boot 2.3.11升级后,ElasticsearchProperties类被干掉了,导致应用编译报错。
解决思路:
spring-data-es是自包含的,他不依赖spring boot的自动配置。因此我们可以屏蔽掉spring boot对es的自动配置。然后根据spring-data-es的api自行进行bean的配置。