Timbo Site

write something


Spring Boot项目中指定依赖版本

端午节前将Spring Boot的版本升级到2.3.1.RELEASE之后,假期回来的第一天就推送上线,最近线上系统开始爆一些奇奇怪怪的错误,比如:

paho3625270288893656: Timed out as no activity, keepAlive=60,000,000,000 lastOutboundActivity=4,391,824,700,168,296 lastInboundActivity=4,391,767,474,515,409 time=4,391,884,700,372,796 lastPing=4,391,824,700,242,264

或:

Lost connection: Timed out waiting for a response from the server; retrying...

怀疑是系统压力过大,处理不过来导致的,而系统在极低的负载时爆出过很多次。检查了一圈怀疑是Paho的版本有问题,Spring Boot 2.3.1.RELEASE指定的Paho是1.2.2,升级前是1.2.0,目前最新版本是1.2.4,扫了一眼Release Notes,感觉1.2.1有好多fix…和领导商量了一下,宁愿降级而不愿意升级,用1.2.0跑了好长时间一点问题都没有,那么就降吧。

使用Spring Boot Gradle Plugin Reference的做法

项目由于使用了Gradle构建,所有的依赖都交给了Spring Boot Gradle Plugin进行管理,在引入依赖的时候做好对齐就好了,即使手动引入一个较高或者较低的依赖版本,在打包的时候仍然会被替换为Plugin管理的版本,在IDEA中还会显示手动引入的依赖版本与Plugin的管理版本

Spring Boot Gradle Plugin Reference提及了可以自定义版本,同时也提醒了:Each Spring Boot release is designed and tested against a specific set of third-party dependencies. Overriding versions may cause compatibility issues and should be done with care.

Reference的推荐做法是在Spring Boot管理的依赖中找到对应的version property,通过在build.gradle中指定版本达成目的,如:

ext['slf4j.version'] = '1.7.20'

在这个名单找不到Paho的版本,Paho被Spring Integration MQTT所引用,Spring Integration MQTT还引用了其他很多工具的依赖,我只需要修改Paho的版本就好,Reference提及的做法不能奏效。

使用Gradle DependencyHandler的做法(Deprecated)

参照Gradle DependencyHandler中的配置:

Examples of advanced dependency declaration including:
- Forcing certain dependency version in case of the conflict.
- Excluding certain dependencies by name, group or both. More details about per-dependency exclusions can be found in docs for ModuleDependency.exclude(java.util.Map).
- Avoiding transitive dependencies for certain dependency.

在手动引用依赖的时候,声明依赖的版本为强制指定,如:

api('org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0') {
  force = true
}

repackaging之后Paho就被替换为指定的版本。

7月28日更新

使用Gradle 6.5.1进行编译的时候,会报出类似这样的警告,提示force已经deprecated

Using force on a dependency has been deprecated. This is scheduled to be removed in Gradle 7.0. Consider using strict version constraints instead (version { strictly ... } }). Consult the upgrading guide for further information: https://docs.gradle.org/6.5.1/userguide/upgrading_version_5.html#forced_dependencies
        at build_9if64uacdsc2chil7ttftfqty$_run_closure1$_closure2.doCall(/Users/timbo/Projects/some-project/build.gradle:10)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)

更推荐使用strictly来指定版本,如:

api('org.eclipse.paho:org.eclipse.paho.client.mqttv3') {
  version {
    strictly '1.2.0'
  }
}

另外,在Spring Boot 2.3.2.RELEASE中,把Spring Integration升级至5.3.2.RELEASE:https://github.com/spring-projects/spring-integration/releases/tag/v5.3.2.RELEASE

该版本将Paho升级至1.2.4版本,修复了Paho keepalive的问题:https://github.com/spring-projects/spring-integration/issues/3348

将Spring Boot升级到2.3.2.RELEASE版本就解决了该问题,不需要额外再指定版本。