Maven知识分析
Maven知识分析
注:本博文是接着上一章节继续讲解
Nexus-私有仓库的配置
点击左边导航栏的Repositories选项,会显示一个所有仓库及仓库组的列表,Type字段的值有group,hosted,proxy,virtual(在Maven1中使用,这里不需要关心),如图14所示:
图14
在这里:
- hosted,本地仓库,这个仓库主要是用来存放本地的依赖包,服务于局域网,不访问公网
- proxy,代理仓库,用来存放nexus从公网中获取的依赖包,这里有中央仓库,Apache和Codehaus开源网站的依赖包
- group,仓库组,用来合并多个hosted/proxy仓库,通常我们配置maven依赖仓库组
比如点击Type为group,如图15所示:
图15
会发现,在Ordered Group Repositories中,有所有hosted和proxy的仓库,而图15中箭头所指的地方有四种类型的仓库,分别是Releases(hosted), Snapshots(hosted), 3rd Party(hosted),Central(proxy),而Central指的是中央仓库,不知道大家是否还有印象,在本系列第二章节,曾经提到中央仓库的位置,存在于apache-maven-3.1.1\lib\maven-model-builder-3.1.1.jar中的org\apache\maven\model\pom-4.0.0.xml文件中,定义了中央仓库的位置,配置文件如下所示
……………………………………………………………… <repositories> <repository> <id>central</id> <name>Central Repository</name> <url>http://repo.maven.apache.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> ………………………………………………………………其中url指向了中央仓库的位置http://repo.maven.apache.org/maven2,
而Releases, Snapshots, 3rd Party,主要功能如下:
Releases: 这里存放我们自己项目中发布的构建, 通常是Release版本
Snapshots: 这个仓库非常的有用, 它的目的是让我们可以发布那些非release版本, 非稳定版本, 比如我们在trunk下开发一个项目,在正式release之前你可能需要临时发布一个版本给你的同伴使用, 因为你的同伴正在依赖你的模块开发, 那么这个时候我们就可以发布Snapshot版本到这个仓库, 你的同伴就可以通过简单的命令来获取和使用这个临时版本
3rd Party: 顾名思义, 第三方库, 你可能会问不是有中央仓库来管理第三方库嘛, 没错, 这里的是指可以让你添加自己的第三方库, 比如有些构件在中央仓库是不存在的. 比如你在中央仓库找不到Oracle 的JDBC驱动, 这个时候我们就需要自己添加到3rd party仓库
在settings.xml中配置远程仓库
既然这个group已经包含了四个仓库,那么只要将这个组进行配置,在Maven中就会引用所有在这个组对应的仓库中的依赖包,配置的URL地址为http://localhost:8081/nexus/content/groups/public/。我们可以配置在项目中的user-parent的pom.xml文件中,但此时会有个问题,这样的配置仅仅是对当前的项目有效(user-parent是父文件,其子文件继承),如果项目有很多,而不需要每个项目都要进行以上设置,也就是只要设置一次,然后本机的项目就会自动从nexus中寻找依赖包,如何做呢?
Maven仓库组
因为Maven在本机中是同一个,所以只要在Maven所对应的settings.xml中进行配置就好,(本博客settings.xml对应的路径为E:\Workspaces\Maven\settings.xml),配置如下:
………………………………………… <profiles> <profile> <id>nexusProFile</id> <repositories> <repository> <id>localNexus</id> <name>Nexus Repository</name> <url>http://localhost:8081/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <!-- 此选项默认是关闭的,手动打开 --> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> </profiles> <activeProfiles> <!-- 激活上面的配置 --> <activeProfile>nexusProFile</activeProfile> </activeProfiles> …………………………………………Maven中的profile是一组可选的配置,可以用来设置或者覆盖配置默认值。有了profile,你就可以为不同的环境定制构建。
这个时候,做个试验,可以在user-core的pom.xml中加入以下依赖(这个依赖包并不存在于本地或者Nexus仓库中)
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.1.1</version> </dependency>添加好后进行保存,会发现Eclipse的控制台中有如图16的信息:
图16
这表明,Maven已经从通过Nexus下载依赖包了,而Nexus从中央工厂中进行下载。
接着看图17:
图17
这也验证了Nexus已经将mybatis的依赖包下载到了仓库中。
但此时会有个问题,如果将Nexus服务停止,如图18所示
图18
这个时候在user-core的pom.xml中添加原来没有的依赖配置文件(可以随便找个不存在的jar依赖文件进行测试,这里用使用Spring)
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.2.2.RELEASE</version> </dependency>这个时候在Eclipse中点击保存,会发现如下的信息
14-3-7 GMT+0800下午8:29:41: [INFO] Using org.eclipse.m2e.jdt.JarLifecycleMapping lifecycle mapping for MavenProject: com.steven.user:user-core:0.0.1-SNAPSHOT @ E:\Workspaces\STSWorkspace\user-core\pom.xml. 14-3-7 GMT+0800下午8:29:42: [INFO] Number of application's worked threads is 4 14-3-7 GMT+0800下午8:29:44: [INFO] Downloaded http://localhost:8081/nexus/content/groups/public/org/springframework/spring-core/3.2.2.RELEASE/spring-core-3.2.2.RELEASE.pom 14-3-7 GMT+0800下午8:29:44: [INFO] Number of application's worked threads is 4 14-3-7 GMT+0800下午8:29:47: [INFO] Downloading http://repo.maven.apache.org/maven2/org/springframework/spring-core/3.2.2.RELEASE/spring-core-3.2.2.RELEASE.pom 14-3-7 GMT+0800下午8:29:47: [INFO] Downloaded http://repo.maven.apache.org/maven2/org/springframework/spring-core/3.2.2.RELEASE/spring-core-3.2.2.RELEASE.pom ………………………………………………………………………………首先通过Nexus下载,但服务已经关闭,这个时候仍然可以下载,而且通过中央仓库进行下载。但在项目中,不允许本地仓库直接下载中央仓库的依赖包,这个时候就需要进行对中央仓库进行覆盖,使之只能通过Nexus访问中央仓库,这个时候需要对镜像进行配置。
在settings.xml中配置镜像
首先配置镜像,使得只有通过Nexus才可以访问中央仓库
………………………………………………………… <mirror> <id>nexusMirror</id> <mirrorOf>*</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://localhost:8081/nexus/content/groups/public/</url> </mirror> …………………………………………………………这里的*号代表所有的仓库都是通过这个url地址访问,这个时候可以附加一段配置,原来的中央仓库中snapshots版本的依赖包默认是不可以下载的,但可以通过以下配置进行修改
…………………………………… </profiles> …………………………………… <profile> <id>centralProFile</id> <repositories> <repository> <id>central</id> <name>Central Repository</name> <!--由于配置过镜像,这个url不起作用--> <url>http://repo.maven.apache.org/maven2</url> <layout>default</layout> <snapshots> <!--覆盖中央仓库中的false配置,可以从中央仓库中下载snapshot版本--> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile> </profiles> <activeProfiles> <!-- 激活上面的配置 --> <activeProfile>centralProFile</activeProfile> </activeProfiles> ……………………………………这样进行保存后,既可生效。
注意:配置文件settings.xml中会默认有相应的mirror和profile的例子,但都是注释掉的,我们在进行以上的改动时候,可以进行对其复制粘贴后进行修改,这样不容易出错。
验证:(此时没有打开nexus服务)
随便找个不存在的jar依赖文件进行测试,
<dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty</artifactId> <version>6.1.26</version> </dependency>跟刚才的步骤一样,但此时保存后,Eclipse控制台中的信息如下所示:
14-3-7 GMT+0800下午9:13:58: [INFO] Downloaded http://localhost:8081/nexus/content/groups/public/org/mortbay/jetty/jetty/6.1.25/jetty-6.1.25.pom 14-3-7 GMT+0800下午9:13:58: [INFO] Using org.eclipse.m2e.jdt.JarLifecycleMapping lifecycle mapping for MavenProject: com.steven.user:user-service:0.0.1-SNAPSHOT @ E:\Workspaces\STSWorkspace\user-service\pom.xml. 14-3-7 GMT+0800下午9:13:58: [INFO] Number of application's worked threads is 4 14-3-7 GMT+0800下午9:14:02: [INFO] Using 'UTF-8' encoding to copy filtered resources. 14-3-7 GMT+0800下午9:14:02: [INFO] skip non existing resourceDirectory E:\Workspaces\STSWorkspace\user-service\src\main\resources 14-3-7 GMT+0800下午9:14:02: [INFO] Using 'UTF-8' encoding to copy filtered resources. 14-3-7 GMT+0800下午9:14:02: [INFO] skip non existing resourceDirectory E:\Workspaces\STSWorkspace\user-service\src\test\resources这里只能通过Nexus下载依赖包,但是由于服务停止,所以下载失败,而如果此时将服务打开
图19
然后在Eclipse中刷新依赖包所在的pom.xml文件,
如果没有任何问题,则在控制台中显示如下信息:
14-3-8 GMT+0800上午12:00:31: [INFO] Downloading http://localhost:8081/nexus/content/groups/public/org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26.jar 14-3-8 GMT+0800上午12:00:31: [INFO] Downloaded http://localhost:8081/nexus/content/groups/public/org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26.jar但此时可能出现以下问题
[ERROR] Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.5 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-resources-plugin:jar:2.5原因:这是因为在进行配置后,所有本地仓库的依赖包都将通过nexus私有仓库访问中央仓库进行下载,而此时在加载一些Maven插件的时候,由于一开始本地仓库中已经存在,而私有仓库中没有这些依赖包的索引(就是指在nexus中存在对依赖包的GAV标识),这个时候就会容易报错。
解决思路:
思路1:
一开始可以进行对索引更新,具体参照图20所示
图20
这样设置以后, Nexus会自动从远程中央仓库下载索引文件,索引文件很大,需要很久等待时间。
思路2:
错误信息也有如下所示的提示:
Could not calculate build plan: Failure to transfer org.apache.maven.plugins:maven-surefire-plugin:pom:2.7.1 from http://repo1.maven.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer artifact org.apache.maven.plugins:maven-surefire-plugin:pom:2.7.1 from/to central (http://repo1.maven.org/maven2): Access denied to http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/2.7.1/maven-surefire-plugin-2.7.1.pom.解决方案:
1.找到maven库目录,进入:\repository\org\apache\maven\plugins\maven-surefire-plugin\2.7.1
2.若2.7.1目录下只有,"maven-surefire-plugin-2.7.1.pom.lastUpdated" 则需要到http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/2.7.1/,把里面的文件下载下来放到2.7.1文件夹中
3.删除2.7.1下的maven-surefire-plugin-2.7.1.pom.lastUpdated文件。
4.项目右键-->maven-->Update Project即可。
思路3:
首先关掉Eclipse,停止Nexus运行,然后将本地E:\Workspaces\Maven\repository中所有的依赖包删除,然后启动Nexus,打开Eclipse,这时候将通过Nexus进行下载依赖包到本地仓库中,一般情况可以解决问题,如果还有思路2中的错误信息,则执行思路2。
通过Maven部署项目到Nexus中
当项目已经编写完成,需要部署到Nexus中,这样团队人员可以通过Nexus下载到自己的本地仓库中,比如说,我是编写user-core的模块的,部署到Nexus中,需要以下两个步骤,
1、需要配置user-core的pom.xml文件,定义发布的版本以及发布到Nexus本地库的哪个仓库中,具体如下所示:
……………………………………………………………… <distributionManagement> <repository> <id>user-core-release</id> <name>user core release</name> <url>http://localhost:8081/nexus/content/repositories/releases/</url> </repository> <snapshotRepository> <id>user-core-snapshot</id> <name>user core snapshot</name> <url>http://localhost:8081/nexus/content/repositories/snapshots/</url> </snapshotRepository> </distributionManagement> ………………………………………………………………
2、配置本地settings.xml文件,让部署过程中有足够的权限,而Nexus中本来存在的有三个用户,如图21所示:
图21
而部署使用deployment用户,具体的配置如下
……………………………………………………………… <server> <id>user-core-release</id> <username>deployment</username> <password>deployment123</password> </server> <server> <id>user-core-snapshot</id> <username>deployment</username> <password>deployment123</password> </server> ………………………………………………………………
完成以上两个步骤,此时进行部署(deploy)操作,如图22所示:
图22
这个时候部署成功,然后我们可以在Nexus中看到部署后的结果,如图23所示
图23
在Snapshots的索引中可以查看到刚刚部署的user-core模块。
通过Nexus搜索构件
首先我们来明确一下构件的含义,
构件:构件是系统中实际存在的可更换部分,它实现特定的功能,符合一套接口标准并实现一组接口,而在我们这里就是我们要使用的即将需找的依赖。
但在我们实际使用构件的过程中通常遇到一个问题,有时候我紧紧知道我所需要的构建的大致名字,并不知道全称或group id, 这是件非常头疼的事情. Nexus基于Nexus indexer(索引)的搜索功能帮我们解决了这个问题。
还记得刚才我们在解决Could not calculate build plan...问题的时候,给出的思路1,其思想就是,通过更改Download Remote Indexes的状态为True,使得Nexus从中央仓库中将所有构件的信息同步到本地,这样在以后的开发中,就可以直接下载私有仓库中的依赖,就不需要Nexus还要去中央仓库中下载了。下面就来领略Nexus搜索构件的方便之处。
如图所示:
图24
这里有以下几种搜索方式:
keyword(关键字查询), classname(类名查询), GAV(groupId,artifactId,version组合查询), checksum(校验和查询),这里我认为前三种使用的最多。
比如,刚刚通过部署后的user-core模块,这个模块正好被其他项目人员使用到,他知道模块的名称叫user-core,这个时候,可以通过GAV的方式进行查询,如图所示:
图25
查出来之后,只要将依赖文件复制到项目的pom.xml配置中,就可以从私有仓库中下载到其本地仓库进行使用了。
创建本地仓库并设置权限
创建仓库
在大公司的项目开发中,不可能所有的Snapshots和Releases版本都发布到Nexus中默认对应的Snapshots和Releases仓库中,我们可以给每个项目创建自己的本地仓库,并赋予相应的角色权限进行操作。比如创建一个UserRelease仓库用来存储User项目的Release版本,这个时候,操作如图所示:
图26
接着将信息填入New Hosted Repository中,如图27所示
图27
这个时候就创建了UserRelease的本地仓库,如图所示
图28
创建权限
虽然我们已经创建了UserRelease仓库,但仓库的权限仅为预览,如果让其可以有增删改查的权限,只要点击图中Add,如图所示:
图29
接着进行信息填入,如图30所示
图30
这个时候UserRelease仓库就拥有了所有的权限,如图31所示
图31
创建角色
虽然有了权限,但在使用的过程中,进一步创建一个角色,对角色添加相应的权限,然后在让角色中添加相应的用户,这样在发布的时候就可以达到权限的最细致化,管理起来更加方面。
如图32,创建角色
图32
然后进行填写信息,如图33
图33
在这里有Add按钮,点击按钮的时候进行如下操作
图34
此时,创建角色后如图35所示:
图35
创建用户
角色创建好后就可以创建用户,通过专有的用户来进行专有项目的部署和其他操作,如图创建用户
图36
然后填入信息,如图所示
图37
在图37中点击Add按钮出现图38所示的选项,如下操作
图38
就是选择该用户所属的角色,而角色拥有所有的权限,完成后如图39所示
图39
注:在以上操作中,我们首先创建一个本地仓库(这里是Release版本的,项目中可以在创建一个Snapshot版本,操作过程同上),然后给这个仓库赋予权限,然后将这些权限通过一个角色进行拥有,当然在这里可以创建不同的角色赋予不同的权限,这时候,创建一个用户,使得该用户担当一个角色,这样的话,这个用户就可以拥有这个角色中的权限,下面就可以按需对所在的项目使用相应的用户进行操作了。
这样根据以上情况可以建立UserSnapshot的仓库,以及将所有的权限付给不同的角色,或者可以让UserReleaseRole同样拥有UserSnapshot的所有权限,并且同样的用户拥有Release和Snapshot仓库的所有权限,这样的话如果进行部署,就可以如下进行配置,在对应部署模块的pom.xml中可以这样配置
……………………………………………………………… <distributionManagement> <repository> <id>user-core-release</id> <name>user core release</name> <url>http://localhost:8081/nexus/content/repositories/UserRelease/</url> </repository> <snapshotRepository> <id>user-core-snapshot</id> <name>user core snapshot</name> <url>http://localhost:8081/nexus/content/repositories/UserSnapshots/</url> </snapshotRepository> </distributionManagement> ………………………………………………………………
而在settings.xml中就可以这样进行配置
……………………………………………………………… <server> <id>user-core-release</id> <username>UserRelease</username> <password>user123</password> </server> <server> <id>user-core-snapshot</id> <username>UserRelease</username> <password>user123</password> </server> ………………………………………………………………
这样就可以把相应的Release和Snapshot版本部署到相应的Nexus仓库中了。
总结
本章节通过对仓库管理器Nexus的讲解,包括如何下载安装Nexus,配置Nexus代理中央仓库,管理Nexus的代理仓库,本地仓库,以及仓库组。并帮助你了解如何通过Nexus搜索构件。最后,如何在Maven中配置Nexus仓库,以及如何部署构件到Nexus仓库中。同时,根据大公司的要求,创建了专有的仓库,并且学习了如何进行用户管理,角色权限管理等等。
如有什么疑问或者建议意见都可以提出,本人在此不胜感激,同时,同样恭祝大家学习愉快!