标签归档:maven

Nexus3.x搭建Maven私服环境

Maven介绍

Apache Maven是一个创新的软件项目管理和综合工具。
Maven提供了一个基于项目对象模型(POM)文件的新概念来管理项目的构建,可以从一个中心资料片管理项目构建,报告和文件。
Maven最强大的功能就是能够自动下载项目依赖库。
Maven提供了开发人员构建一个完整的生命周期框架。开发团队可以自动完成项目的基础工具建设,Maven使用标准的目录结构和默认构建生命周期。
在多个开发团队环境时,Maven可以设置按标准在非常短的时间里完成配置工作。由于大部分项目的设置都很简单,并且可重复使用,Maven让开发人员的工作更轻松,同时创建报表,检查,构建和测试自动化设置。
Maven项目的结构和内容在一个XML文件中声明,pom.xml 项目对象模型(POM),这是整个Maven系统的基本单元。

Maven提供了开发人员的方式来管理:
1)Builds
2)Documentation
3)Reporting
4)Dependencies
5)SCMs
6)Releases
7)Distribution
8)mailing list
概括地说,Maven简化和标准化项目建设过程。处理编译,分配,文档,团队协作和其他任务的无缝连接。
Maven增加可重用性并负责建立相关的任务。
Maven最初设计,是以简化Jakarta Turbine项目的建设。在几个项目,每个项目包含了不同的Ant构建文件。 JAR检查到CVS。
Apache组织开发Maven可以建立多个项目,发布项目信息,项目部署,在几个项目中JAR文件提供团队合作和帮助。

Maven主要目标是提供给开发人员:
1)项目是可重复使用,易维护,更容易理解的一个综合模型。
2)插件或交互的工具,这种声明性的模式。

私服介绍
私服是指私有服务器,是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构建。有了私服之后,当 Maven 需要下载构件时,直接请求私服,私服上存在则下载到本地仓库;否则,私服请求外部的远程仓库,将构件下载到私服,再提供给本地仓库下载。

Nexus介绍
Nexus是一个强大的Maven仓库管理器,它极大地简化了本地内部仓库的维护和外部仓库的访问。
如果使用了公共的Maven仓库服务器,可以从Maven中央仓库下载所需要的构件(Artifact),但这通常不是一个好的做法。
正常做法是在本地架设一个Maven仓库服务器,即利用Nexus私服可以只在一个地方就能够完全控制访问和部署在你所维护仓库中的每个Artifact。
Nexus在代理远程仓库的同时维护本地仓库,以降低中央仓库的负荷,节省外网带宽和时间,Nexus私服就可以满足这样的需要。
Nexus是一套“开箱即用”的系统不需要数据库,它使用文件系统加Lucene来组织数据。
Nexus使用ExtJS来开发界面,利用Restlet来提供完整的REST APIs,通过m2eclipse与Eclipse集成使用。
Nexus支持WebDAV与LDAP安全身份认证。
Nexus还提供了强大的仓库管理功能,构件搜索功能,它基于REST,友好的UI是一个extjs的REST客户端,它占用较少的内存,基于简单文件系统而非数据库。

为什么要构建Nexus私服?
如果没有Nexus私服,我们所需的所有构件都需要通过maven的中央仓库和第三方的Maven仓库下载到本地,而一个团队中的所有人都重复的从maven仓库下载构件无疑加大了仓库的负载和浪费了外网带宽,如果网速慢的话,还会影响项目的进程。很多情况下项目的开发都是在内网进行的,连接不到maven仓库怎么办呢?开发的公共构件怎么让其它项目使用?这个时候我们不得不为自己的团队搭建属于自己的maven私服,这样既节省了网络带宽也会加速项目搭建的进程,当然前提条件就是你的私服中拥有项目所需的所有构件。

总之,在本地构建nexus私服的好处有:
1)加速构建;
2)节省带宽;
3)节省中央maven仓库的带宽;
4)稳定(应付一旦中央服务器出问题的情况);
5)控制和审计;
6)能够部署第三方构件;
7)可以建立本地内部仓库;
8)可以建立公共仓库
这些优点使得Nexus日趋成为最流行的Maven仓库管理器。

Maven的安装
下载地址:http://maven.apache.org/download.cgi
提前在服务器上安装jdk环境(参考:Centos中yum方式安装java)
[root@master-node ~]# cd /usr/local/src/
[root@master-node src]# wget http://mirrors.hust.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz
[root@master-node src]# tar -zvxf apache-maven-3.3.9-bin.tar.gz
[root@master-node src]# mv apache-maven-3.3.9 /usr/local/maven

接着配置系统环境变量,在/etc/profile文件底部添加如下内容:
[root@master-node src]# java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-b15)
OpenJDK 64-Bit Server VM (build 25.111-b15, mixed mode)
[root@master-node src]# vim /etc/profile
.....
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk                                //java的环境变量设置
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

export MAVEN_HOME=/usr/local/maven                                                 //maven的环境变量设置
export PATH=$PATH:$MAVEN_HOME/bin
[root@master-node src]# source /etc/profile

最后验证是否安装成功,出现如下信息,说明安装成功
[root@master-node src]# mvn --version                   # 最好按照java jdk
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
Maven home: /usr/local/maven
Java version: 1.8.0_111, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-2.b15.el7_3.x86_64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-327.el7.x86_64", arch: "amd64", family: "unix"

Nexus安装
Nexus的安装有两种实现方式:
1)war包安装方式
下载地址:https://sonatype-download.global.ssl.fastly.net/nexus/oss/nexus-2.14.2-01.war
直接将war包放在tomcat的根目录下,启动tomcat就可以用了

2)源码安装方式(之前在用的是2.14.4版本,这里是新版本)
下载地址:https://www.sonatype.com/download-oss-sonatype           (云盘下载:http://pan.baidu.com/s/1miKFm5a)
[root@master-node ~]# cd /usr/local/src/
[root@master-node src]# wget https://sonatype-download.global.ssl.fastly.net/nexus/3/nexus-3.2.0-01-unix.tar.gz
[root@master-node src]# tar -zvxf nexus-3.2.0-01-unix.tar.gz
[root@master-node src]# mv nexus-3.2.0-01 /usr/local/nexus

启动nexus(默认端口是8081)
[root@master-node src]# /usr/local/nexus/bin/nexus
WARNING: ************************************************************
WARNING: Detected execution as "root" user. This is NOT recommended!
WARNING: ************************************************************
Usage: /usr/local/nexus/bin/nexus {start|stop|run|run-redirect|status|restart|force-reload}
[root@master-node src]# /usr/local/nexus/bin/nexus start
WARNING: ************************************************************
WARNING: Detected execution as "root" user. This is NOT recommended!
WARNING: ************************************************************
Starting nexus
上面在启动过程中出现告警:不推荐使用root用户启动。这个告警不影响nexus的正常访问和使用。
去掉上面WARNING的办法:
[root@master-node src]# vim /etc/profile
......
export RUN_AS_USER=root
[root@master-node src]# source /etc/profile
[root@master-node src]# lsof -i:8081            //nexus服务启动成功后,需要稍等一段时间,8081端口才起来
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 1486 root 859u IPv4 23504303 0t0 TCP *:tproxy (LISTEN)

在部署机上的iptables里打开8081端口
[root@master-node src]# vim /etc/sysconfig/iptables
....
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8081 -j ACCEPT
[root@master-node src]# /etc/init.d/iptables restart

访问nexus,即http://localhost:8081    (如果出现404,就访问http://localhost:8081/nexus)

出现上述页面,说明配置nexus成功!
点击右上角“Log in”,
输入默认用户名(admin)和默认密码(admin123)登录

可以点击上面的“设置”图标,在“设置”里可以添加用户、角色,对接LDAP等的设置,如下:

可以在“管理”里查看nexus的系统信息

注意下面几点说明:
1.component name的一些说明:
1)maven-central:maven中央库,默认从https://repo1.maven.org/maven2/拉取jar
2)maven-releases:私库发行版jar
3)maven-snapshots:私库快照(调试版本)jar
4)maven-public:仓库分组,把上面三个仓库组合在一起对外提供服务,在本地maven基础配置settings.xml中使用。
2.Nexus默认的仓库类型有以下四种:
1)group(仓库组类型):又叫组仓库,用于方便开发人员自己设定的仓库;
2)hosted(宿主类型):内部项目的发布仓库(内部开发人员,发布上去存放的仓库);
3)proxy(代理类型):从远程中央仓库中寻找数据的仓库(可以点击对应的仓库的Configuration页签下Remote Storage Location属性的值即被代理的远程仓库的路径);
4)virtual(虚拟类型):虚拟仓库(这个基本用不到,重点关注上面三个仓库的使用);
3.Policy(策略):表示该仓库为发布(Release)版本仓库还是快照(Snapshot)版本仓库;
4.Public Repositories下的仓库
1)3rd party: 无法从公共仓库获得的第三方发布版本的构件仓库,即第三方依赖的仓库,这个数据通常是由内部人员自行下载之后发布上去;
2)Apache Snapshots: 用了代理ApacheMaven仓库快照版本的构件仓库
3)Central: 用来代理maven中央仓库中发布版本构件的仓库
4)Central M1 shadow: 用于提供中央仓库中M1格式的发布版本的构件镜像仓库
5)Codehaus Snapshots: 用来代理CodehausMaven 仓库的快照版本构件的仓库
6)Releases: 内部的模块中release模块的发布仓库,用来部署管理内部的发布版本构件的宿主类型仓库;release是发布版本;
7)Snapshots:发布内部的SNAPSHOT模块的仓库,用来部署管理内部的快照版本构件的宿主类型仓库;snapshots是快照版本,也就是不稳定版本
所以自定义构建的仓库组代理仓库的顺序为:Releases,Snapshots,3rd party,Central。也可以使用oschina放到Central前面,下载包会更快。
5.Nexus默认的端口是8081,可以在etc/nexus-default.properties配置中修改。
6.Nexus默认的用户名密码是admin/admin123
7.当遇到奇怪问题时,重启nexus,重启后web界面要1分钟左右后才能访问。
8.Nexus的工作目录是sonatype-work(路径一般在nexus同级目录下)
[root@master-node local]# pwd
/usr/local
[root@master-node local]# ls nexus/
bin deploy etc lib LICENSE.txt NOTICE.txt public system
[root@master-node local]# ls sonatype-work/
nexus3
[root@master-node local]# ls sonatype-work/nexus3/
backup blobs cache db elasticsearch etc generated-bundles health-check instances keystores lock log orient port tmp

Nexus仓库分类的概念:
1)Maven可直接从宿主仓库下载构件,也可以从代理仓库下载构件,而代理仓库间接的从远程仓库下载并缓存构件
2)为了方便,Maven可以从仓库组下载构件,而仓库组并没有时间的内容(下图中用虚线表示,它会转向包含的宿主仓库或者代理仓库获得实际构件的内容).

Nexus的web界面功能介绍

1.Browse Server Content

1.1  Search
这个就是类似Maven仓库上的搜索功能,就是从私服上查找是否有哪些包。
注意:
1)在Search这级是支持模糊搜索的,如图所示:

2)如果进入具体的目录,好像不支持模糊搜索,如图所示:

1.2  Browse

1)Assets
这是能看到所有的资源,包含Jar,已经对Jar的一些描述信息。
2)Components
这里只能看到Jar包。

2.Server Adminstration And configuration

看到这个选项的前提是要进行登录的,如上面已经介绍登陆方法,右上角点击“Sign In”的登录按钮,输入admin/admin123,登录成功之后,即可看到此功能,如图所示:

2.1 Blob Stores
文件存储的地方,创建一个目录的话,对应文件系统的一个目录,如图所示:

2.2 Repositories

1)Proxy
这里就是代理的意思,代理中央Maven仓库,当PC访问中央库的时候,先通过Proxy下载到Nexus仓库,然后再从Nexus仓库下载到PC本地。
这样的优势只要其中一个人从中央库下来了,以后大家都是从Nexus私服上进行下来,私服一般部署在内网,这样大大节约的宽带。
创建Proxy的具体步骤
1--点击“Create Repositories”按钮

2--选择要创建的类型

3--填写详细信息
Name:就是为代理起个名字
Remote Storage: 代理的地址,Maven的地址为: https://repo1.maven.org/maven2/
Blob Store: 选择代理下载包的存放路径

2)Hosted
Hosted是宿主机的意思,就是怎么把第三方的Jar放到私服上。
Hosted有三种方式,Releases、SNAPSHOT、Mixed
Releases: 一般是已经发布的Jar包
Snapshot: 未发布的版本
Mixed:混合的
Hosted的创建和Proxy是一致的,具体步骤和上面基本一致。如下:

注意事项:
Deployment Pollcy: 需要把策略改成“Allow redeploy”。

3)Group
能把两个仓库合成一个仓库来使用,目前没使用过,所以没做详细的研究。

2.3 Security
这里主要是用户、角色、权限的配置(上面已经提到了在这里添加用户和角色等)

2.4 Support
包含日志及数据分析。

2.5 System
主要是邮件服务器,调度的设置地方
这部分主要讲怎么和Maven做集成,集成的方式主要分以下种情况:代理中央仓库、Snapshot包的管理、Release包的管理、第三方Jar上传到Nexus上。

代理中央仓库
只要在PMO文件中配置私服的地址(比如http://192.168.1.14:8081)即可,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<repositories>
        <repository>
            <id>maven-central</id>
            <name>maven-central</name>
            <url>http://192.168.1.14:8081/repository/maven-central/</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

Snapshot包的管理
1)修改Maven的settings.xml文件,加入认证机制

1
2
3
4
5
6
<servers>
<server>
      <id>nexus</id>
      <username>admin</username>
      <password>admin123</password>
     </server>

2)修改工程的Pom文件

1
2
3
4
5
6
7
8
9
10
11
12
<distributionManagement>
        <snapshotRepository>
            <id>nexus</id>
            <name>Nexus Snapshot</name>
            <url>http://192.168.1.14:8081/repository/maven-snapshots/</url>
        </snapshotRepository>
        <site>
            <id>nexus</id>
            <name>Nexus Sites</name>
            <url>dav:http://192.168.1.14:8081/repository/maven-snapshots/</url>
        </site>
    </distributionManagement>

注意事项:

上面修改的Pom文件如截图中的名字要跟/usr/local/maven/conf/settings.xml文件中的名字一定要对应上。

3)上传到Nexus上

1--项目编译成的jar是Snapshot(POM文件的头部)

1
2
3
4
<groupId>com.woasis</groupId>
<artifactId>test-nexus</artifactId>
<version>1.0.0-<span style="color: #ff0000;">SHAPSHOT</span></version>
<packaging>jar</packaging>

2--使用mvn deploy命令运行即可(运行结果在此略过)

3--因为Snapshot是快照版本,默认他每次会把Jar加一个时间戳,做为历史备份版本。

Releases包的管理

1)与Snapshot大同小异,只是上传到私服上的Jar包不会自动带时间戳
2)与Snapshot配置不同的地方,就是工程的PMO文件,加入repository配置

1
2
3
4
5
6
<distributionManagement>
        <repository>
            <id>nexus</id>
            <name>Nexus Snapshot</name>
            <url>http://192.168.1.14:8081/repository/maven-releases/</url>
        </repository>

3)打包的时候需要把Snapshot去掉

1
2
3
4
<groupId>com.woasis</groupId>
    <artifactId>test-nexus</artifactId>
    <version>1.0.0</version>
<packaging>jar</packaging>

第三方Jar上传到Nexus

[root@master-node src]# mvn deploy:deploy-file -DgroupId=org.jasig.cas.client -DartifactId=cas-client-core -Dversion=3.1.3 -Dpackag
注意事项:
-DrepositoryId=nexus 对应的就是Maven中settings.xml的认证配的名字。

来源:https://www.cnblogs.com/kevingrace/p/6201984.html

随着Nexus Repository Manager OSS 3的发布(目前更新至3.2.1),虽然目前还是Nexus 2和Nexus 3并行的状态,但是Nexus 3在很多方面已经显现出很大的优势,等到Nexus 3在Maven方面的支持稳定之后就应该是Nexus 3的全面使用之时。

理由1:安装更加简单

安装变得更加方便,详细可以参看如下链接。

安装参照URLhttp://books.sonatype.com/nexus-book/3.0/reference/install.html?__hstc=239247836.f7854f6edce31b386d0c10d0555205f0.1487887540518.1487887540518.1489490179025.2&__hssc=239247836.3.1489490179025&__hsfp=285730640

理由2:官方Docker镜像

使用官方Docker镜像使得更加容易的导入Repository Manager.

项目详细
官方镜像https://hub.docker.com/r/sonatype/nexus3/
Easypack镜像https://github.com/liumiaocn/easypack/tree/master/containers/standard/nexus

理由3:REST API

使用Nexus提供的API使得集成更容易进行。

项目详细
APIhttp://books.sonatype.com/nexus-book/3.0/reference/scripting.html?__hstc=239247836.f7854f6edce31b386d0c10d0555205f0.1487887540518.1487887540518.1489490179025.2&__hssc=239247836.3.1489490179025&__hsfp=285730640

理由4:用户界面

同Nexus 2相比,Nexus 3的界面增加了一些现代的元素,多多少少使人稍稍有些眼前一亮的感觉,虽说跟Artifactory还是明显有些差距,但是性价比也完全不在一个级别上。

理由5:性能

据说性能依然很好,像其标榜的那样。

理由6:Docker 私库

现在可以用Nexus 来管理Docker 私库了,统一管理,是不是很具有吸引力。

