问题发现
近期在搭建jenkins 过程中,由于本地使用的4.10.1 版本在jenkins 后台自动下载的jenkins 列表中没出现,所以升级了该工程的gradle到5.0 版本,升级后就出现了编译错误
/home/microServer/src/main/java/com/zhishan/microserver/DownUtils.java:20: error: package okhttp3 does not exist
import okhttp3.Call;
^
/home/microServer/src/main/java/com/zhishan/microserver/DownUtils.java:21: error: package okhttp3 does not exist
import okhttp3.Callback;
^
/home/microServer/src/main/java/com/zhishan/microserver/DownUtils.java:22: error: package okhttp3 does not exist
import okhttp3.OkHttpClient;
^
问题分析
回顾修改,发现只修改了gradle-wrapper.properties中的gradle 版本号
可以基本断定是gradle 5.0 问题影响,尝试切换回4.10.1 版本后发现编译正常了,验证了该猜想
问题现象是okhttp 类找不着,那就在gradle 4.10.1 下看看okhttp 是怎么引用的
在4.10.1下,可以看到引用的是3.3.1 的okhttp
如何确定该okhttp 的引用是哪个依赖引入的呢,可以通过help组下得dependencies task 查看依赖关系,
E:\ruijie_workspace\whiteboard>gradlew.bat app:dependencies > depend.log
在depend.log 中搜索3.3.1 ,可以看到该引用是okhttputils 引入的
+--- com.zhy:okhttputils:2.6.2
| \--- com.squareup.okhttp3:okhttp:3.3.1
| \--- com.squareup.okio:okio:1.8.0
到这一步可以定位到是哪个依赖出问题了,但具体为何出问题还没发确定
可以知道,开发者上传aar 到远程maven 的时候,除了上传aar 包以外,还需要上传pom 文件以指明该aar 使用了哪些依赖
我们可以把这个com.zhy:okhttputils:2.6.2 的pom文件下下来看看是否有线索
不确定该aar 是在maven 还是jcenter 或是googleCenter 的情况下,我们使用阿里云maven镜像查找该依赖
[https://maven.aliyun.com/mvn/search](https://maven.aliyun.com/mvn/search)
可以看到该aar 的pom文件中,的确有对okhttp3 的依赖,不过有一点比较好奇的是scope=runtime,猜测这可能是影响的原因。
可以知道,scope 属性有几个值:
- compile 默认选项,打包时是包含该代码的
- provided 打包时不包含,仅在编译时作为环境使用
- runtime 打包时不包含,编译时作为环境,实际调用由实际运行时决定
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhy</groupId>
<artifactId>okhttputils</artifactId>
<version>2.6.2</version>
<packaging>aar</packaging>
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.3.1</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
按照理解,scope=runtime 时,:okhttputils不应该包含该okhttp 依赖,但实际上在4.10.1 版本是包含的,到5.0 版本却才不包含了
可以猜到,一定是gradle 5.0 修改了这部分相关逻辑
让我们查阅一下gradle 的release note,可以看到gradle 5.0 的确是区分了runtime 和compile 类型依赖的不同处理方式,在4.x gradle 上,也可以通过enableFeaturePreview('IMPROVED_POM_SUPPORT') 来开启该功能
至此,该gradle 升级后的问题得到解决
[https://docs.gradle.org/5.0/userguide/java_library_plugin.html#sec:java_library_separation](https://docs.gradle.org/5.0/userguide/java_library_plugin.html#sec:java_library_separation)
网友评论