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 即可。