参考资料:http://my.oschina.net/zh119893/blog/276090 html
咱们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,全部这些任务都交给插件来完成。java
例如编译源代码是由maven-compiler-plugin完成的。web
进一步说,每一个任务对应了一个插件目标(goal),每一个插件会有一个或者多个目标。apache
例如maven-compiler-plugin的compile目标用来编译位于src/main/java/
目录下的主源码,testCompile目标用来编译位于src/test/java/
目录下的测试源码。浏览器
用户能够经过两种方式调用Maven插件目标。tomcat
第一种方式是将插件目标与生命周期阶段(lifecycle phase)绑定,这样用户在命令行只是输入生命周期阶段而已。服务器
例如Maven默认将maven-compiler-plugin的compile目标与compile生命周期阶段绑定,所以命令mvn compile其实是先定位到compile这一辈子命周期阶段,而后再根据绑定关系调用maven-compiler-plugin的compile目标。并发
第二种方式是直接在命令行指定要执行的插件目标。app
例如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。
接下来介绍一些经常使用的MAVEN插件
http://maven.apache.org/plugins/maven-antrun-plugin/
maven-antrun-plugin能让用户在Maven项目中运行Ant任务。用户能够直接在该插件的配置以Ant的方式编写Target,而后交给该插件的run目标去执行。
在一些由Ant往Maven迁移的项目中,该插件尤为有用。
此外当你发现须要编写一些自定义程度很高的任务,同时又以为Maven不够灵活时,也能够以Ant的方式实现之。maven-antrun-plugin的run目标一般与生命周期绑定运行。
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,帮助他们快速上手。
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目标能够直接在命令行调用,也能够被绑定至生命周期。
http://maven.apache.org/plugins/maven-dependency-plugin/
maven-dependency-plugin最大的用途是帮助分析项目依赖
dependency:list可以列出项目最终解析到的依赖列表
dependency:tree能进一步的描绘项目依赖树
dependency:analyze能够告诉你项目依赖潜在的问题
若是你有直接使用到的却未声明的依赖,该目标就会发出警告。
maven-dependency-plugin还有不少目标帮助你操做依赖文件,例如dependency:copy-dependencies能将项目依赖从本地Maven仓库复制到某个特定的文件夹下面。
http://maven.apache.org/plugins/maven-enforcer-plugin/
在一个稍大一点的组织或团队中,你没法保证全部成员都熟悉Maven,那他们作一些比较愚蠢的事情就会变得很正常。
例如给项目引入了外部的SNAPSHOT依赖而致使构建不稳定,使用了一个与你们不一致的Maven版本而常常抱怨构建出现诡异问题。
maven-enforcer-plugin可以帮助你避免之类问题,它容许你建立一系列规则强制你们遵照,包括设定Java版本、设定Maven版本、禁止某些依赖、禁止SNAPSHOT依赖。
只要在一个父POM配置规则,而后让你们继承,当规则遭到破坏的时候,Maven就会报错。
除了标准的规则以外,你还能够扩展该插件,编写本身的规则。maven-enforcer-plugin的enforce目标负责检查规则,它默认绑定到生命周期的validate阶段。
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。
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的各类目标一般直接在命令行调用,由于版本发布显然不是平常构建生命周期的一部分。
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传入属性的值,以实现更为灵活的构建。
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参数实现的。
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到远程仓库。
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 以查看运行效果。
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加入。
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插件也不是难事,更况且还有这么多开放源代码的插件供你参考。
一些常见例子
① maven-jetty-plugin
http://blog.sina.com.cn/s/blog_62b0363101012he0.html
http://stamen.iteye.com/blog/1933452
输入:mvn jetty:run。这将在端口为8080的Jetty服务器上启动你的项目。Jetty将持续运行,直到插件是明确中止。例如,按下<ctrl-c>,或使用mvn jetty:stop命令。
<build> <finalName>rop-sample</finalName> <plugins> <!-- jetty插件 --> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.5</version> <configuration> <webAppSourceDirectory>src/main/webapp</webAppSourceDirectory> <scanIntervalSeconds>3</scanIntervalSeconds> <contextPath>/</contextPath> <connectors> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> <port>8088</port> </connector> </connectors> </configuration> </plugin> </plugins> </build>
② maven-compiler-plugin 编译源代码
在Maven项目下,咱们须要配置"maven-compiler-plugin"的"encoding"参数
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <encoding>UTF8</encoding> </configuration> </plugin> </plugins>
须要在编译和生成的时候使用不一样的jdk版本
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.6</source> <target>1.7</target> </configuration> </plugin>
③ maven-war-plugin
打包war项目的时候排除某些web资源文件,这时就应该配置maven-war-plugin以下:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.1.1</version> <configuration> <webResources> <resource> <directory>src/main/webapp</directory> <excludes> <exclude>**/*.jpg</exclude> </excludes> </resource> </webResources> </configuration> </plugin>
④ maven-source-plugin 生成源码包
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.1.2</version> <executions> <execution> <id>attach-sources</id> <phase>verify</phase> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin>
<!-- 源代码打包插件 -->
<plugin> <artifactId>maven-source-plugin</artifactId> <version>2.1</version> <configuration> <!-- <finalName>${project.build.name}</finalName> --> <attach>true</attach> <encoding>${project.build.sourceEncoding}</encoding> </configuration> <executions> <execution> <phase>compile</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin>
⑤ maven-javadoc-plugin 生成javadoc包
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <version>2.7</version> <executions> <execution> <id>attach-javadocs</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin>
⑥ maven-assembly-plugin
它支持各类打包文件格式,包括zip、tar.gz、tar.bz2等等,经过一个打包描述文件(该例中是src/main/assembly.xml),它可以帮助用户选择具体打包哪些文件集合、依赖、模块、和甚至本地仓库文件,每一个项的具体打包路径用户也能自由控制。以下就是对应上述需求的打包描述文件src/main/assembly.xml:
<assembly> <id>bin</id> <formats> <format>zip</format> </formats> <dependencySets> <dependencySet> <useProjectArtifact>true</useProjectArtifact> <outputDirectory>lib</outputDirectory> </dependencySet> </dependencySets> <fileSets> <fileSet> <outputDirectory>/</outputDirectory> <includes> <include>README.txt</include> </includes> </fileSet> <fileSet> <directory>src/main/scripts</directory> <outputDirectory>/bin</outputDirectory> <includes> <include>run.sh</include> <include>run.bat</include> </includes> </fileSet> </fileSets> </assembly>
最终生成一个zip格式的分发包,它包含以下的一个结构:
bin/
lib/
README.txt
最后,咱们须要配置maven-assembly-plugin使用打包描述文件,并绑定生命周期阶段使其自动执行打包操做:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.2.1</version> <configuration> <descriptors> <descriptor>src/main/assembly/assembly.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
运行mvn clean package以后,咱们就能在target/目录下获得名为hello-world-1.0-bin.zip的分发包了。
⑦ maven-surefire-plugin 打包时跳过单元测试
<plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.6</version> <configuration> <skip>true</skip> </configuration> </plugin>
mvn package -Dmaven.test.skip=true
若是单元测试中有输出中文,eclipse的控制台里中文可能会变成乱码输出,也能够经过这个插件解决,参考配置:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.16</version> <configuration> <forkMode>once</forkMode> <argLine>-Dfile.encoding=UTF-8</argLine> </plugin>
⑧ maven-resource-plugin
<!-- 设置资源文件的编码方式 -->
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.4.3</version> <executions> <execution> <phase>compile</phase> </execution> </executions> <configuration> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin>
把web项目的输出copy到tomcat的webapp下
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.5</version> <executions> <execution> <id>deploy-website</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${server_home}/webapps/${project.build.finalName}</outputDirectory> <resources> <resource> <directory>${project.build.directory}/${project.build.finalName}</directory> </resource> </resources> </configuration> </execution> </executions> </plugin>
⑨ maven-dependency-plugin
自动拷贝jar包到target目录
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>copy-dependencies</id> <phase>compile</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <!-- ${project.build.directory}为Maven内置变量,缺省为target --> <outputDirectory>${project.build.directory}/lib</outputDirectory> <!-- 表示是否不包含间接依赖的包 --> <excludeTransitive>false</excludeTransitive> <!-- 表示复制的jar文件去掉版本信息 --> <stripVersion>true</stripVersion> </configuration> </execution> </executions> </plugin>
在部署war包时,须要将项目依赖的jar包,也打到war包中,所以就会用到上述插件
⑩ 在打包时,须要清空一些指定的目录
在一个J2EE项目中,想使用mvn clean命令清除target里的内容的同时,也清除tomcat/webapp下的相应目录,该怎么办呢?
<plugin> <artifactId>maven-clean-plugin</artifactId> <configuration> <verbose>true</verbose> <filesets> <fileset> <directory>c:/a/b/c/</directory> </fileset> </filesets> </configuration> </plugin>
本例中,删除的是c:/a/b/c/目录.
当用户在该maven项目中执行mvn clean后,除了删除clean插件默认的
project.build.directory
project.build.outputDirectory
project.build.testOutputDirectory
project.reporting.outputDirectory
c:/a/b/c/
十一、利用tomcat-maven-plugin插件将项目自动打包并部署到tomcat中
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> <configuration> <server>tomcat6-manager</server> <path>/${project.build.name}</path> <url>http://localhost:8080/manager</url> <username>admin</username> <password>admin</password> </configuration> <executions> <execution> <phase>deploy</phase> <goals> <goal>deploy</goal> </goals> </execution> </executions> </plugin> </plugins>
path: 是指项目部署到tomcat后的项目名称
url: 是指tomcat的manager访问地址
server: 这个是tomcat服务名称设置,须要配置maven的settings.xml文件,在servers节点中手动配置server,以下所示:
<server> <id>tomcat6-manager</id> <username>admin</username> <password>admin</password> </server>
十二、利用cargo-maven2-plugin插件将项目自动打包并部署到tomcat中
cargo插件能够帮助你完成WAR包到服务器的部署及服务器的启动和关闭等工做,方便,快速!
<plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <version>1.2.0</version> <configuration> <container> <containerId>${server_name}</containerId> <home>${server_home}</home> </container> <configuration> <type>existing</type> <home>${server_home}</home> <properties> <cargo.servlet.port>8088</cargo.servlet.port> </properties> </configuration> </configuration> </plugin>
注意,若是你的tomcat服务器的端口使用的不是默认的8080(如本例中的8088),则须要使用cargo.servlet.port参数将cargo的监听端口也配置到tomcat的那个监听端口(如本例中的8088),不然使用mvn cargo:run启动的服务器会在120000毫秒(120秒)后自动关闭!
mvn cargo:start命令完成WAR包部署后,启动服务器,而后会将服务器当即关掉;
mvn cargo:run命令完成WAR包部署后,启动服务器,直到你Ctrl+C将服务器关掉;
mvn cargo:stop命令关闭服务器。
参考:http://cargo.codehaus.org/Maven2+plugin
<plugin> <!-- 指定插件名称及版本号 --> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <version>1.2.3</version>
<!-- 插件的Tomcat6.x配置 --> <configuration> <!-- 容器的配置 --> <container> <!-- 指定服务器版本 --> <containerId>tomcat6x</containerId> <!-- 指定服务器的安装目录 --> <home>E:\Program Files\tomcat-6.0.32</home> </container> <!-- 具体的配置 --> <configuration> <!-- 部署模式:existing、standalone等 --> <type>existing</type> <!-- Tomcat的位置,即catalina.home --> <home>E:\Program Files\tomcat-6.0.32</home> <!-- 配置属性 --> <properties> <!-- 管理地址 --> <cargo.tomcat.manager.url>http://localhost:8080/manager</cargo.tomcat.manager.url> <!-- Tomcat用户名 --> <cargo.remote.username>admin</cargo.remote.username> <!-- Tomcat密码 --> <cargo.remote.password>admin</cargo.remote.password> <!-- <cargo.jvmargs> -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787 </cargo.jvmargs> --> </properties> </configuration> </configuration> </plugin>