美文网首页
httpclient与httpcore版本不匹配导致的编译问题

httpclient与httpcore版本不匹配导致的编译问题

作者: rockops | 来源:发表于2017-12-14 00:10 被阅读1645次

httpclient与httpcore版本不匹配导致的编译问题

一、起因
maven编译报错

[ERROR] 无法访问org.apache.http.annotation.ThreadSafe
找不到org.apache.http.annotation.ThreadSafe的类文件

看本地的确不存在ThreadSafe这个文件,为什么会出现这个情况呢,升级之前还不存在这个问题,怀疑是jar包版本冲突导致的。
Google了下发现ThreadSafe是httpcore 4.4.4中的一个注解文件,将pom中httpcore的版本修改为4.4.4之后错误消失。

问题消失了不代表事情就可以结束了,原因是什么,为什么会出现这个问题? 做技术要有打破砂锅问到底的精神。

看项目中有很多文件有用到ThreadSafe这个注解,主要是有两个jar包,一个是httpclient, 一个是它自己所在的包httpcore。查看httpclient的pom.xml,写的也比较明确,httpclient会依赖于httpcore包.

<dependencies>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpcore</artifactId>
      <scope>compile</scope>
    </dependency>
    ...
</dependencies>

groupId, artifactId比较容易理解,用于确定jar包的坐标,<scope>表示范围,<version>在哪儿呢?

查看httpclient在META-INF/DEPENDENCIES中写明了Apache HttpCore org.apache.httpcomponents:httpcore:jar:4.4.4。需要依赖于4.4.4的版本。我怀疑DEPENDENCIES文件只是起到一个说明作用,并不会做什么动作。应该是这样的,本身我的项目是spring-boot的,spring boot支持对jar包的版本进行统一管理,这个不在本章展开。

二、关于scope
我们在httpclient中看到了dependency的依赖范围是compile,这个scope还有哪些枚举值呢? 都代表什么意思? scope有6个枚举值, 分别如下

  • compile, 默认值。表示这个依赖的jar包需要在build、test、run的时候都在classPath中
  • test, 跑单测的时候会用到这个依赖包
  • system, 依赖本地jar包,不从maven仓库中获取。如果使用system scope,则在<dependency>配置块中需要增加<systemPath>${basedir}\war\WEB-INF\lib\extDependency.jar</systemPath>的说明。
  • import, 只会出现在dependencyManagement部分,dependencyManagement用于“声明”项目所需要的依赖(但不引用),主要为了解决maven没法做到多继承的场景,比如我的模块要继承多个父pom,这个是没法做到的。如果在一个project里边有100个module,每个module的版本都在一个parent pom里边维护的话,太混乱了。这时可以分开把不同类型的依赖包放到不同的"管理pom文件"中(<dependency><type>是pom)进行管理,各个子module分别去import这些pom,这个理念有点类似于interface,区别于parent class
  • providerd, 跟compile很像,需要在build、test时在classPath下,而run的时候不需要,因为已经有容器提供这个包的服务。
  • runtime, 无需编译,但是该依赖的jar包出现在其他的classPath下,可以用于test,run服务

参考:

三、dependencies和dependencyManagement
要理解dependencyManagement需要知道它出现的背景,在一个多模块的工程中,各模块可能会依赖相同的jar包,之前是在每个模块的pom.xml中通过具体jar包的坐标来指定,但可能会造成不同版本之间jar包冲突导致的运行问题。
解决这个问题的方法就是在项目顶层pom.xml文件中使用dependencyManagement声明那些可能用到的jar包以及其版本。子模块通过<parent>标签来指定依赖顶层项目的pom。子模块在写具体的dependencies的时候,就可以不指定jar包的版本,默认会使用<parent>中的dependencyManagement中的版本,从而达到在一个项目中依赖的第三方jar包版本统一的目的。

相关文章

网友评论

      本文标题:httpclient与httpcore版本不匹配导致的编译问题

      本文链接:https://www.haomeiwen.com/subject/xqutwxtx.html