這個Maven依賴的問題,你敢說你沒遇到過

  • 2020 年 5 月 30 日
  • 筆記

Maven 依賴沒處理好的話經常會導致發生一些問題,非常煩。今天給大家分享一個依賴相關的問題,說不定你之前就遇到過。

問題背景

有個 ES 搜索的項目,剛開始還是好好的狀態,過了一段時間,然後就發現啟動時報錯了。看了下 Git 提交日誌,也沒有改動過,神奇的程式碼世界。

錯誤如下圖所示,很明顯的錯誤,經常會碰到,肯定是依賴版本的問題。

kitty-spring-cloud-starter-elasticsearch 是我自己封裝的,裡面用的版本是 6.8.7。最開始測試的時候也是正常的,這突然就不行了。我看了下目前項目的依賴,發現變成了 6.4.3。所以才找不到 CountRequest 這個類。

問題原因

這麼看來,應該是我的項目中哪裡已經有了版本的限制,覆蓋了 kitty-spring-cloud-starter-elasticsearch 定義的 6.8.7 版本。

在項目的父 pom 中也沒找到對應的配置,唯一有可能的就是 Spring Boot 中了。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath />
</parent>

在 spring-boot-dependencies 中找到了 6.4.3 的配置。

<elasticsearch.version>6.4.3</elasticsearch.version>
<dependency>
  <groupId>org.elasticsearch</groupId>
  <artifactId>elasticsearch</artifactId>
  <version>${elasticsearch.version}</version>
</dependency>
<dependency>
  <groupId>org.elasticsearch.client</groupId>
  <artifactId>transport</artifactId>
  <version>${elasticsearch.version}</version>
</dependency>
<dependency>
  <groupId>org.elasticsearch.distribution.integ-test-zip</groupId>
  <artifactId>elasticsearch</artifactId>
  <version>${elasticsearch.version}</version>
  <type>zip</type>
</dependency>
<dependency>
  <groupId>org.elasticsearch.plugin</groupId>
  <artifactId>transport-netty4-client</artifactId>
  <version>${elasticsearch.version}</version>
</dependency>
<dependency>
  <groupId>org.elasticsearch.client</groupId>
  <artifactId>elasticsearch-rest-client</artifactId>
  <version>${elasticsearch.version}</version>
  <exclusions>
    <exclusion>
      <artifactId>commons-logging</artifactId>
      <groupId>commons-logging</groupId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.elasticsearch.client</groupId>
  <artifactId>elasticsearch-rest-high-level-client</artifactId>
  <version>${elasticsearch.version}</version>
</dependency>

我們都知道如果父 pom 中 dependencyManagement 定義了版本的話,子模組中可以不用指定版本,直接依賴父 pom 的版本,我們這裡就是因為沒有強制指定,所以用了最頂層父 pom 定義的版本。

下圖就是我們 pom 的依賴關係:

問題解決

在使用項目的 pom 中直接定義版本,優先順序高於父 pom 的定義,這樣才可以強制使用我們需要的版本。只能在 kitty-cloud-search.pom 中定義才可以。

<dependency>
    <groupId>com.cxytiandi</groupId>
    <artifactId>kitty-spring-cloud-starter-elasticsearch</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <groupId>org.elasticsearch.client</groupId>
        </exclusion>
        <exclusion>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>6.8.7</version>
    <exclusions>
        <exclusion>
            <artifactId>elasticsearch-rest-client</artifactId>
            <groupId>org.elasticsearch.client</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>6.8.7</version>
</dependency>

這樣做能解決問題,始終感覺不是很好。

如果想規避這個問題,除非說我們就用 spring boot 已經定義好了的版本,這樣就是一致的了,但總會有一些特殊的需求嘛,雖然你定義了在 2.1.6.RELEASE 版本的 Spring Boot 中 ES 就用 6.4.3,但是我還是想用其他版本的應該也挺常見。

還有一種方式就是如果是公司內部是統一的開發框架的話,你自己可以定義 dependencies 來管理框架的版本,直接把 spring-boot-dependencies 的內容複製一份,然後改掉 elasticsearch.version 的值,最後在項目中就直接用你自定義的 dependencies 即可。