项目详细
参照内容https://www.sonatype.com/concepts-benefits-repo-management?__hstc=239247836.f7854f6edce31b386d0c10d0555205f0.1487887540518.1487887540518.1489490179025.2&__hssc=239247836.3.1489490179025&__hsfp=285730640

理由7:npm与bower

支持npm和bower的package管理,对前端工程师造成了很大的诱惑,目前此项优势继续保持中。

理由8:Raw repositories

在Nexus 3中支持一种新的方式:raw repositories。利用这种方式,任何文件都可以像Maven管理对象文件那样被管理起来,对所有的artifacts进行统一集成管理。

理由9:NuGet repositories

支持NuGet repositories,对于.Net开发者来说,这无疑是一个福音。

理由10:支持检索

对于Nexus所支持的任何类型都支持检索功能,这使得无论任何情况下我们都能利用这些功能进行精确定位。

理由11:支持浏览

支持对其仓库的内容进行浏览,非常方便。

理由12:检查机制

对Maven/NuGet/npm仓库,支持安全以及license的检查,使得使用起来更无后顾之忧。

总结

Nexus物美价廉,又提供功能全面的oss版,加之支持种类众多的倚赖管理,又可以统一管理docker镜像,界面也在慢慢好看起来,这些不禁给了我们对Nexus 3更多的期待。

参照文档

http://www.sonatype.org/nexus/2016/04/13/a-dozen-reasons-why-nexus-repository-3-0-kicks-ass/

常用Maven插件介绍

Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由 maven-compiler-plugin完成的。进一步说,每个任务对应了一个插件目标(goal),每个插件会有一个或者多个目标,例如maven-compiler-plugin的compile目标用来编译位于src/main/java/目录下的主源码,testCompile目标用来编译位于 src/test/java/目录下的测试源码。

用户可以通过两种方式调用Maven插件目标。第一种方式是将插件目标与生命周期阶段 (lifecycle phase)绑定,这样用户在命令行只是输入生命周期阶段而已,例如Maven默认将maven-compiler-plugin的compile目标与 compile生命周期阶段绑定,因此命令mvn compile实际上是先定位到compile这一生命周期阶段,然后再根据绑定关系调用maven-compiler-plugin的compile目 标。第二种方式是直接在命令行指定要执行的插件目标,例如mvn archetype:generate 就表示调用maven-archetype-plugin的generate目标,这种带冒号的调用方式与生命周期无关。

认识上述 Maven插件的基本概念能帮助你理解Maven的工作机制,不过要想更高效率地使用Maven,了解一些常用的插件还是很有必要的,这可 以帮助你避免一不小心重新发明轮子。多年来Maven社区积累了大量的经验,并随之形成了一个成熟的插件生态圈。Maven官方有两个插件列表,第一个列 表的GroupId为org.apache.maven.plugins,这里的插件最为成熟,具体地址 为:http://maven.apache.org/plugins/index.html。第二个列表的GroupId为 org.codehaus.mojo,这里的插件没有那么核心,但也有不少十分有用,其地址为:http://mojo.codehaus.org /plugins.html。

部分插件列表

Core plugins
clean
compiler
deploy
failsafe
install
resources
site
surefire
verifier

Packaging types/tools
ear
ejb
jar
rar
war
app-client/acr
shade
source
Reporting plugins
changelog
changes
checkstyle
doap
docck
javadoc
jdeps
jxr
linkcheck
pmd
project-info-reports
surefire-report
Tools
ant
antrun
archetype
assembly
dependency
enforcer
gpg
help
invoker
jarsigner
patch
pdf
plugin
release
remote-resources
repository
scm
scm-publish
stage
toolchains

接下来笔者根据自己的经验介绍一些最常用的Maven插件,在不同的环境下它们各自都有其出色的表现,熟练地使用它们能让你的日常构建工作事半功倍。

 

maven-antrun-plugin

http://maven.apache.org/plugins/maven-antrun-plugin/

maven- antrun-plugin能让用户在Maven项目中运行Ant任务。用户可以直接在该插件的配置以Ant的方式编写Target, 然后交给该插件的run目标去执行。在一些由Ant往Maven迁移的项目中,该插件尤其有用。此外当你发现需要编写一些自定义程度很高的任务,同时又觉 得Maven不够灵活时,也可以以Ant的方式实现之。maven-antrun-plugin的run目标通常与生命周期绑定运行。

 

maven-archetype-plugin

http://maven.apache.org/archetype/maven-archetype-plugin/

Archtype 指项目的骨架,Maven初学者最开始执行的Maven命令可能就是mvn archetype:generate,这实际上就是让maven-archetype-plugin生成一个很简单的项目骨架,帮助开发者快速上手。可 能也有人看到一些文档写了mvn archetype:create, 但实际上create目标已经被弃用了,取而代之的是generate目标,该目标使用交互式的方式提示用户输入必要的信息以创建项目,体验更好。 maven-archetype-plugin还有一些其他目标帮助用户自己定义项目原型,例如你由一个产品需要交付给很多客户进行二次开发,你就可以为 他们提供一个Archtype,帮助他们快速上手。

 

maven-assembly-plugin

http://maven.apache.org/plugins/maven-assembly-plugin/

maven- assembly-plugin的用途是制作项目分发包,该分发包可能包含了项目的可执行文件、源代码、readme、平台脚本等等。 maven-assembly-plugin支持各种主流的格式如zip、tar.gz、jar和war等,具体打包哪些文件是高度可控的,例如用户可以 按文件级别的粒度、文件集级别的粒度、模块级别的粒度、以及依赖级别的粒度控制打包,此外,包含和排除配置也是支持的。maven-assembly- plugin要求用户使用一个名为assembly.xml的元数据文件来表述打包,它的single目标可以直接在命令行调用,也可以被绑定至生命周 期。

maven-dependency-plugin

http://maven.apache.org/plugins/maven-dependency-plugin/

