導語
Maven和gradle是現在JAVA世界中最普遍的兩個依賴管理工具。很多人最開始接觸的便是maven,而即便是使用gradle的人,也不能保證你即將接觸的項目不是基於maven的。
相信作為一個JAVA開發者,一定會遇到不少Maven相關的錯誤。這里總結一下一些maven的使用經驗,能解決幾乎所有平時能遇到的棘手問題。
2020年01月15日起 Maven中央倉庫禁止了HTTP訪問,需要修改HTTP為HTTPS才能訪問。
Effective January 15, 2020, The Central Repository no longer supports insecure communication over plain HTTP and requires that all requests to the repository are encrypted over HTTPS.
If you're receiving this error, then you need to replace all URL references to Maven Central with their canonical HTTPS counterparts
參考鏈接
找不到jar,無法在某某倉庫找到jar
解決方案:
以commons-collections為例,
- 檢查是不是網絡問題:
mvn dependency:get -Dartifact=org.apache.commons:commons-collections4:4.4
。 - 如果不能下載,則可能是倉庫問題,需要去
https://mvnrepository.com/
查找該jar所在的倉庫,一般來說 central的jar,下載失敗,肯定是因為網速問題。如果一些jar不在central,例如:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0-cdh5.13.2</version>
</dependency>
網站會提示:Note: this artifact it located at Cloudera Rel repository (//repository.cloudera.com/content/repositories/releases/)
那么,要么你的項目pom.xml需要配置 repository要么 在 MAVEN_HOME/conf/settings.xml中的profile中配置全局repository
IDEA中,某一個依賴的import報紅,或者某一個方法報 cannot resolve symbol之類的,而其實是可以用mvn package打包的,就是不能在本地運行。
解決方案:
- 可能的原因有,本地倉庫的jar在網絡傳輸中損壞,刪除掉重新下載。
- 重新下載的方式有 點擊右側刷新reimport,以及手動下載,執行
mvn dependency:get -Dartifact=$groupId:$artifactId:$version
。 - 最后一個終極解決辦法,無需重新安裝IDEA,無需invalid Cache And Restart,直接退出IDEA,刪除
%USERPROFILE%\.IdeaIC2019.3\system\Maven
,重新打開IDEA,IDEA會update maven indices。 - 對於IDEA 2020.1.x的版本,位置變成了
%APPDATA%\Local\JetBrains\IdeaIC2020.1\Maven
- 如果你曾經手動刪除過local Repository的某一個文件夾,這個緩存就對不上了,特別容易出現這個問題。
IDEA中,有一個已知的非中央倉庫的,特別是私服的jar,如果IDEA點擊刷新reimport報錯:cannot resolve $groupId:$artifactId:$version
解決方案:
- 可手動下載
mvn dependency:get -Dartifact=$groupId:$artifactId:$version
- 如果1不行,則參考上述刪除緩存的方案,如果是401 unauthorzied之類的,則檢查settings.xml語法是否正常,Server的賬戶密碼是否正確。
maven下載慢
maven鏡像服務器是肯定需要配置的,有華為雲,騰訊雲,阿里雲鏡像服務器,又快又穩。注意,每個人所在的公司的網絡環境可能有所不同,訪問阿里雲不一定是最快的,或者訪問騰訊雲不是最快的,甚至很慢。
可以在構建項目的時候多做測試。
下面給出最快的Maven三個鏡像服務器
<!-- 阿里雲倉庫 -->
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun-maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
<!-- 中央倉庫1 -->
<mirror>
<id>repo1</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>https://repo1.maven.org/maven2/</url>
</mirror>
<!-- 中央倉庫2 -->
<mirror>
<id>repo2</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>https://repo2.maven.org/maven2/</url>
</mirror>
<!-- 騰訊雲 -->
<mirror>
<id>nexus-tencentyun</id>
<name>Nexus tencentyun</name>
<url>http://mirrors.cloud.tencent.com/nexus/repository/maven-public/</url>
</mirror>
<!--華為雲 -->
<mirror>
<id>huaweicloud</id>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
</mirror>
常見的誤區
注意,99%的JAR都是在中央倉庫的,還有一些在公司的私服,也就是nexus repository,還有一些在第三方開源倉庫,例如SpringPlugins:
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26.cloudera.4</version>
</dependency>
Note: this artifact it located at Spring Plugins repository (//repo.spring.io/plugins-release/)
因此鏡像服務器不要上來就配mirrorOf *, 這個表示所有的jar都從這里下載,這肯定是不行的。
<mirror>
<id>alimaven</id>
<mirrorOf>*</mirrorOf>
<name>aliyun-maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
正確做法是
<mirrorOf>external:*</mirrorOf>
或者是
<mirrorOf>central</mirrorOf>
external表示URL是127.0.0.1或者localhost以外的
參見https://github.com/apache/maven/blob/maven-3.3.9/... external的源碼
另外,對於公司自己的私服,肯定是要在mirrorOf里面排除的,假設私服的id是 snaps,不論是在 pom.xml還是在 settings.xml的profiles里面的repository內配置了這個私服,
在mirror中的寫法:
<mirrorOf>external:*,!snaps</mirrorOf>
而且對於某一個找不到jar的依賴,應該養成習慣,第一時間檢查這個artifact是不是在maven中央倉庫,是不是在某一個第三方倉庫。如果在某一個第三方倉庫,則把它加入到自己的pom.xml中,或者全局配置。
除此以外,還可以將這個倉庫加入自己私服的PROXY代理中。