背景訴求:
最近在幫助銀行內網環境中搭建Java開發環境,其中使用到了Maven來進行項目管理。按照之前的理解,我在外網環境下把整個項目的框架先搭建好,然后把相關的文件,比如項目文件,Maven本地倉庫等等拷貝進內網的電腦里面即可。
使用到:Spring Cloud相關的依賴。
問題:
在實際操作中,雖然Maven本地倉庫的所有文件都已經拷貝進入了內網機器上,但是在運行項目工程的時候,還是出現了問題,導致無法正常啟動。
定位問題:
先補充下Maven相關知識:
1、對於Maven安裝文件中的conf/setting.xml文件,其中有一項<mirror></mirro>:
<mirror> <id>alimaven</id> //表示此鏡像的id <mirrorOf>central</mirrorOf> //表示它是哪個遠程公開倉庫的鏡像,這里表示是是central的中央倉庫 <name>aliyun maven</name> //此鏡像的名稱 <url>http://maven.aliyun.com/nexus/content/repositories/central/</url> //此鏡像的地址 </mirror>
2、本地倉庫地址:
<!-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> -->
正常來說,Maven讀取POM文件中的依賴時,會按照:本地倉庫>>setting 中指定的遠程倉庫>>POM文件中指定的遠程倉庫。
3、離線模式:離線模式決定了在通過Maven進行build時,是否會連接互聯網
<!-- offline | Determines whether maven should attempt to connect to the network when executing a build. | This will have an effect on artifact downloads, artifact deployment, and others. | | Default: false <offline>true</offline> -->
按照網絡上的說法我們先嘗試使用離線模式:
使用Idea中Maven離線模式
然后再在終端窗口運行:
mvn clean compile -o
發現還是報錯,大意是無法從遠端倉庫同步信息下來
[ERROR] Plugin org.springframework.boot:spring-boot-maven-plugin:2.3.0.RELEASE or one of its dependencies could not be resolved: Failed to read artifact descriptor
for org.springframework.boot:spring-boot-maven-plugin:jar:2.3.0.RELEASE: Could not transfer artifact org.springframework.boot:spring-boot-maven-plugin:pom:2.3.0.R
ELEASE from/to alimaven (http://maven.aliyun.com/nexus/content/repositories/central/): maven.aliyun.com: Unknown host maven.aliyun.com -> [Help 1]
參考文章:
https://blog.csdn.net/u010843886/article/details/81322664 說需要把本地倉庫地址以及mirror鏡像地址都指向本地倉庫的文件地址所在。
https://blog.csdn.net/xingxing513234072/article/details/78191505 說需要開啟offline 模式
即做以下設置
<localRepository>C:/Users/sliec/.m2/repository</localRepository> ..... <!-- offline | Determines whether maven should attempt to connect to the network when executing a build. | This will have an effect on artifact downloads, artifact deployment, and others. | | Default: false <offline>true</offline> --> <offline>true</offline>
...
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>file://C:/Users/sliec/.m2/repository </url>
</mirror>
嘗試過后還是不行。
這時提示說:
Cannot access nexus-aliyun in onffline mode and the artifact org.springframework.boot:spring-boot-starter-parent:pom:2.3.0.RELEASE has not been download from it before
最終解決辦法:
在復制Maven相關文件時,需要把當前能夠聯網的環境下,Maven程序包,重點是配置文件,加上此時此刻的本地倉庫文件一並復制。
原因在於,Maven配置文件中,執定了mirror相關的內容,然后這里存在一個mirror本身的id,然后在本地倉庫中,每一個依賴包里面,都存在着一份名為:_remote.repositories的文件,這個文件記載了類似下面的這些內容:
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Fri May 29 15:05:16 CST 2020
spring-web-5.2.6.RELEASE-javadoc.jar>alimaven= //這個地方和setting.xml中的mirrorid需要保持一致
spring-web-5.2.6.RELEASE.jar>alimaven=
spring-web-5.2.6.RELEASE.jar>central=
spring-web-5.2.6.RELEASE.pom>alimaven=
spring-web-5.2.6.RELEASE.pom>central=
spring-web-5.2.6.RELEASE-sources.jar>alimaven=
也就是說,這一份依賴包是從哪里下載來下的,上面的示例就表示是從倉庫id為 :alimaven,central的遠程倉庫下載下來的。
setting.xml中的mirror配置內容:
<mirror> <id>alimaven</id>//重點注意這個,需要和本地倉庫里下載的依賴記錄文件_remote.repositories 一致 <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/repositories/central/</url> </mirror>
如果這份列表里面記載的倉庫id,與我們使用的Maven配置文件setting.xml當中配置的mirrorid不一致,那么,我們在局域網電腦中重新通過maven進行構建時,maven會認為本地倉庫里存的這份依賴,和配置的遠程鏡像地址不是一個源,因此不能直接使用。
此時,它會嘗試根據setting.xml中配置的鏡像地址,去獲取新的依賴文件,結果,這時候時局域網,訪問不到鏡像,所以會報錯,並且提示你鏡像無法訪問,而且這個依賴之前沒有下載下來。(感覺這個邏輯也很奇怪,你直接按照我的artifactId去庫里定位就完了啊,還比較來源干什么)
而我之前拷貝本地倉庫和項目工程進辦公環境之后,由於自己不注意,改了setting.xml文件中的mirrorid,和本地倉庫地址localRepository這兩個內容,導致失敗。