Maven中GeoTools的引入 - Maven 的 repository 与 mirror

Maven中GeoTools的引入 - Maven 的 repository 与 mirror

在Maven中引入GeoTools时找不到jar包,搜索了蛮久才明白是自己maven没有学明白,于是重学了一次maven,解决了这个问题。关键在于理解maven中仓库(repository)与镜像(mirror)的关系与使用。

@

一、问题描述

起因是这样的,我想要引入GeoTools包,却发现即使按照官方quick start来操作,也没有引入成功,始终是找不到jar包,百思不得其解。

按照官网和谷歌百度搜索的结果看
要使用GeoTools,首先引入需要的GeoTools的模块。GeoTools有很多模块,如shapefile,csv等。
这个是我要引入的geojson模块

<dependency>
   <groupId>org.geotools</groupId>
   <artifactId>gt-geojson</artifactId>
   <version>19.0</version>
</dependency>

然后添加GeoTools官方的仓库

<repository>
   <id>osgeo</id>
   <name>OSGeo Release Repository</name>
   <url>https://repo.osgeo.org/repository/release/</url>
   <snapshots><enabled>false</enabled></snapshots>
   <releases><enabled>true</enabled></releases>
</repository>
<repository>
   <id>osgeo-snapshot</id>
   <name>OSGeo Snapshot Repository</name>
   <url>https://repo.osgeo.org/repository/snapshot/</url>
   <snapshots><enabled>true</enabled></snapshots>
   <releases><enabled>false</enabled></releases>
</repository>

但就是找不到jar包
在这里插入图片描述
dependencies也是报错
在这里插入图片描述

后来尝试将仓库以镜像的方式写入到settings.xml之中,结果发现可行了。(当然后续发现这种方法是错误的解决方案,正确的做法在后面)

二、原理说明

出错原因: 没有理解清楚maven的repository与mirror的关系,错误地将阿里云镜像的mirrorOf参数值设置为*(星号,表示匹配全部仓库)(正确的参数值为central)

为了让各位更好地理解这个问题,有必要占用一些篇幅介绍一下maven的基本信息和相关概念。

2.1 maven的主要功能

以下描述摘自维基百科:

Maven是一个主要用于Java项目的构建自动化工具。Maven还可以用来构建和管理使用c#、Ruby、Scala和其他语言编写的项目。Maven项目由Apache软件基金会托管,它以前是Jakarta项目的一部分。

Maven解决了构建软件的两个方面:如何构建软件及其依赖关系。

maven的主要功能有两个:一个是解决项目的构建:包括编译(build)测试(test)打包(package)部署(deploy)等,maven使用生命周期的概念描述这一过程,并通过插件实现和控制项目构建各个阶段的执行。

下图为完整的maven生命周期
在这里插入图片描述
maven的另一个功能就是解决项目之间的依赖关系从仓库(repository)自动下载需要的jar包

maven使用项目对象模型(Project Object Model,POM)实现对项目的抽象和管理。

项目对象模型(POM)提供了单个项目的所有配置。一般配置包括项目的名称(name)、所有者(owner)及其对其他项目的依赖关系(dependencies)。还可以配置构建过程的各个阶段,这些阶段以插件(plugins)的形式实现。

默认情况下,所有的POM都继承自超级POM。超级POM提供默认配置,比如默认源目录、默认插件等等。

maven将约定大于配置作为其设计理念,约定了一些默认的配置,如项目的默认结构,对某个项目坐标、依赖和插件的规定的配置方法(IDE通常会帮助检查配置项的正确性)等。

下图表示默认的maven项目目录:
maven的默认配置

2.2 仓库

所有的maven项目都存储在服务器上,该服务器被抽象为仓库(repository),当用户需要某些jar包时就可以从仓库中下载。

maven通过超级POM机制配置了默认的仓库。由于所有的POM都隐式地继承自超级POM,超级仓库中配置了中央仓库,因此所有的项目默认配置了中央仓库

对于 Maven3,超级 POM 在文件 %MAVEN_HOME%/lib/maven-model-builder-x.x.x.jar 中的
org/apache/maven/model/pom-4.0.0.xml 路径下、

对于 Maven2,超级 POM 在文件 %MAVEN_HOME%/lib/maven-x.x.x-uber.jar 中的
org/apache/maven/project/pom-4.0.0.xml 目录下。

默认配置的部分内容如下:

  <repositories>
    <repository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

  <pluginRepositories>
    <pluginRepository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <updatePolicy>never</updatePolicy>
      </releases>
    </pluginRepository>
  </pluginRepositories>

我们可以自己添加仓库,如我添加了提供GeoTools相关包的仓库,id为osgeo,url地址为https://repo.osgeo.org/repository/release/

在项目的pom.xml中加入仓库配置:

<repository>
   <id>osgeo</id>
   <name>OSGeo Release Repository</name>
   <url>https://repo.osgeo.org/repository/release/</url>
   <snapshots><enabled>false</enabled></snapshots>
   <releases><enabled>true</enabled></releases>
