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>
官方文檔鏈接: