断网环境中的Maven使用
背景诉求:
最近在帮助银行内网环境中搭建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这两个内容,导致失败。