上周给公司的同事做了一下Maven的培训,周末重新整理一下发布到网上。以前使用Ant构建项目,如果使用Ant构建项目时会有一个比较严重的问题,基于分模块的时候对于依赖的管理不太好操作,Maven就是为了解决Ant不太好解决的哪些问题的一种新的项目管理工具,目前Maven是Apache的一个顶级项目(http://maven.apache.org/)。从官方下载的Maven二进制包只有4.7M左右,其实通过官网下载到的只是Maven的一个架构。
Maven的安装非常简单,将Maven的二进制包解压到指定的目录下。那么需要将Maven的bin目录配置到操作系统环境变量中的path中,新建环境变量M2_HOME配置为Maven的根目录。
如果在命令行下输入“mvn -version”命令后能够显示maven的版本信息,说明整个maven的安装已经成功。
如果使用Maven构建项目,需要项目目录下创建一个pom.xml文件,在Ant中配置文件是build.xml,在Maven中配置文件是pom.xml。目前凡是从网上下载的第三方工具包中都是使用Maven进行管理的,我们可以从已建项目中将pom.xml文件拷贝过来作为参考。
所有的Maven都需要配置四个最基本的元素:
4.0.0 com.jianshi.demo demo-core SNAPSHOT-0.0.1
下面演示一个使用Maven搭建的一个小例子,如果要使用maven构建一个项目那么就需要按照maven的约定去创建对应的目录结构:
package com.jianshi.demo.dataobject;
public class Hello{
public String sayHello(String name){
return "hello:" + name;
}
}
这个简单的小例子中的pom.xml文件内容可以直接参考上面pom.xml中的内容,如果需要使用maven对项目进行编译那么就需要在项目中pom.xml文件所在的路径下执行命令“mvn compile”。
D:\Demo\maven\01>mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building uimc-core SNAPSHOT-0.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ demo-core ---
[debug] execute contextualize
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Demo\maven\01\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ demo-core ---
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to D:\Demo\maven\01\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.285s
[INFO] Finished at: Sun Aug 26 15:44:44 CST 2012
[INFO] Final Memory: 6M/83M
[INFO] ------------------------------------------------------------------------
D:\Demo\maven\01>
Maven只有4M,我们所需要的jar包都是作为插件存储在中心仓库中,在执行maven命令的时候需要什么插件,他会直接从网上下载。当每次maven命令执行后从中央仓库下载的插件都会存储在本地的仓库中。通常是在当前登录用户(操作系统)的工作目录下面有一个“.m2”的目录。我们将本地仓库放在C盘明显是不明智的选择(通常C盘作为系统盘),那么通常的方式是将Maven的仓库放在另外一个空闲盘的某个文件夹中。通常maven的配置都会在setting.xml文件中,在maven的安装目录下也有setting.xml文件,安装目录下面setting.xml文件是对所有的项目都起作用的,如果需要为自己机器的maven设置本地仓库的信息就需要将这个setting.xml文件拷贝到本地的仓库目录下面。
D:\maven\repository ......
通过本地仓库的配置后,就可以做到如果在本地仓库中存在插件就从本地仓库中获取,如果没有再从中央仓库中下载。(maven安装文件中也需要作此配置)通过刚才执行的“mvn compile”命令发现在pom.xml的目录中出现了target目录,里面存储着编译后的文件。如果需要对文件进行测试,那么就需要在src目录下面创建test目录。同样也需要在test目录下面创建测试类。
package com.jianshi.demo.dataobject;
import org.junit.*;
import static junit.framework.Assert.*;
public class TestHello{
@Test
public void testHello(){
Hello h = new Hello();
assertEquals("hello:zhangsan",h.sayHello("zhangsan"));
}
}
上面的代码中需要引用Junit组件来完成测试,此时需要在pom.xml文件中加入Junit的依赖关系。dependencies表示所有依赖的配置的最高级标签,dependency表示每一个依赖的配置标签。
4.0.0 com.jianshi.demo demo-core SNAPSHOT-0.0.1 junit junit 4.7 test
上面的配置就说明这个项目中存在一个依赖,即依赖Junit包,并且说明依赖于Junit的4.10这个版本,以及说明引入的这个包依赖仅作用于测试域。下面执行“mvn test”命令进行测试代码的编译以及测试代码的运行。
D:\Demo\maven\01>mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building uimc-core SNAPSHOT-0.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ demo-core ---
[debug] execute contextualize
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Demo\maven\01\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ demo-core ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ demo-core ---
[debug] execute contextualize
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Demo\maven\01\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ demo-core ---
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to D:\Demo\maven\01\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ demo-core ---
[INFO] Surefire report directory: D:\Demo\maven\01\target\surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.jianshi.demo.dataobject.TestHello
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.088 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.399s
[INFO] Finished at: Sun Aug 26 16:04:08 CST 2012
[INFO] Final Memory: 8M/108M
[INFO] ------------------------------------------------------------------------
D:\Demo\maven\01>
工程的target目录下发现多出了一些测试报告的类。测试报告还可以生成更丰富的,那么后续测试部分进行介绍。下面执行“mvn clean”命令,可以清空刚才编译或执行的结果数据,即删除target目录。
D:\Demo\maven\01>mvn clean
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building demo-core SNAPSHOT-0.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ demo-core ---
[INFO] Deleting D:\Demo\maven\01\target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.758s
[INFO] Finished at: Sun Aug 26 16:06:42 CST 2012
[INFO] Final Memory: 2M/82M
[INFO] ------------------------------------------------------------------------
D:\Demo\maven\01>
如果执行“mvn clean package”命令,可以先执行删除上次的编译结果,在执行本次的编译及打包。
D:\Demo\maven\01>mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building demo-core SNAPSHOT-0.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ demo-core ---
[INFO] Deleting D:\Demo\maven\01\target
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ demo-core ---
[debug] execute contextualize
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Demo\maven\01\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ demo-core ---
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to D:\Demo\maven\01\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ demo-core ---
[debug] execute contextualize
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Demo\maven\01\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ demo-core ---
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to D:\Demo\maven\01\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ demo-core ---
[INFO] Surefire report directory: D:\Demo\maven\01\target\surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.jianshi.demo.dataobject.TestHello
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.101 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] --- maven-jar-plugin:2.3.2:jar (default-jar) @ demo-core ---
[INFO] Building jar: D:\Demo\maven\01\target\demo-core-SNAPSHOT-0.0.1.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.454s
[INFO] Finished at: Sun Aug 26 16:11:08 CST 2012
[INFO] Final Memory: 11M/106M
[INFO] ------------------------------------------------------------------------
D:\Demo\maven\01>
执行Maven命令“mvn clean package”后会在target目录之后创建对应的jar包,即:D:\Demo\maven\01 \target\demo-core-SNAPSHOT- 0.0 . 1 .jar
可以通过执行maven命令“mvn clean install”会完成上面的操作之后同时还会将其发布到本地仓库。
通常在一个项目开发过程中都是需要分模块进行建设的,在maven中不同的模块是物理分离的,上面创建的是demo项目的一个核心模块,那么下面再去创建一个manager模块,manager模块需要引用core的内容。此时在manager这个项目中并没有将core中的类引入到ClassPath中,那么就需要在项目manager的pom.xml中增加配置。因为上面的命令执行过“mvn clean install”命令,此时就会将编译后的文件上传到本地库中。
package com.jianshi.demo.manager;
import com.jianshi.demo.dataobject.*;
public class DemoManager{
public static void main(String [] args){
Hello h = new Hello();
System.out.println(h.sayHello("zhangsan"));
}
}
4.0.0 com.jianshi.demo demo-manager SNAPSHOT-0.0.1 junit junit 4.7 test com.jianshi.demo demo-core SNAPSHOT-0.0.1 compile
此时执行“mvn clean package”命令,此时编译打包成功,manager这个项目是依赖于第一个项目的。这个我们发现maven可以有效的在不同的模块之前有效的管理我们的项目。
D:\Demo\maven\02>mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building demo-manager SNAPSHOT-0.0.1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ demo-manager ---
[INFO] Deleting D:\Demo\maven\02\target
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ demo-manager ---
[debug] execute contextualize
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Demo\maven\02\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ demo-manager ---
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to D:\Demo\maven\02\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ demo-manager ---
[debug] execute contextualize
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\Demo\maven\02\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ demo-manager ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.10:test (default-test) @ demo-manager ---
[INFO] No tests to run.
[INFO] Surefire report directory: D:\Demo\maven\02\target\surefire-reports
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Results :
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] --- maven-jar-plugin:2.3.2:jar (default-jar) @ demo-manager ---
[INFO] Building jar: D:\Demo\maven\02\target\demo-manager-SNAPSHOT-0.0.1.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.549s
[INFO] Finished at: Sun Aug 26 16:31:08 CST 2012
[INFO] Final Memory: 8M/106M
[INFO] ------------------------------------------------------------------------
D:\Demo\maven\02>
通过上面的小例子对maven有了初步的了解,下面进行总结:
“mvn clean”表示运行清理操作(默认会将target文件夹中的数据清理)
“mvn clean compile”表示先运行清理之后在进行编译,将编译后的代码放到target文件夹中
“mvn clean test”运行清理和测试
“mvn clean package”运行清理和打包
“mvn clean install”运行清理和安装,将打包好的jar安装到本地仓库,以便于其他项目的调用
“mvn clean depoly”运行情况和发布(发布到私服上)
如果向上面一样老是手工的创建项目非常麻烦,可以使用“mvn archetype:generate”命令进行操作来完成项目基本骨架的构建。
mvn package -Dmaven.test.skip=true 打包但不测试
上面介绍的都是手工操作,在项目中通常可以使用工具进行管理,例如eclipse的m2eclipse插件。