1.问题描述
因公司项目调整,需要为jar包添加版本号。之前jar包命名格式一直是XXXX.0.0.1-SNAPSHOT.jar。修改后的格式是XXXX.1.0.0.${environment}.jar(environment:DEV、TEST、RELEASE)。修改之后通过jenkis构建gralde项目时却报错,提示找不到依赖的某模块A中的代码。
2.问题排查
出现这种问题,第一想法是依赖的模块没有上传到私有代码仓库,导致部署时拉取的依赖jar包还是历史jar包。但是通过观察代码仓库jar包的生成时间确实是最新的,而且反编译jar包之后,代码也是最新的。既然代码是最新的,那么就说明gradle构建项目时,没有从仓库拉取最新的jar包。但是为什修改jar包命名格式之前并没有这种问题呢?
带着这种疑问通过网上搜索,最终发现加和不加SNAPSHOT的区别如下:
1.加了SNAPSHOT后缀,gradle会认为该jar包只是快照版本,是不稳定的,会经常性更新的。这种状态下,我们修改jar包的内容后不需要修改版本号,相同版本的jar包也是可以被覆盖为最新的。
2. 不加SNAPSHOT后缀时,表示该jar包是稳定版本,只有更新版本号才会覆盖历史jar包。
看到这里我们也就清晰了,由于我们的jar包没有加SNAPSHOT后缀,gradle会认为是稳定版本,而且我们又没有变更版本号,因此导致不会拉取最新jar包,那要怎么解决呢?有两种办法如下:
1. 在build.gradle中引用的模块中添加changeing=true,当加了changing=true 就和添加标记SNAPSHOT后缀功能是一样的。
implementation("io.dushu.login:login:1.0.0-SNAPSHOT") {
changing true
}
当使用SNAPSHOT或者changing=true时,我们需要增加以下配置,这是因为gradle存在缓存机制默认是24小时,我们可以通过最外层build.gradle配置将gradle缓存时间设置为0,使每次都会拉取最新jar包。
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'
}
2.清空gradle缓存,--refresh-dependences,我们通过jenkis配置,每次gradle构件项目时都清楚缓存。
3.maven项目pom依赖中scope标签的使用
pom.xml中
<dependency>
<groupId>com.github.wxiaoqi</groupId>
<artifactId>ace-common</artifactId>
<version>2.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
maven项目中,如果存在编译需要而发布不需要的jar包,可以用scope标签,值设为provided。
Scope标签的其他值如下:
compile
:默认的scope,表示 dependency 都可以在生命周期中使用。
而且,这些dependencies 会传递到依赖的项目中。适用于所有阶段,会随着项目一起发布
provided
:跟compile相似,但是表明了dependency 由JDK或者容器提供,例如Servlet AP和一些Java EE APIs。这个scope 只能作用在编译和测试时,同时没有传递性,即:child module无法引用。
runtime
:表示dependency不作用在编译时,但会作用在运行和测试时,如JDBC驱动,适用运行和测试阶段,与provided相反。
test
:表示dependency作用在测试时,不作用在运行时。 只在测试时使用,用于编译和运行测试代码。不会随项目发布。
system
:跟provided 相似,但是在系统中要以外部JAR包的形式提供,maven不会在repository查找它。