</repository>

2.3 镜像

由于maven的中央仓库在国外,国内访问速度较慢,一般我们采用配置镜像(mirror)的方式从国内的镜像服务器中下载资源。

maven根据setting.xml文件中配置的镜像拦截发往原仓库的请求,并将其转发到镜像仓库。

即:当一个镜像的mirrodOf参数与某个仓库的id参数相匹配,就向该镜像请求资源,否则向原仓库请求资源。

阿里云镜像是常用的maven镜像之一,其镜像了中央仓库的所有资源。

setting.xml文件中阿里云镜像的配置如下:

<!-- 阿里云镜像 -->
<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>central</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

setting.xml文件中,我们设置阿里云镜像的mirrorOf属性为central,以此去匹配id属性为central的中央仓库。这样所有对中央仓库发起的请求,都会被转发给阿里云镜像,大大提高了资源的下载速度。

2.4 仓库与镜像的关系

当我们配置了多个仓库多个镜像时,maven执行的策略为:

  1. maven根据镜像配置文件(setting.xml)自上至下地依次查看所有的镜像,对每一个仓库依次进行匹配,并使用第一个匹配上的镜像。被镜像匹配的仓库,仓库的url被替换为镜像的url,没有匹配的仓库,url不变。
  2. 查询各仓库是否包请求的资源(项目),如都没有,则报错(如未找到),否则从第一个匹配上的仓库拉取资源。
    在这里插入图片描述在这里插入图片描述

三、解决方案与小技巧

  1. 不是所有的jar包都被包含在maven中央仓库中,如果中央仓库没有该资源,就需要配置第三方仓库(也可以理解为别人的公开私服)。maven中央仓库不包含GeoTools的相关资源,因此需要单独配置OSGeo Release Repository仓库。
  2. 阿里镜像和清华镜像只提供对中央仓库的资源镜像mirrorOf属性的值只能设置为central不要设置为* 。如果设置为*,则所有仓库的url都会被替换,对于本文的情况,就是本来应当发往OSGeo Release Repository仓库的请求被发往阿里云镜像,而阿里云镜像不包含GeoTools的资源,自然是找不到了。正确的做法是每个镜像的mirrorOf属性应与该镜像对应的仓库的id属性保持一致。
  3. 还有一种骚操作(错误操作),就是在setting.xml将仓库作为镜像配置进去。由于maven的镜像机制,仓库的url会被替换为第一个匹配上的镜像,那么在阿里云镜像之前添加一个(伪)仓库镜像,也可以解决问题。但是这个方法肯定是错误用法(但是很骚)。

错误配置
setting.xml

<!-- 阿里云镜像 -->
<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>*</mirrorOf> <!-- 正确的属性为central -->
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

或者

<!-- osgeo(伪)镜像 -->
<mirror>
    <id>mirror-osgeo</id>
    <mirrorOf>osgeo</mirrorOf>
    <name>Mirror Osgeo</name>
    <url>https://repo.osgeo.org/repository/release/</url>
</mirror>
<!-- 阿里云镜像 -->
<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>*</mirrorOf> <!-- 正确的属性为central -->
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

pom.xml

<repository>
   <id>osgeo</id>
   <name>OSGeo Release Repository</name>
   <url>https://repo.osgeo.org/repository/release/</url>
   <snapshots><enabled>false</enabled></snapshots>
   <releases><enabled>true</enabled></releases>
</repository>

正确配置
setting.xml

<!-- 阿里云镜像 -->
<mirror>
    <id>nexus-aliyun</id>
    <mirrorOf>central</mirrorOf>
    <name>Nexus aliyun</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

pom.xml

<repository>
   <id>osgeo</id>
   <name>OSGeo Release Repository</name>
   <url>https://repo.osgeo.org/repository/release/</url>
   <snapshots><enabled>false</enabled></snapshots>
   <releases><enabled>true</enabled></releases>
</repository>

四、如何知道是否需要配置仓库?

在maven的官网可以查询相关项目的信息,项目页面的标签栏标识了存储了该项目的仓库,只要是存储在中央仓库的项目都会标识Central标签,此时就不用配置新的仓库。在这里插入图片描述
如果标签栏中没有标识Central仓库,说明中央仓库不包含该项目,需要配置新的仓库。
如对于GeoTools包,从图中我们可知,由于Central仓库不包含该包,我们就需要从其标签栏标识的GeoSolutions仓库、Geomajas仓库、Boundless仓库或OSGeo仓库拉取GeoTools包的资源。
在这里插入图片描述
参考资料:
https://en.wikipedia.org/wiki/Apache_Maven
https://www.cnblogs.com/shengulong/p/8295453.html maven的超级pom

如果这篇文章对你有用,可以点个赞再走哦~~

posted @ 2020-04-09 16:52  天空树快递  阅读(9133)  评论(3编辑  收藏  举报