Sonatype Nexus2.0.6介绍与安装
安装完maven后,还会创建一个mavenRepository目录,这个目录就是本地maven仓库,用来存放从中央仓库获取下来的构建和插件。这个 地方,会有疑问了,什么是中央仓库?如何获取到本地的?原来,maven项目在开始时就创建了该仓库,目的是让maven开发者能够共享该仓库,从该仓库 中获取构建,中央仓库的地址是:http://repo1.maven.org/maven2/; 那么本地的maven是如何获取到中央仓库的构建的呢?换句话说,本地的maven怎么知道去这个地方获取构件?其实本地maven的源代码中有配置文件 已经默认配置好了这个路径,具体在:%M2_HOME%\lib\maven-2.2.1-uber.jar中的org\apache\maven \project\pom-4.0.0.xml这个文件中,有兴趣的朋友可以打开该文件看一下,里边还定义了一些其他的maven配置信息,包括 maven项目的默认包结构等等。
说到这个地方,肯定有人要说,全世界的maven开发者都去访问这个中央仓库?那它的压力得有多大啊!还有如果我的网速不够理想,下载一次构件都耗费好长时间啊。这都是一些典型的问题,就是因为这些问题,nexus应运而生了。
1.nexus介绍
nexus其实是一个仓库管理器,在使用maven的时候,你通常可以从中央仓库获取需要的构件,但这通常不是一个好的做法,你应该在本地架设一个Maven仓库服务器,在代理远程仓库的同时维护本地仓库,以节省带宽和时间,Nexus就可以满足这样的需要。说的通俗一点儿,就是在本地maven仓库和中央仓库之间再建一个中间仓库,本地仓库如果需要下载构件可以先去这个仓库管理器获取,如果仓库管理器有了那么直接就可以用,如果仓库管理器没有那么由它去中央仓库获取。通常,在一个公司内部,可以创建公司级的仓库管理器,相当于一个公司只有这个仓库管理器去和中央仓库打交道,而这个仓库管理器通常设置在公司内网,大大减轻了从中央仓库获取构件的带宽和不必要的磁盘浪费。
nexus还提供了强大的仓库管理功能,构件搜索功能,它基于REST,友好的UI是一个extjs的REST客户端,它占用较少的内存,基于简单文件系统而非数据库。这些优点使其日趋成为最流行的Maven仓库管理器。
2.nexus安装
本文章相关软件的环境信息:win7旗舰版32位、jdk1.6.0_14、maven2.2.1、nexus2.0.6
2.1下载
地址:http://www.sonatype.org/nexus/go
下载完,解压缩后可以看到两个文件夹,一个是nexus-2.0.6,另一个是sonatype-work,我们只需要将nexus-2.0.6拷贝到需要安装的路径即可,比如在我的机器上,我copy到了D:\maven目录下,sonatype-work可以不拷贝。
很简单,这就安装完了。
2.3启动
nexus已经将各个平台的启动脚本都写好了,并分开目录放置,具体可以查看nexus-2.06\bin\jsw目录,我的机器是windows32位的,就可以进入到windows-x86-32目录下,点击console-nexus.bat即可启动,启动完成后,访问url:http://localhost:8081/nexus即可看到nexus的页面。
如果是其他平台,找到对应的目录启动脚本即可。
到这里为止,我们的nexus就已经启动起来了。
3.nexus的配置
上一章节,我们讲述了nexus的概况和安装,并且成功启动了nexus,这一节我们讨论下nexus是如何工作的,如何来配置和管理nexus。
接着上一节,我们启动了nexus后,可以通过浏览器访问到nexus的管理界面:http://localhost:8081/nexus。管理员登陆密码默认为:admin/admin123,UI界面是Ext来搭建的,操作起来没有什么障碍,而且界面看起来很清爽。
好,我们输入用户名密码开始来配置nexus。
左侧分为4部分,其中views/repositories是仓库相关的管理项;security是安全权限相关的;administrotr是管理相关的;help是帮助相关的。
由于nexus提供的功能相当强大,咱们这篇文章只描述里边平时用的比较多的且较重要的部分说明,其余的可能会一笔带过或者忽略掉。
3.1 仓库配置
3.1.1仓库浏览
点击左侧的“views/repositories–>repositories”,右边列出来了nexus默认的仓库
其中有四种类型的仓库,分别是hosted、proxy、virtual、group。
hosted,宿主型的,实实在在由nexus给管理的仓库,nexus自带了3个宿主仓库
proxy,代理型的,每个仓库都是对一个远程仓库的代理,这其中就包括了对中央仓库的代理。
virtual,虚拟型的,这个不太了解,就不说了
group,严格来说它不是一个仓库,顾名思义,是组的意思,它相当于是由多个仓库合成了一个组,由该组的url对外提供服务,nexus默认有两个组,一个是public group,其中包含了上边的3个宿主仓库和中央仓库;另一个是public snapshots group,里边包含了Apache Snapshots和CodeHaus Sanpshots。当然这些组包含的内容是可以修改的。
同时,nexus提供了增加、删除、修改仓库定义的功能。
3.1.2 打开远程索引下载
上一节咱们也提到了,巨大的用户访问中央仓库会带来巨大的网络压力和服务器压力,因此在nexus中默认的各个代理仓库的索引都是关闭状态,即安装完nexus后里边是空的,什么东东都没有,包括索引。我们现在要做的就是需要把这个索引给下载到nexus服务器中,以便使用者可以从nexus中搜索到相关构建。
方法如下:选中中央仓库这条记录,即名字为central的仓库
下边选中configuration选项卡,找到其中的Download Remote Indexes,把fasle改为true,并保存。
在上边的中央仓库记录上点击右键,选择update index
下载完成后如图
然后在下边选中Browse Index选项卡,打开central这颗树的节点,应该能看到内容。在下载索引之前是空的。其他的proxy类型的仓库,都可以用同样的方法来下载索引。
注意:这一步仅仅是下载了远程仓库的索引,真正的构件还没有下载到nexus中。等真正有实际用户使用这些构件的时候,才会从中央仓库下载真正的构件文件。有的远程仓库没有索引文件而不能下载索引文件,但只要Browse Remote中能看到包,即使Browse Index看不到也能通过maven依赖下载下来,下载后就能在nexus中搜索到该包了。
3.1.3 搜索构件
在使用maven之前,如果我们的项目中需要使用一个jar包,我们一般会怎么做呢?举个例子,我们要使用dom4j这个包,那么我们一般要去官方网站下载或者去baidu、google里边直接搜索,版本呢只能逮到哪个是哪个了。这种情况如果找一个两个jar还行,如果多了将会带来巨大的工作量,而且还非常容易导致缺包、冲突等问题。
现在有了maven,工作将会变的非常简单。还拿找dom4j这个jar来举例子,在nexus的页面中搜索“dom4j”这个词,看如下结果
左侧的搜索框输入了dom4j,右侧上方出现了所有包含dom4j的项目,假如我们需要1.6.1版本的dom4j的jar,那么点击相应的条目在下方就会列出来。搜索到之后怎么用呢?右侧给出了依赖xml格式的数据,只需要将该xml copy到你的pom.xml中,那么你的项目将会自动从nexus下载(注:项目中配置nexus的方法还没说,下一节细说)。
说到这里,可能会有疑问,那假如说我的项目需要A.jar,但是A.jar又依赖B.jar,那我是不是还要依次去找所有的依赖jar呢?答案是否定的,maven已经给你提供了最简单的方法,只要你依赖了A.jar,那么A.jar所需要的所有jar它将自动帮你查找下载。怎么样,省事了很多吧。
3.1.4 创建仓库
我们来做一个创建proxy类型的仓库,点击仓库里边上方的“Add….—>Proxy Repository”
Id是唯一的,输入一个名字,Remote Storage Location输入jboss的maven仓库地址,下边的代理相关的设置根据自己的情况来确定,输入完后点击保存即可。创建完成后按照3.1.2节提供的方法下载索引即可。
3.1.5组管理
组是若干仓库的一个集合,那么如何来管理组中包含的仓库呢?看下图:
选中public group这条记录,选中下方的configuration选项卡,左侧列出了已经选择的仓库列表,右边是可选的,通过中间的箭头来控制仓库列表信息。
3.2 安全相关
主要是对nexus中资源的授权管理。
security–>Change Password,修改当前用户的密码;
security–>Privilege,权限点管理;
security–>Roles,角色管理;
security–>Users,用户管理
这几项都是标准的权限管理,很简单,就不再多说了。
3.3.管理相关
3.3.1代理设置
如果nexus服务器上网需要设置代理,那么需要在Administrator–>Server中设置,如下图所示:
大概说了这么多,都是比较常用的了。
4.项目中配置使用nexus
上一节,我们讨论了nexus的管理与配置。那么,当nexus配置完了之后,就相当于我们本地项目与maven中央仓库这个桥梁已经搭好了,剩下的就是看怎么通过怎样的配置来使用nexus。在本地开发的时候,主要牵涉到两个配置文件,一个是settings.xml(%M2_HOME%/conf/settings.xml和%USER_HOME%\.m2\settings.xml),一个是项目中的pom.xml。所有的主要配置都集中在这两个配置文件中,下边咱们就通过一个实际的项目的例子来说说这两个配置文件的用法。
4.1 项目描述
我们先从这个项目开始说起。onlinestore是一个主项目,onlinestore-core、onlinestore-interf、onlinestore-chinaweb、onlinestore-americaweb是onlinestore的4个子项目(其中前两个是java项目,后边两个是web项目)。在这里说子项目,可能大家还有些不太习惯或者不太好理解,这个子与父的关系,我们在后边会再说。注意:这里我起的在线商店这个项目,里边没有什么实质性的代码,只是讲的框架和主要的配置文件。下边截图是这几个项目的工程结构图:
在图中我们可以看到父项目和子项目在MyEclipse里边是平级的关系,在磁盘的目录结构中,子项目在父项目所在的文件夹中,如下图:
其实在这两个截图中,都看不出里边的父子关系,真正的父子关系,在哪里定义呢?在pom.xml文件中,我们打开父项目的pom.xml文件,里边可以找到:
<modules>
<module>onlinestore-core</module>
<module>onlinestore-interf</module>
<module>onlinestore-chinaweb</module>
<module>onlinestore-americaweb</module>
</modules>
另外,在4个子项目的pom.xml的文件中,也能找到类似的:
<parent>
<artifactId>parent</artifactId>
<groupId>com.uuwit.onlinestore</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
也就是说,在父项目和子项目中,都有说明他们之间的关系。
说到这里,咱们说一下为什么要创建父项目和子项目,他们之间到底有着什么样的联系。通常一个大的项目会将项目分成多个模块,比如上边咱们举的例子,core是项目的一些核心类或者组件,interf放接口类,其余两个分别是两个相对独立的web模块。正常情况下,两个web模块比如会依赖core和interf这两个项目。而两个web项目之间通常并不会有依赖关系,但是他们之间却有很多共性的东西,比如说很多类似的配置、很多类似的jar包等等,这时候父项目和子项目的优势就能体现出来了。我们知道maven父项目和子项目的pom.xml是有继承关系的,也就是说各个模块相同的部分,我们可以配置到父项目的pom.xml文件中,这样子项目中的pom.xml只放自己个性的东西就可以了,这大大减少了工作量。另外,在编译和打包等其他阶段,都可以统一在父项目中来进行,maven会自动操作其中的子项目,提高了效率。
【注意:】事实上,所有的maven项目都会继承一个超级pom,这个pom就是%M2_HOME%\lib\maven-2.2.1-uber.jar中的org\apache\maven\project\pom-4.0.0.xml。
4.2 配置nexus
我们知道,我们架设仓库管理器的目的是为了减少与中央仓库的交互,既然这样,那我们在本地肯定要配置nexus的相关信息,以便能够把中央仓库的配置覆盖掉,从而真正来使用nexus。
两个步骤:
1.打开settings.xml文件:
<mirrors>
<!– mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
–>
<mirror>
<id>nexus-public-snapshots</id>
<mirrorOf>public-snapshots</mirrorOf>
<url>http://localhost:8081/nexus/content/groups/public-snapshots</url>
</mirror>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/nexus/content/groups/public</url>
</mirror>
</mirrors>
找到mirrors标签,在其中添加上边的配置,其中的localhots:8081根据自己的具体情况修改。
2.打开父项目的pom.xml文件,添加如下配置:
<distributionManagement>
<repository>
<id>repo</id>
<name>public</name>
<url>http://localhost:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Snapshots</name>
<url>http://localhost:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
其中的localhots:8081根据自己的具体情况修改。
好了,就这么简单,就配置好了,如何验证一下项目真的不去找中央仓库的麻烦了呢?可以这么测试一下,你把你项目中使用到的一些构件在本地的maven仓库删除掉,然后再编译一下项目,在控制台打印的日志中,你能够清晰的看到都是从nexus中downlaod的,而在之前都是打印从中央仓库获取的。
4.3 java项目的几个操作
3.1编译
mvn compile,编译java项目,java文件将会被编译成class文件放到target/classes目录下
3.2打包
mvn package,打包java项目,项目将会打包成jar文件放到target目录下,jar文件的命名规则是:${project.artifactId}-${project.version}.jar
3.3安装
安装的作用是将打包好的jar文件安装到本地的mavan仓库中,以供其他项目(如果其他项目依赖该项目的话)使用。
mvn install,在maven仓库中存放的目录结构是:${project.groupId}–>${project.artifactId}–>${project.version}
3.4部署
部署的作用是将打包好的jar文件上传到nexus中,以供其他同伴(如果其他同伴依赖该项目的话)使用。
mvn deploy,在这里要注意,在部署的时候,会提示401错误,此时你需要在setting.xml文件中添加鉴权信息,即在部署的时候需要使用nexus给分配的账户来上传。
在settings.xml中找到servers标签,在其中添加如下配置:
<server>
<id>repo</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
其中的用户名和密码是nexus分配的,其中的id一定要和父项目中pom.xml文件中刚才配置的repository和snapshotRepository的id一致。
4.4 web项目的几个操作
先贴一下web项目的pom.xml的build标签:
<build>
<finalName>onlinestore-chinaweb</finalName>
<outputDirectory>src/main/webapp/WEB-INF/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!–
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.2</version>
<configuration>
<parallel>methods</parallel>
<threadCount>10</threadCount>
<argLine>-Dfile.encoding=UTF-8</argLine>
<skip>true</skip>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
<plugin>
<groupId>maven</groupId>
<artifactId>maven-clover-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
–>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<warName>onlinestore-chinaweb</warName>
<attachClasses>true</attachClasses>
<classesClassifier>classes</classesClassifier>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<webappDirectory>${project.build.directory}/onlinestore-chinaweb</webappDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<configuration>
<charset>${project.build.sourceEncoding}</charset>
<url>http://localhost:8080/manager</url>
<!– <server>tomcat.server</server> –>
<path>/onlinestore-chinaweb</path>
<port>8080</port>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warFile>${project.build.directory}/onlinestore-chinaweb.war</warFile>
<uriEncoding>${project.build.sourceEncoding}</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
4.4.1 全局配置
outputDirectory要重新指定,指定到src/main/webapp/WEB-INF/classes目录下,否则默认会是在test/classes目录
4.4.2 war插件
配置比较简单,不再累述。
4.4.3 tomcat插件
tomcat插件可以让你不使用外部的tomcat,而使用起内嵌的tomcat,这样更省劲,更简单。如果你不想使用内嵌的tomcat,也可以单独指定,需要在<configuration>标签中指定tomcat的server的id,这个id也需要在settings.xml中的servers标签中定义。其中的tomcat端口可以自己指定。