maven- dependency-plugin最大的用途是帮助分析项目依赖,dependency:list能够列出项目最终解析到的依赖列 表,dependency:tree能进一步的描绘项目依赖树,dependency:analyze可以告诉你项目依赖潜在的问题,如果你有直接使用到 的却未声明的依赖,该目标就会发出警告。maven-dependency-plugin还有很多目标帮助你操作依赖文件,例如 dependency:copy-dependencies能将项目依赖从本地Maven仓库复制到某个特定的文件夹下面。

 

maven-enforcer-plugin

http://maven.apache.org/plugins/maven-enforcer-plugin/

在 一个稍大一点的组织或团队中,你无法保证所有成员都熟悉Maven,那他们做一些比较愚蠢的事情就会变得很正常,例如给项目引入了外部的 SNAPSHOT依赖而导致构建不稳定,使用了一个与大家不一致的Maven版本而经常抱怨构建出现诡异问题。maven-enforcer- plugin能够帮助你避免之类问题,它允许你创建一系列规则强制大家遵守,包括设定Java版本、设定Maven版本、禁止某些依赖、禁止 SNAPSHOT依赖。只要在一个父POM配置规则,然后让大家继承,当规则遭到破坏的时候,Maven就会报错。除了标准的规则之外,你还可以扩展该插 件,编写自己的规则。maven-enforcer-plugin的enforce目标负责检查规则,它默认绑定到生命周期的validate阶段。

 

maven-help-plugin

http://maven.apache.org/plugins/maven-help-plugin/

maven- help-plugin是一个小巧的辅助工具,最简单的help:system可以打印所有可用的环境变量和Java系统属性。 help:effective-pom和help:effective-settings最 为有用,它们分别打印项目的有效POM和有效settings,有效POM是指合并了所有父POM(包括Super POM)后的XML,当你不确定POM的某些信息从何而来时,就可以查看有效POM。有效settings同理,特别是当你发现自己配置的 settings.xml没有生效时,就可以用help:effective-settings来验证。此外,maven-help-plugin的 describe目标可以帮助你描述任何一个Maven插件的信息,还有all-profiles目标和active-profiles目标帮助查看项目 的Profile。

maven-release-plugin

http://maven.apache.org/plugins/maven-release-plugin/

maven- release-plugin的用途是帮助自动化项目版本发布,它依赖于POM中的SCM信息。release:prepare用来准备版本发布,具体的 工作包括检查是否有未提交代码、检查是否有SNAPSHOT依赖、升级项目的SNAPSHOT版本至RELEASE版本、为项目打标签等等。 release:perform则 是签出标签中的RELEASE源码,构建并发布。版本发布是非常琐碎的工作,它涉及了各种检查,而且由于该工作仅仅是偶尔需要,因此手动操作很容易遗漏一 些细节,maven-release-plugin让该工作变得非常快速简便,不易出错。maven-release-plugin的各种目标通常直接在 命令行调用,因为版本发布显然不是日常构建生命周期的一部分。

 

maven-resources-plugin

http://maven.apache.org/plugins/maven-resources-plugin/

为 了使项目结构更为清晰,Maven区别对待Java代码文件和资源文件,maven-compiler-plugin用来编译Java代码,maven- resources-plugin则用来处理资源文件。默认的主资源文件目录是src/main/resources,很多用户会需要添加额外的资源文件 目录,这个时候就可以通过配置maven-resources-plugin来实现。此外,资源文件过滤也是Maven的一大特性,你可以在资源文件中使 用${propertyName}形式的Maven属性,然后配置maven-resources-plugin开启对资源文件的过滤,之后就可以针对不 同环境通过命令行或者Profile传入属性的值,以实现更为灵活的构建。

 

maven-surefire-plugin

http://maven.apache.org/plugins/maven-surefire-plugin/

可 能是由于历史的原因,Maven 2/3中用于执行测试的插件不是maven-test-plugin,而是maven-surefire-plugin。其实大部分时间内,只要你的测试 类遵循通用的命令约定(以Test结尾、以TestCase结尾、或者以Test开头),就几乎不用知晓该插件的存在。然而在当你想要跳过测试、排除某些 测试类、或者使用一些TestNG特性的时候,了解maven-surefire-plugin的一些配置选项就很有用了。例如 mvn test -Dtest=FooTest 这样一条命令的效果是仅运行FooTest测试类,这是通过控制maven-surefire-plugin的test参数实现的。

 

build-helper-maven-plugin

http://mojo.codehaus.org/build-helper-maven-plugin/

Maven 默认只允许指定一个主Java代码目录和一个测试Java代码目录,虽然这其实是个应当尽量遵守的约定,但偶尔你还是会希望能够指定多个 源码目录(例如为了应对遗留项目),build-helper-maven-plugin的add-source目标就是服务于这个目的,通常它被绑定到 默认生命周期的generate-sources阶段以添加额外的源码目录。需要强调的是,这种做法还是不推荐的,因为它破坏了 Maven的约定,而且可能会遇到其他严格遵守约定的插件工具无法正确识别额外的源码目录。

build-helper-maven-plugin的另一个非常有用的目标是attach-artifact,使用该目标你可以以classifier的形式选取部分项目文件生成附属构件,并同时install到本地仓库,也可以deploy到远程仓库。

 

exec-maven-plugin

http://mojo.codehaus.org/exec-maven-plugin/

exec- maven-plugin很好理解,顾名思义,它能让你运行任何本地的系统程序,在某些特定情况下,运行一个Maven外部的程序可能就是最简单的问题解 决方案,这就是exec:exec的 用途,当然,该插件还允许你配置相关的程序运行参数。除了exec目标之外,exec-maven-plugin还提供了一个java目标,该目标要求你 提供一个mainClass参数,然后它能够利用当前项目的依赖作为classpath,在同一个JVM中运行该mainClass。有时候,为了简单的 演示一个命令行Java程序,你可以在POM中配置好exec-maven-plugin的相关运行参数,然后直接在命令运行 mvn exec:java 以查看运行效果。

 

jetty-maven-plugin

http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin

在 进行Web开发的时候,打开浏览器对应用进行手动的测试几乎是无法避免的,这种测试方法通常就是将项目打包成war文件,然后部署到Web容器 中,再启动容器进行验证,这显然十分耗时。为了帮助开发者节省时间,jetty-maven-plugin应运而生,它完全兼容 Maven项目的目录结构,能够周期性地检查源文件,一旦发现变更后自动更新到内置的Jetty Web容器中。做一些基本配置后(例如Web应用的contextPath和自动扫描变更的时间间隔),你只要执行 mvn jetty:run ,然后在IDE中修改代码,代码经IDE自动编译后产生变更,再由jetty-maven-plugin侦测到后更新至Jetty容器,这时你就可以直接 测试Web页面了。需要注意的是,jetty-maven-plugin并不是宿主于Apache或Codehaus的官方插件,因此使用的时候需要额外 的配置settings.xml的pluginGroups元素,将org.mortbay.jetty这个pluginGroup加入。

versions-maven-plugin

http://mojo.codehaus.org/versions-maven-plugin/

很 多Maven用户遇到过这样一个问题,当项目包含大量模块的时候,为他们集体更新版本就变成一件烦人的事情,到底有没有自动化工具能帮助完成这件 事情呢?(当然你可以使用sed之类的文本操作工具,不过不在本文讨论范围)答案是肯定的,versions-maven- plugin提供了很多目标帮助你管理Maven项目的各种版本信息。例如最常用的,命令 mvn versions:set -DnewVersion=1.1-SNAPSHOT 就能帮助你把所有模块的版本更新到1.1-SNAPSHOT。该插件还提供了其他一些很有用的目标,display-dependency- updates能告诉你项目依赖有哪些可用的更新;类似的display-plugin-updates能告诉你可用的插件更新;然后use- latest-versions能自动帮你将所有依赖升级到最新版本。最后,如果你对所做的更改满意,则可以使用 mvn versions:commit 提交,不满意的话也可以使用 mvn versions:revert 进行撤销。

 

小结
本文介 绍了一些最常用的Maven插件,这里指的“常用”是指经常需要进行配置的插件,事实上我们用Maven的时候很多其它插件也是必须的,例如 默认的编译插件maven-compiler-plugin和默认的打包插件maven-jar-plugin,但因为很少需要对它们进行配置,因此不在 本文讨论范围。了解常用的Maven插件能帮助你事倍功半地完成项目构建任务,反之你就可能会因为经常遇到一些难以解决的问题而感到沮丧。本文介绍的插件 基本能覆盖大部分Maven用户的日常使用需要,如果你真有非常特殊的需求,自行编写一个Maven插件也不是难事,更何况还有这么多开放源代码的插件供 你参考。

本文的这个插件列表并不是一个完整列表,读者有兴趣的话也可以去仔细浏览一下Apache和Codehaus Mojo的Maven插件列表,以的到一个更为全面的认识。最后,在线的Maven仓库搜索引擎如http://search.maven.org/也能 帮助你快速找到自己感兴趣的Maven插件。

另外的一些插件:

maven-site-plugin

maven-site-plugin是一个负责为Java项目生成静态HTML网站的插件。这个插件非常的有用,里面可以嵌入各种插件,比如用来对代码检查bug的findbugs,检查代码风格的checkstyle,生成testng测试报告的surefire等。先来看一下关于这个插件的配置的一个例子:

CheckStyle
请注意,checkstyle可以接受一个定制的规则文件,比如我这里的叫my_checkstyle.xml。这是从eclipse中导出的。

其实自己编辑这份xml文档也可以,语法规则还是很简单的。
有一个Maven插件可以帮助我对Java代码进行格式化,这个插件不属于maven-site-plugin管理,但是很有用。看我下面的配置:
这个插件需要一个从Eclipse导出的代表当前Eclipse编码风格的xml文件(你也可以手动编辑):
maven-java-formatter-plugin 对于我可是帮了大忙,我不用Eclipse开发,每次只要执行mvn clean compile,就会自动格式化我的Java代码。然后稍作修改,就满足CheckStyle的规则了。原来还用过一个叫做jalopy,那东西现在要付钱了,免费版本我记得并不好用。

Javadoc plugin
现在聊聊生成Java文档。maven-javadoc-plugin可以根据注释,自动生成文档。但是如果你还想要在文档里面看到UML静态结构图,需要制定使用UmlGraph.在我的Ubuntu下面,需要事先做一些准备工作:
1.下载UmlGraph 并安装,可以参考这里的文档:

http://www.umlgraph.org/doc/install.html (javadoc tool已经在安装jdk的时候装好了)

2.apt-get install graphviz
3.apt-get install plotutils

测试报告
要想使用surefire-report-plugin产生报告,还需要在site-plugin之外配置一个maven-surefire-plugin,里面指定了testng.xml,因为我用TestNG开发测试程序。

现在执行一下mvn clean site

会编译,测试,扫描代码,生成html文件.最后通过浏览器打开target/site/下面的project-reports.html。仔细看看,Java社区多么规范,Maven多么方便啊。

maven根据profile中定义的环境变量打包的设置

一个项目里总会有很多配置文件。而且一般都会有多套环境。开发的、测试的、正式的。而在这些不同的环境这些配置的值都会不一样。比如mail的配置、服务的url配置这些都是很常见的。所以在打包的时候就要根据environment来选不同的值或者配置文件。

比较常用的办法就是为不同的环境建立不同的配置文件目录。在打包的时候用对应的文件目录下的配置文件。

|-- resources
 |   |-- dev
 |   |-- product
 |   |-- qa
 |   `-- qa53

以前用ant的时候打包的时候处理就比较方便。打包前copy一下对应目录下的配置文件覆盖target下的那些文件再打包就可以了。在刚开始用 maven的时候就想要怎么解决,一直没有找到ant的这种方式的可行的办法。其实主要是按ant这种处理方法去思考了。只去想没有有cp这种 target。其实在maven里用profile就可以解决了。对于不同的environment定义不同的profile就ok了,目录结构还是沿用 原来的就可以。

在pom.xml里定义一个变量

<properties>
 ......
 <package.environment>qa53</package.environment>
 </properties>

这里定义的值是经常打包的一个profile,方便少敲点代码。然后定义一些profile

<profiles>
 <profile>
 <id>product</id>
 <properties>
 <package.environment>product</package.environment>
 </properties>
 </profile>
 <profile>
 <id>dev</id>
 <properties>
 <package.environment>dev</package.environment>
 </properties>
 </profile>
 <profile>
 <id>qa</id>
 <properties>
 <package.environment>qa</package.environment>
 </properties>
 </profile>
 </profiles>

最后再修改一下打包的plugin,引用这个变量。

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-war-plugin</artifactId>
 <configuration>
 <archive>
 <addMavenDescriptor>false</addMavenDescriptor>
 </archive>
 <webResources>
 <resource>
 <!-- this is relative to the pom.xml directory -->
 <directory>src/main/resources/${package.environment}</directory>
 <targetPath>WEB-INF/classes</targetPath>
 <filtering>true</filtering>
 </resource>
 </webResources>
 </configuration>
 </plugin>

这里注意一个参数<filtering>true</filtering>,一定要设置成true这样才会用对应environment目录下的配置文件覆盖原来的。ok。mvn package的时候就会用默认的qa53目录下的配置文件。如果要发布正式环境的包就运行。

mvn -Pproduct package

-----------------------------------

Profiles是maven的一个很关键的术语:profile是用来定义一些在build lifecycle中使用的environmental variations,profile可以设置成在不同的环境下激活不同的profile(例如:不同的OS激活不同的profile,不同的JVM激活不同的profile,不同的dabase激活不同的profile等等)。

定义Profiles

你可以把profiles定义在4个地方:

%M2_HOME%/conf/settings.xml,这是针对该部电脑的所有user的profiles,是global profiles,它会影响所有的maven project build

<your -home-directory>/.m2/settings.xml,这是针对per user的profiles,是user级的profiles,它会影响当前user的所有maven project build

定义在pom.xml文件里面,这是仅针对该project的profiles,是project级的profiles

profiles.xml,它和pom.xml在同一个目录下,也是project级的profiles,使用profiles.xml的目的是希望把profiles的设置从pom.xml里抽离出来设置。

定义在这4个地方的profiles中,涉及范围越窄的profiles会覆盖范围越宽的profiles。即:定义在pom.xml里profiles会覆盖profiles.xml的,profiles.xml的会覆盖<your -home-directory>/.m2/settings.xml的,<your -home-directory>/.m2/settings.xml的会覆盖%M2_HOME%/conf/settings.xml的。

不过请注意:设置在pom.xml里的profiles是最最推荐的,因为pom.xml会被deploy到repository里,所以pom.xml里的profiles才会available for subsequent builds originating from the repository or as transitive dependencies。而settings.xml和profiles.xml里定义的profiles不会被deploy到repository,则有诸多限制,因此,只有下面几个profiles能够在settings.xml和profiles.xml里定义:

repositories

pluginRepositories

properties

其他类型的profiles必须在pom.xml里定义(上面3个profiles也可以在pom.xml里定义)。

Pom.xml能够定义的profiles包括:

<repositories>
<pluginRepositories>
<dependencies>
<plugins>
<properties> (not actually available in the main POM, but used behind the scenes)
<modules>
<reporting>
<dependencyManagement>
<distributionManagement>
a subset of the <build> element, which consists of:
<defaultGoal>
<resources>
<testResources>
<finalName>

-----------------------------------

profile简介

profile可以让我们定义一系列的配置信息,然后指定其激活条件。这样我们就可以定义多个profile,然后每个profile对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。比如说,我们可以通过profile定义在jdk1.5以上使用一套配置信息,在jdk1.5以下使用另外一套配置信息;或者有时候我们可以通过操作系统的不同来使用不同的配置信息,比如windows下是一套信息,linux下又是另外一套信息,等等。具体的激活条件有哪些我在后文会讲到。

profile的定义位置

对于使用Maven3,我们可以有多个地方定义profile。定义的地方不同,它的作用范围也不同。

(1)    针对于特定项目的profile配置我们可以定义在该项目的pom.xml中。

(2)    针对于特定用户的profile配置,我们可以在用户的settings.xml文件中定义profile。该文件在用户家目录下的“.m2”目录下。

(3)    全局的profile配置。全局的profile是定义在Maven安装目录下的“conf/settings.xml”文件中的。

profile中能定义的信息

profile中能够定义的配置信息跟profile所处的位置是相关的。以下就分两种情况来讨论,一种是定义在settings.xml中,另一种是定义在pom.xml中。

profile定义在settings.xml中
当profile定义在settings.xml中时意味着该profile是全局的,它会对所有项目或者某一用户的所有项目都产生作用。因为它是全局的,所以在settings.xml中只能定义一些相对而言范围宽泛一点的配置信息,比如远程仓库等。而一些比较细致一点的需要根据项目的不同来定义的就需要定义在项目的pom.xml中。具体而言,能够定义在settings.xml中的信息有<repositories>、<pluginRepositories>和<properties>。定义在<properties>里面的键值对可以在pom.xml中使用。

profile定义在pom.xml中
定义在pom.xml中的profile可以定义更多的信息。主要有以下这些:

<repositories>
<pluginRepositories>
<dependencies>
<plugins>
<properties>
<dependencyManagement>
<distributionManagement>
还有build元素下面的子元素,主要包括:
<defaultGoal>
<resources>
<testResources>
<finalName>

 
profile的激活方式

Maven给我们提供了多种不同的profile激活方式。比如我们可以使用-P参数显示的激活一个profile,也可以根据环境条件的设置让它自动激活等。下面将对它们一一进行介绍:

使用activeByDefault设置激活

先看下面一个配置

    <profiles>  
            <profile>  
                 <id>profileTest1</id>  
                 <properties>  
                        <hello>world</hello>  
                 </properties>  
                 <activation>  
                        <activeByDefault>true</activeByDefault>  
                 </activation>  
            </profile>  
              
            <profile>  
                 <id>profileTest2</id>  
                 <properties>  
                        <hello>andy</hello>  
                 </properties>  
            </profile>  
     </profiles>

我们可以在profile中的activation元素中指定激活条件,当没有指定条件,然后指定activeByDefault为true的时候就表示当没有指定其他profile为激活状态时,该profile就默认会被激活。所以当我们调用mvn package的时候上面的profileTest1将会被激活,但是当我们使用mvn package –P profileTest2的时候将激活profileTest2,而这个时候profileTest1将不会被激活。

在settings.xml中使用activeProfiles指定处于激活状态的profile
我们可以在settings.xml中使用activeProfiles来指定需要激活的profile,这种方式激活的profile将所有情况下都处于激活状态。比如现在我们定义了如下两个profile

 

    <profiles>  
           <profile>  
                <id>profileTest1</id>  
                <properties>  
                       <hello>world</hello>  
                </properties>  
           </profile>  
             
           <profile>  
                <id>profileTest2</id>  
                <properties>  
                       <hello>andy</hello>  
                </properties>  
           </profile>  
    </profiles>

这里的profile可以是定义在settings.xml中的,也可以是定义在pom.xml中的。这个时候如果我们需要指定profileTest1为激活状态,那么我们就可以在settings.xml中定义activeProfiles,具体定义如下:

<activeProfiles>  
         <activeProfile>profileTest1</activeProfile>  
    </activeProfiles>

考虑这样一种情况,我们在activeProfiles下同时定义了多个需要激活的profile。这里还拿上面的profile定义来举例,我们定义了同时激活profileTest1和profileTest2。

    <activeProfiles>  
         <activeProfile>profileTest1</activeProfile>  
         <activeProfile>profileTest2</activeProfile>  
    </activeProfiles>

从profileTest1和profileTest2我们可以看出它们共同定义了属性hello。那么这个时候我在pom.xml中使用属性hello的时候,它到底取的哪个值呢?是根据activeProfile定义的顺序,后面的覆盖前面的吗?根据我的测试,答案是非也,它是根据profile定义的先后顺序来进行覆盖取值的,然后后面定义的会覆盖前面定义的。

使用-P参数显示的激活一个profile
假设我们现在有如下定义的profiles

    <profiles>  
           <profile>  
                  <id>profileTest1</id>  
                  <properties>  
                         <hello>world</hello>  
                  </properties>  
           </profile>  
           <profile>  
                  <id>profileTest2</id>  
                  <properties>  
                         <hello>andy</hello>  
                  </properties>  
           </profile>  
    <profiles>  

那么当我们在进行Maven操作时就可以使用-P参数显示的指定当前激活的是哪一个profile了。比如我们需要在对项目进行打包的时候使用id为profileTest1的profile,我们就可以这样做:

mvn package –P profileTest1

当我们使用activeByDefault或settings.xml中定义了处于激活的profile,但是当我们在进行某些操作的时候又不想它处于激活状态,这个时候我们可以这样做:
Cmd代码  收藏代码

Mvn package –P !profileTest1

这里假设profileTest1是在settings.xml中使用activeProfile标记的处于激活状态的profile,那么当我们使用“-P !profile”的时候就表示在当前操作中该profile将不处于激活状态。

根据环境来激活profile

profile一个非常重要的特性就是它可以根据不同的环境来激活,比如说根据操作系统的不同激活不同的profile,也可以根据jdk版本的不同激活不同的profile,等等。
根据jdk来激活profile

    <profiles>  
           <profile>  
                  <id>profileTest1</id>  
                  <jdk>1.5</jdk>  
           </profile>  
    <profiles>

上面情况表示在jdk为1.5版本系列的时候激活profileTest1。

 <profiles>  
           <profile>  
                  <id>profileTest1</id>  
                  <jdk>[1.4,1.7)</jdk>  
           </profile>  
    <profiles>

上面的情况表示在jdk为1.4、1.5和1.6的时候激活profileTest1。

根据操作系统来激活profile

<profiles>
<profile>
<id>profileTest1</id>
<activation>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
</activation>
</profile>
</profiles>

上面的情况就是根据操作系统的类型来激活profileTest1。

根据系统属性来激活profile

<profiles>
<profile>
<id>profileTest1</id>
<activation>
<property>
<name>hello</name>
<value>world</value>
</property>
</activation>
</profile>
</profiles>

上面的profileTest1将在提供了系统属性hello,并且其值为world的时候激活。下面的做法可以激活profileTest1。

mvn package –Dhello=world

当是下面的这种定义形式时,profileTest1将在指定了系统属性hello,且其值为任意值的时候被激活。

<profiles>
<profile>
<id>profileTest1</id>
<activation>
<property>
<name>hello</name>
</property>
</activation>
</profile>
</profiles>

根据文件是否存在激活profile
<profiles>
<profile>
<id>profileTest1</id>
<activation>
<file>
<exists>target</exists>
</file>
</activation>
</profile>
</profiles>

上面的定义表示当存在target文件时激活profileTest1。

<profiles>
<profile>
<id>profileTest1</id>
<activation>
<file>
<missing>target</missing>
</file>
</activation>
</profile>
</profiles>

上面的定义表示当不存在target文件时激活profileTest1。

我们可以同时定义多个profile,那么在建立项目的过程中,到底激活的是哪一个profile呢?Maven为我们提供了一个指令可以查看当前处于激活状态的profile都有哪些,这个指定就是mvn help:active-profiles。

现在假设我们的settings.xml文件中有如下profile的定义:

<profiles>
<profile>
<id>profileTest1</id>
<activation>
<file>
<missing>target</missing>
</file>
</activation>
</profile>
</profiles>

<activeProfiles>
<activeProfile>profileTest1</activeProfile>
</activeProfiles>

这个时候我们可以看到,我们已经定义了profileTest1始终为激活状态,这个时候我们使用mvn help:active-profiles查看处于激活状态的profile时,就会打印出如下内容: