第三方库的更新和升级

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2014/03/30/update_depend_library/

模块化、代码重用等思维的引领下,各种不同功能的库不断出现,基本涵盖了所有功能需求,极大加速了软件开发效率。

另一方面,包管理工具的流行简化了引用过程。不再需要下载库文件,添加到项目目录。

第三方库也是一种产品,一样存在生命周期,这样就会有升级的问题产生。

为什么要升级

第三方库也是人创造的,同样会有效率,代码质量等问题。伴随着升级会有各种修复、优化和新的特性。

及时的升级可以排除潜在的bug,提升效率,如果有需要还可以根据API的升级简化代码并优化流程。

对于一个成熟的、经过广泛验证的第三方库,比如Spring、Hibernate等等。它们的方方面面经过时间的考研,在一个稳定的版本范围内都是可信的。所谓的版本范围是指标准版本号

如果第三方依赖库的管理是手动的,那么升级的步骤就很无趣了。你需要定期访问你所使用的库的主页,检查是否有升级,然后手动下载新版本,覆盖旧版本。

如果使用包管理工具或者构建工具,如npm、gradle等,那么升级就比较简单了,直接修改配置本身然后执行更新命令就可以完成了。

Gradle中的版本管理

npm很方便,使用也简单,所以下面的例子都是以gradle为例的。

在gradle中如果你需要引入一个第三方包,你只需要在配置中写道:

apply plugin:'java'

repositories {
mavenCentral()
}

dependencies {
compilegroup:'org.hibernate', name:'hibernate-core', version:'3.6.7.Final'
testCompilegroup:'junit', name:'junit', version:'4.11'
}

这样gradle就可以自动下载相关的库,而当你需要升级的时候你只需要修改version配置即可。

当然更多的人可能习惯偏好更紧凑的写法:

dependencies {
compile'org.hibernate:hibernate-core:3.6.7.Final'
testCompile'junit:junit:4.11'
}

不过以上的修改都需要你在一大篇缩进不同的字符串中来回寻找,特别是以下情况的时候你可以就觉得有点不方便了:

testCompile(
"org.hamcrest:hamcrest-core:1.3",
"org.hamcrest:hamcrest-library:1.3"
)

最简单也是最具可读性的方法是把版本号抽取出来作为项目的配置:

project.ext {
hamcrestVersion ='1.3'
}

testCompile(
"org.hamcrest:hamcrest-core:$hamcrestVersion",
"org.hamcrest:hamcrest-library:$hamcrestVersion"
)

这样所有的升级只需要修改hamcrestVersion了。

当然有时候你需要一个更宽松且智能的版本号,比如2.5.+。

你需要的是主版本号为2,副版本号为5的最新的第三方依赖库。如果这个库是严格遵循版本规范的,那么你就可以享受不断修复的稳定版本了。

如果了解最新的版本

带‘+’号的版本号可以享受到便利性,但是它也是有局限和风险的。比如’2.5.+’比’2.+’更谨慎。

还有一种极端的情况,比如你使用的是’0.2.+’,结果新版本已经是’0.6.+’。
其实这种情况也不是多么罕见…至少我前些日子才发现我一直使用async依赖就是这样的。

当然可以通过访问官方网站来了解当前的版本号,但是这样未必太麻烦了,我一般采用两种方法来操作。

一是使用依赖版本跟踪服务,比如david-dm,它可以监控你的nodejs依赖。

界面效果

还可以查看当前版本到最新版本的CHANGELOG。

ChangeLog追踪

这样你可以很方便的更新版本了。

如果没有相关的服务,获取你的项目不方便暴露给其他服务商,还有一个方法就是使用其他工具。

原理上比较简单,因为管理工具获取第三方依赖库一般是从仓库中提取,这样可以直接比较仓库中最新的版本了。

Gradle有一个插件gradle-versions-plugin,可以通过执行

gradle dependencyUpdates -Drevision=release

来获取相关版本更新情况

The following dependencies are using the latest release version:
-- com.google.inject:guice:3.0
-- com.google.inject.extensions:guice-multibindings:3.0
-- com.google.inject.extensions:guice-servlet:3.0
-
-The following dependencies exceed the version found at the release revision level:
-- org.scalatra:scalatra [2.3.0-SNAPSHOT <- 2.2.0-RC1]
-- org.scalatra:scalatra-auth [2.3.0-SNAPSHOT <- 2.2.0-RC1]
-- org.scalatra:scalatra-specs2 [2.3.0-SNAPSHOT <- 2.2.0-RC1]
-
-The following dependencies have later release versions:
-- com.amazonaws:aws-java-sdk [1.3.21.1 -> 1.3.26]
-- com.beust:jcommander [1.27 -> 1.30]

保证自身程序的正常工作

版本的升级可能带来一些风险,比如API的变动会导致程序的bug,一般有以下几种情况:

  • API显性变动

比如方法名或者参数变化会直接导致程序编译无法通过,很容易辨别和修复。

  • API隐形变动

这种变动比较容易忽略,比如client.get(url)升级后默认不开启缓存,而你确需要使用缓存。

  • 功能性移除

这种情况在一些第三方库处于beta时很常见,不再提供某种方法和功能等等。

这些情况都只能通过一些测试和细心来小心处理了。

参考资料

Version Number
Gradle Dependency
gradle-versions-plugin

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载自夜明的孤行灯

本文链接地址: https://www.huangyunkun.com/2014/03/30/update_depend_library/

发表评论