Maven本质上是一个执行插件的框架。插件共分两类:build插件和reporting插件。
- build插件,会在build阶段被执行,应该配置在POM的<build/>元素中。
- reporting插件,生成站点的时候会执行,应该配置在POM的<reporting/>元素中。因为reporting插件的结果是生成的站点的一部分,所以这种插件应该是国际化和本地化的。此处更多详见 http://maven.apache.org/plugins/localization.html。
但所有的插件至少都需要指明:groupId、artifactId、version。
通用配置
Maven插件都是通过指定一个<configuration>元素来配置的。而该元素中的子元素,都是Mojo中的property。
详见 http://maven.apache.org/guides/mini/guide-configuring-plugins.html 。
配置build插件
下面仅仅是在<build>元素中配置build插件。
使用<executions>标签
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<此处未完待续>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Maven项目支持的插件
org/apache/maven/plugins中有最新的插件列表。
核心插件
clean 负责build之后的清理工作
compiler 编译Java源码
deploy 将构建好的artifact部署到远程仓库
failsafe 在隔离的类加载器中运行JUnit集成测试
install 将构建好的artifact部署到本地仓库
resources 将资源复制到输出文件夹,以包含进JAR中。
site 为当前项目生成一个站点
surefire 在一个隔离的类加载器中运行JUnit单元测试
verifier 对集成测试有用 -- 校验特定环境的存在性
负责打包的类型/工具
ear 为当前项目生成一个EAR
jar 从当前项目构建一个JAR
rar 从当前项目构建一个RAR
war 从当前项目构建一个WAR
shade 从当前项目构建一个Uber_JAR,包含依赖。(也叫fat jar或super jar)
source 从当前项目构建一个源码JAR
Maven大陆之外的插件:codehaus.org, code.google.com, misc
misc,其他的缩写。主要是指由各个项目提供的Maven插件,这里仅列出两个:
下面用一些例子来说明使用的方法
一、WAR插件,有4种方式来使用它:
- 将项目package成war类型
- 调用 war:war goal
- 调用 war:exploded goal
- 调用 war:inplace goal
注意:当使用 war: goals时,它会假定compile阶段已经完成。
<project> ... <build> <!-- 在parent POM中定义版本 --> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.0.0</version> </plugin> ... </plugins> </pluginManagement> <!-- 在POM 或 parent POM中使用插件 --> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.0.0</version> </plugin> ... </plugins> </build> ... </project>
<project> ... <groupId>com.example.projects</groupId> <artifactId>documentedproject</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>Documented Project</name> <url>http://example.com</url> ... </project>
- 调用 mvn package 或者 mvn compile war:war,会在 target/ 下面生产相应版本的war文件(文件名是:artifactId-version.war)。
- 调用 mvn compile war:exploded 则会在 target/ 下面生成非打包的war文件夹。该文件夹的名字是finalName,而finalName通常是artifactId-version形式。当然,可以通过制定 webappDirectory参数来覆盖默认。
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.0.0</version> <configuration> <webappDirectory>/sample/servlet/container/deploy/directory </webappDirectory> </configuration> </plugin> </plugins> </build> ... </project>
- 调用 mvn compile war:inplace,则会在 src/main/webapp/ 下面创建未打包的war文件夹。
小结:4种调用方式,但实际效果是3种,区别在于最终创建的是文件还是文件夹、在什么地方创建(target/, src/main/webapp/)。
Maven项目默认的资源文件夹是 src/main/resources,最终会出现在WAR文件的target/classes 和 WEB-INF/classes中。
WAR插件可以使用webResources参数来包含默认资源文件夹以外的资源。
添加web资源:
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.0.0</version> <configuration> <webResources> <resource> <!-- this is relative to the pom.xml directory --> <directory>resource2</directory> </resource> </webResources> </configuration> </plugin> </plugins> </build> ... </project>
我们的示例项目带有额外的外部资源,其结构如下:
- .
- |-- pom.xml
- |-- resource2
- | |-- external-resource.jpg
- | `-- image2
- | `-- external-resource2.jpg
- `-- src
- `-- main
- |-- java
- | `-- com
- | `-- example
- | `-- projects
- | `-- SampleAction.java
- |-- resources
- | `-- images
- | `-- sampleimage.jpg
- `-- webapp
- |-- WEB-INF
- | `-- web.xml
- |-- index.jsp
- `-- jsp
- `-- websource.jsp
最终在WAR中的结构如下:
- documentedproject-1.0-SNAPSHOT.war
- |-- META-INF
- | |-- MANIFEST.MF
- | `-- maven
- | `-- com.example.projects
- | `-- documentedproject
- | |-- pom.properties
- | `-- pom.xml
- |-- WEB-INF
- | |-- classes
- | | |-- com
- | | | `-- example
- | | | `-- projects
- | | | `-- SampleAction.class
- | | `-- images
- | | `-- sampleimage.jpg
- | `-- web.xml
- |-- external-resource.jpg
- |-- image2
- | `-- external-resource2.jpg
- |-- index.jsp
- `-- jsp
- `-- websource.jsp
注意: external-resource2.jpg 和 image2 都被复制到WAR的root目录下,保持了目录结构。
配置web资源
webResources 是一组资源列表。支持资源的所有选项。
web资源:
- 能够被 includes/excludes
- 能够被 filtered
- 不限于默认位置 -- root of WAR
includes/excludes
想要在WAR中包含所有jpgs,可以这样设置POM:
... <configuration> <webResources> <resource> <!-- this is relative to the pom.xml directory --> <directory>resource2</directory> <!-- the list has a default value of ** --> <includes> <include>**/*.jpg</include> </includes> </resource> </webResources> </configuration> ...
想要在WAR中排除image2目录:
... <configuration> <webResources> <resource> <!-- this is relative to the pom.xml directory --> <directory>resource2</directory> <!-- there's no default value for this --> <excludes> <exclude>**/image2</exclude> </excludes> </resource> </webResources> </configuration> ...
当混合使用includes和excludes时,要小心,excludes的优先级更高。
从WAR中包含或排除文件
通过 <packagingIncludes> 或 <packagingExcludes> 配置参数来实现。它们都可以接收一个逗号间隔的Ant风格文件列表。
就是说,使用 ** 来代表多级目录,使用 * 来代表文件或目录名字的一部分。
例如,排除所有WEB-INF/lib 下的JAR文件:
<project> ... <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.0.0</version> <configuration> <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes> </configuration> </plugin> </plugins> </build> ... </project>
有时候,仅使用这种通配符是不够的。这时你可以使用正则表达式,%regex[]。
下面的例子中,我们想排除所有commons-logging和log4j JARs,但不想排除log4j-over-slf4j JAR。
<project> ... <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.0.0</version> <configuration> <!-- Exclude JCL and LOG4J since all logging should go through SLF4J. Note that we're excluding log4j-<version>.jar but keeping log4j-over-slf4j-<version>.jar --> <packagingExcludes> WEB-INF/lib/commons-logging-*.jar, %regex[WEB-INF/lib/log4j-(?!over-slf4j).*.jar] </packagingExcludes> </configuration> </plugin> </plugins> </build> ... </project>
二、Tomcat Maven插件
注意,之前该插件是位于Codehaus上面,可惜那个网站已经over了。
现在在这里:https://tomcat.apache.org/maven-plugin-2.2/
2.2 版本新功能:
- 支持Tomcat 7
- 可以build executable WAR/JAR了
该插件提供了用于在Tomcat中操作WAR项目、或者使用一个内置Tomcat来运行你的WAR项目的goals。这些goals可以让你快速开发你的应用,而不必单独安装一个Tomcat实例。
关于groupId 和Mojo name的变更
自版本 2.0-beta-1 起,tomcat mojos已经被重命名为tomcat6 和 tomcat7,二者goals相同。
所以,你必须这样使用它们:
在POM中:
<pluginManagement> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat6-maven-plugin</artifactId> <version>2.2</version> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> </plugin> </plugins> </pluginManagement>
或者在settings.xml中:
<pluginGroups> .... <pluginGroup>org.apache.tomcat.maven</pluginGroup> .... </pluginGroups>
goals概览
context goals、container goals、build an executable WAR/JAR
context goals
该插件提供了可以在项目的context上执行不同任务的goals -- 只要项目已经被部署到Tomcat中。如下:
- 重新部署一个WAR项目
- 当项目是使用tomcat:deploy 部署的WAR项目时,可以使用 mvn package tomcat6/7:redeploy
- 当项目是使用tomcat:exploded部署的WAR项目时,可以使用 mvn war:exploded tomcat6/7:redeploy
- 当项目是使用tomcat:inplace部署的WAR项目时,可以使用 mvn war:inplace tomcat6/7:redeploy
- 想要重新部署使用tomcat:deploy部署的一个context.xml文件时,可以使用 mvn tomcat6/7:redeploy
重新部署一个WAR项目取决于该项目部署的方式:
注意:取决于context.xml中指定的docBase,可能也会需要像上面那样调用 war:exploded 或者 war:inplace。
- 取消部署一个WAR项目
mvn tomcat6/7:undeploy
- 启动一个WAR项目
mvn tomcat6:start
- 停止一个WAR项目
mvn tomcat6:stop
- 列出会话统计
mvn tomcat6:sessions
container goals
该插件还提供了获取Tomcat容器各种信息的goals:
- 列出被部署的所有项目
mvn tomcat6:list
- 列出服务器信息
mvn tomcat6:info
- 列出JNDI资源
mvn tomcat6:resources -- 列出所有Tomcat内可用的JNDI资源
mvn -Dmaven.tomcat.type=my.class.name tomcat6:resources -- 列出特定类型的JNDI资源
- 列出安全角色
mvn tomcat6:roles
build an executable WAR/JAR
从 2.0 版本开始,可用使用一个内置的Tomcat7来build一个可执行的WAR/JAR。
仅tomcat7 插件支持!
注意:你的项目的<packaging/>的值必须是pom或war。
需要添加至war模块的artifact
<project> ... <packaging>war or pom</packaging> ... <build> ... <plugins> ... <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <executions> <execution> <id>tomcat-run</id> <goals> <goal>exec-war-only</goal> </goals> <phase>package</phase> <configuration> <path>foo</path> <!-- optional, needed only if you want to use a preconfigured server.xml file --> <serverXml>src/main/tomcatconf/server.xml</serverXml> <!-- optional values which can be configurable --> <attachArtifactClassifier>default value is exec-war but you can customize</attachArtifactClassifier> <attachArtifactClassifierType>default value is jar</attachArtifactClassifierType> </configuration> </execution> </executions> </plugin> ... </plugins> ... </build> ... </project>
需要添加至你的pom模块的artifact:
<project> ... <packaging>war</packaging> ... <build> ... <plugins> ... <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <executions> <execution> <id>tomcat-run</id> <goals> <goal>exec-war-only</goal> </goals> <phase>package</phase> <configuration> <!-- optional only if you want to use a preconfigured server.xml file --> <!-- <serverXml>src/main/tomcatconf/server.xml</serverXml> --> <warRunDependencies> <warRunDependency> <dependency> <groupId>a groupId</groupId> <artifactId>and artifactId</artifactId> <version>version</version> <type>war</type> </dependency> <contextPath>/</contextPath> </warRunDependency> </warRunDependencies> <!-- naming is disabled by default so use true to enable it --> <enableNaming>true</enableNaming> <!-- extra dependencies to add jdbc driver, mail jars, etc. --> <extraDependencies> <extraDependency> <groupId>org.apache.derby</groupId> <artifactId>derby</artifactId> <version>10.1.3.1</version> </extraDependency> <extraDependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4</version> </extraDependency> </extraDependencies> </configuration> </execution> </executions> </plugin> ... </plugins> ... </build> ... </project>
生成的executable jar/war
通过上面的配置,你可以执行该生成的jar (因其内置了Tomcat容器):
java -jar yourjar
辅助输出的参数:
usage: java -jar [path to your exec war jar] -ajpPort <ajpPort> ajp port to use -clientAuth enable client authentication for https -D <arg> key=value -extractDirectory <extractDirectory> path to extract war content, default value: .extract -h,--help help -httpPort <httpPort> http port to use -httpProtocol <httpProtocol> http protocol to use: HTTP/1.1 or org.apache.coyote.http11.Http11Nio Protocol -httpsPort <httpsPort> https port to use -keyAlias <keyAlias> alias from keystore for ssl -loggerName <loggerName> logger to use: slf4j to use slf4j bridge on top of jul -obfuscate <password> obfuscate the password and exit -resetExtract clean previous extract directory -serverXmlPath <serverXmlPath> server.xml to use, optional -X,--debug debug
运行Mojo:让你的Maven war 项目更快速地运行
当开发一个war项目时,通常需要build war,然后将其部署到一个安装好的Tomcat实例中。这很耗费时间和资源,同时必须有一个本地的Tomcat实例。
而运行mojo则可以让你免于这些,只需要在你的Maven build的内置Tomcat实例中运行war即可。
注意,如果你有多个Maven项目,且在使用Maven 3,你不需要在运行goal之前install所有资源,在根模块直接使用tomcat6/7:run 即可,该插件会自动探测不同模块的build输出目录,并会使用webapp类加载器中的这些目录来替换依赖。
运行内置Tomcat
在POM中配置插件的版本,并使用 mvn tomcat6/7:run 。
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <!-- or if you want to use tomcat 6.x <artifactId>tomcat6-maven-plugin</artifactId> --> <version>2.2</version> <configuration> <!-- http port --> <port>9090</port> <!-- application path always starts with / --> <path>/</path> <!-- optional path to a context file --> <contextFile>${tomcatContextXml}</contextFile> <!-- optional system propoerties you want to add --> <systemProperties> <appserver.base>${project.build.directory}/appserver-base</appserver.base> <appserver.home>${project.build.directory}/appserver-home</appserver.home> <derby.system.home>${project.build.directory}/appserver-base/logs</derby.system.home> <java.io.tmpdir>${project.build.directory}</java.io.tmpdir> </systemProperties> <!-- if you want to use test dependencies rather than only runtime --> <useTestClasspath>false</useTestClasspath> <!-- optional if you want to add some extra directories into the classloader --> <additionalClasspathDirs> <additionalClasspathDir></additionalClasspathDir> </additionalClasspathDirs> </configuration> <!-- For any extra dependencies needed when running embedded Tomcat (not WAR dependencies) add them below --> <dependencies> <dependency> <groupId>org.apache.derby</groupId> <artifactId>derby</artifactId> <version>${derbyVersion}</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4</version> </dependency> </dependencies> </plugin>
Maven项目结构
pom.xml (top level pom with packaging pom)
my-api/pom.xml (API project with packaging jar)
my-api-impl/pom.xml (API implementation project with packaging jar)
my-webapp/pom.xml (webapp project with packaging war)
对于上面这样的结构,需要从顶级目录运行:mvn tomcat6/7:run -pl :my-webapp -am
配合selenium mojo使用
你可以使用该mojo在Tomcat实例中启动你的项目,并针对该实例运行你的selenium测试。
下列配置会在pre-integration-test中启动一个内置的Tomcat,然后在 post-integration-test时关闭它。
<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <!-- or if you want to use tomcat 6.x <artifactId>tomcat6-maven-plugin</artifactId> --> <version>2.2</version> <executions> <execution> <id>tomcat-run</id> <goals> <goal>run-war-only</goal> </goals> <phase>pre-integration-test</phase> <configuration> .... <fork>true</fork> .... </configuration> </execution> <execution> <id>tomcat-shutdown</id> <goals> <goal>shutdown</goal> </goals> <phase>post-integration-test</phase> </execution> </executions> </plugin>
官方文档链接: