Maven HowTo
Table of Contents
1 maven 简介
我们先不谈maven是什么,我们先说,我们开发一个应用需要什么
- 编译,测试,运行,打包
- 管理依赖
- 项目报告
好的,maven以统一的形式提供了这些功能,虽然几乎所有功能都是以插件的形式提供的。
2 安装 maven
安装很简单,下载源码,解压,把bin目录添加到 PATH 路径即可。
# mvn -version Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T19:57:37+08:00)
能正确运行,说明安装成功
3 修改maven源
maven的默认源在国内很慢,在 $MAVEN_HOME/conf/settings.xml
的 mirrors 下增加国内的maven镜像源,下载依赖时提速明显。
<mirror> <id>CN</id> <name>Aliyun Nexus</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> <mirrorOf>central</mirrorOf> </mirror>
4 创建项目
要使用maven,项目必须符合一定的目录规范,最简单的方法就是用maven来创建项目。
# mvn archetype:generate -DgroupId=example -DartifactId=howto -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false # tree howto howto/ ├── pom.xml └── src ├── main │ └── java │ └── example │ └── App.java └── test └── java └── example └── AppTest.java
5 样板 pom.xml
除了目录结构外,pom.xml 是 maven 的核心, package
是包的类型 jar
或者 war
, properties
中定义的值可以在其它地方引用, dependencies
定义依赖, build
定义构建过程需要的插件, reporting
定义构建完后的一些报告插件。maven的大部分功能都是通过插件提供的,后面会说一些比较有用的插件。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>example</groupId> <artifactId>howto</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>howto</name> <url>http://maven.apache.org</url> <properties> <java.version>1.8</java.version> <spring.version>4.2.5.RELEASE</spring.version> <jetty.http.port>8888</jetty.http.port> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.2.4.Final</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <compilerArgs> <arg>-Xlint:unchecked</arg> <arg>-Xlint:deprecation</arg> </compilerArgs> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <packagingExcludes> WEB-INF/lib/slf4j-api-*.jar </packagingExcludes> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.3.4.RC1</version> <configuration> <httpConnector> <port>${jetty.http.port}</port> </httpConnector> </configuration> </plugin> </plugins> </build> <reporting> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>3.6</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>findbugs-maven-plugin</artifactId> <version>3.0.3</version> <configuration> <excludeFilterFile>findbugs-exclude.xml</excludeFilterFile> </configuration> </plugin> </plugins> </reporting> </project>
6 常用的maven命令和选项
- mvn compile 编译
- mvn test-compile 仅编译测试
- mvn package 打
war
或者jar
包 - mvn clean 清除 package 或其它过程中产生的中间文件
- mvn dependency:help 查看 dependency 插件的帮助
- mvn site 查看项目报告,把 target/site 配置到 http doc 目录,可以以web方式查看
- -T xC 使用x个cpu,例如:mvn test -T 1C,使用1个CPU运行mvn test
通过 MAVEN_OPTS
环境变量,可以设置java的启动参数,例如 export MAVEN_OPTS="-Xmx512M -Xms512M"
目标是可以组合的,例如 mvn clean package jetty:run
跳过某些插件的方法似乎是通用的:
- 跳过测试插件 maven-test-plugin,-Dmaven.test.skip=true
- 跳过 maven-antrun-plugin,-Dmaven.antrun.skip=true
7 mvn test 常用选项
- -Dtest=my.package.TestCircle 只测试 TestCircle
- -Dtest=my.package.TestCi*le 模糊匹配
- -Dtest=my.package.TestSquare,my.package.TestCi*le 指定多个
- -Dtest=my.package.TestCircle#mytest 指定方法
- -Dtest=my.package.TestCircle#test* 模糊匹配
- -Dtest=my.package.TestCircle#testOne+testTwo 指定多个方法
注意 这里TestCircle在my.package下,一定要带上包名。
8 管理依赖
通过 dependency
填写依赖,maven会在本地缓存一份数据 $HOME/.m2/repository
依赖管理是个很便捷的东西。c和c++就没有类似的项目,Makefile 里面指定的依赖额外安装。
8.1 处理maven仓库中不存在的库
有时候会碰到jar包不在标准maven仓库的情况,这时有两种选择,一种是自己搭建maven仓库,另一种是把jar把安装到maven缓存中,这里介绍第二种方法。
# download jar curl http://path-to-jar/org.patchca.patchca-0.6.0.jar -o org.patchca.patchca-0.6.0.jar # install jar to local mvn cache mvn install:install-file -Dfile=org.patchca.patchca-0.6.0.jar -DgroupId=org.patchca -DartifactId=patchca -Dversion=0.6.0 -Dpackaging=jar
9 打出多种格式的包
假设应用除了提供web接口(这需要应用打包成war),还提供了一些小命令(这些小命令对war里面的class有依赖),此时除了war外,再打包出一个jar包供小命令用是个不错的选择。
通过build阶段的多个plugin,可以打出多种格式的包。
10 常用的maven插件
10.1 maven-compiler-plugin 插件
编译插件,配置编译选项
10.2 maven-war-plugin
打war包插件,配置打包选项
10.3 maven-jar-plugin
打jar包插件,不包含依赖
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>make-a-jar</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin>
10.4 maven-dependency-plugin
提取所有的依赖
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>copy</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> </configuration> </execution> </executions> </plugin>
10.5 maven-assembly-plugin
打独立运行的jar包,build-plugins段
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.6</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-a-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
10.6 jetty-maven-plugin
jetty插件,通过 mvn jetty:run-war 运行war包,查看 5 虽然通过 jetty:run 也可以运行,但有时候会引起问题,尤其是关于 slf4j 的。例如:把依赖 slf4j-api 设置为 compile ,但是使用 jetty:run 却会加载 slf4j-api 。推荐使用 jetty:run-war 此时执行的是war包中的内容, slf4j-api 肯定不在里面,并且因为更接近真实环境,更能减少上线的bug。
通过jetty插件运行程序使用的是maven的日志配置,在 $MAVEN_HOME/conf/logging/simplelogger.properties
文件中,默认基本是 info,通过增加 org.slf4j.simpleLogger.log.example=debug
把example包(及子包)下的日志级别设置为debug,用于调试example包。如果 jetty:run 出现了 SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder" ,试试 jetty:run-war 。
10.7 maven-pmd-plugin
源码分析插件,发现隐藏的bug,参考 5
10.8 findbugs-maven-plugin
代码静态分析,发现隐藏的bug,参考 5