CI流程
1. 已部署环境地址Jenkins:http://192.168.0.23:8099/jenkins/
Nexus: http://192.168.0.23:8081/nexus/

站点Site: http://192.168.0.23:18080/slide/
Svn: svn://192.168.0.163/rss
2. Maven2.1. 基本介绍Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具.
如果你已经有十次输入同样的Ant targets来编译你的代码、jar或者war、生成javadocs,你一定会自问,是否有一个重复性更少却能同样完成该工作的方法。Maven便提供了这样一种选择,将你的注意力从作业层转移到项目管理层。Maven项目已经能够知道如何构建和捆绑代码,运行测试,生成文档并宿主项目网页.
项目的主页地址为:http://maven.apache.org/
2.2. 安装2.2.1. 下载地址官网 http://maven.apache.org/download.html
本地SHH 192.168.0.23/home/geosoft/soft
用户名root 密码admins
2.2.2. 安装步骤解压apache-maven-3.0.3.zip到本地目录,下载maven的eclipse插件 并安装
Eclipse添加插件
Eclipse插件地址: http://m2eclipse.sonatype.org/sites/m2e/0.10.0.20100209-0800/
装完插件重启eclipse就可以新建maven项目了
在环境变量里配置maven的安装目录
Windows用户如下
Linux用户需要使用export命令设置环境变量
2.2.3. 初步使用
我们创建一个maven项目
点击next,到下一个界面 这时候需要输入group id,artifact Id,Version,package
groupId :定义当前Maven项目隶属的实际项目。首先,Maven项目和实际项目不一定是一对一的关系。比如SpringFrameWork这一实际项目,其对应的Maven项目会有很多,如spring-core,spring-context等。这是由于Maven中模块的概念,因此,一个实际项目往往会被划分成很多模块。其次,groupId不应该对应项目隶属的组织或公司。原因很简单,一个组织下会有很多实际项目,如果groupId只定义到组织级别,而后面我们会看到,artifactId只能定义Maven项目(模块),那么实际项目这个层次将难以定义。最后,groupId的表示方式与Java包名的表达方式类似,通常与域名反向一一对应。
artifactId : 该元素定义当前实际项目中的一个Maven项目(模块),推荐的做法是使用实际项目名称作为artifactId的前缀。比如上例中的my-app。
version : 该元素定义Maven项目当前的版本
输入之后,点击next就完成项目的创建了
2.2.4. maven中项目的目录结构2.2.4.1. 标准目录结构
一般项目,如jar
编译后代码都集中在prjecto/target目录下
Web项目,如war
编译后代码都集中在prjecto/target目录下
-mainbin 脚本库java java源代码文件resources 资源库,会自动复制到classes目录里filters 资源过滤文件assembly 组件的描述配置(如何打包)config 配置文件webapp web应用的目录。WEB-INF、css、js等-testjava 单元测试java源代码文件resources 测试需要用的资源库filters 测试资源过滤库-site Site(一些文档)targetLICENSE.txt Project's licenseREADME.txt Project's readme工程根目录下就只有src和target两个目录target是有存放项目构建后的文件和目录,jar包、war包、编译的class文件等。
target里的所有内容都是maven构建的时候生成的.
2.2.4.2. Maven项目的标准目录介绍Maven提倡使用一个共同的标准目录结构,使开发人员能在熟悉了一个Maven工程后,对其他的Maven工程也能清晰了解。这样做也省去了很多设置的麻烦。
以下的文档介绍是Maven希望的目录结构,并且也是目录创建工程是采用的目录结构。Maven推荐大家尽可能的遵守这样的目录结构。
src/main/java
Application/Library sources
src/main/resources
Application/Library resources
src/main/filters
Resource filter files
src/main/assembly
Assembly descriptors
src/main/config
Configuration files
src/main/webapps
Web application sources
src/test/java
Test sources
src/test/resources
Test resources
src/test/filters
Test resource filter files
src/site
Site
LICENSE.txt
Project's license
README.txt
Project's readme
在顶级目录上是工程的描述文件pom.xml(如果使用Ant则还包括其他属性文件,maven.xml或build.xml),另外还包括提供给最终用户的文件,如,README.txt, LICENSE.txt等等。
顶级目录还包括两个子目录:src,target。顶级目录下可能出现的其他目录仅仅是CVS或.svn和其他多模块工程的工程目录,最好不要再有其他目录。
Target目录是所有工程编译构建的输出目录。
Src目录包含所有工程的源码文件,配置文件,资源文件等等。它下面的子目录一般包含main(主要的工程源文件),test(测试文件),site(项目站点文件)。
2.2.5. maven的坐标与依赖2.2.5.1. 坐标1.为什么要定义Maven坐标 在我们开发Maven项目的时候,需要为其定义适当的坐标,这是Maven强制要求的。在这个基础上,其他Maven项目才能应用该项目生成的构件。 2.Maven坐标详解
Maven坐标为各种构件引入了秩序,任何一个构件都必须明确定义自己的坐标,而一组Maven坐标是通过一些元素定义的,它们是groupId,artifactId,version,packaging,class-sifer。下面是一组坐标定义:
Xml代码
<groupId>com.maven.study</groupId>
<artifactId>study-dao</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
下面讲解一下各个坐标元素:
groupId :定义当前Maven项目隶属的实际项目。首先,Maven项目和实际项目不一定是一对一的关系。比如SpringFrameWork这一实际项目,其对应的Maven项目会有很多,如spring-core,spring-context等。这是由于Maven中模块的概念,因此,一个实际项目往往会被划分成很多模块。其次,groupId不应该对应项目隶属的组织或公司。原因很简单,一个组织下会有很多实际项目,如果groupId只定义到组织级别,而后面我们会看到,artifactId只能定义Maven项目(模块),那么实际项目这个层次将难以定义。最后,groupId的表示方式与Java包名的表达方式类似,通常与域名反向一一对应。
artifactId : 该元素定义当前实际项目中的一个Maven项目(模块),推荐的做法是使用实际项目名称作为artifactId的前缀。比如上例中的my-app。
version : 该元素定义Maven项目当前的版本
packaging :定义Maven项目打包的方式,首先,打包方式通常与所生成构件的文件扩展名对应,如上例中的packaging为jar,最终的文件名为my-app-0.0.1-SNAPSHOT.jar。也可以打包成war, ear等。当不定义packaging的时候,Maven 会使用默认值jar
classifier: 该元素用来帮助定义构建输出的一些附件。附属构件与主构件对应,如上例中的主构件为my-app-0.0.1-SNAPSHOT.jar,该项目可能还会通过一些插件生成如my-app-0.0.1-SNAPSHOT-javadoc.jar,my-app-0.0.1-SNAPSHOT-sources.jar, 这样附属构件也就拥有了自己唯一的坐标
我们项目中用到的jar包可以通过依赖的方式引入,构建项目的时候从Maven仓库下载即可。
2.2.5.2. 依赖· 依赖配置
<project>
...
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>group-c</groupId>
<artifactId>excluded-artifact</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
依赖配置如下:
Xml代码
1. <dependencies>
2. <dependency>
3. <groupId>junit</groupId>
4. <artifactId>junit</artifactId>
5. <version>3.8.1</version>
6. <scope>test</scope>
7. </dependency>
8. </dependencies>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
依赖会包含基本的groupId, artifactId,version等元素,根元素project下的dependencies可以包含一个或者多个dependency元素,以声明一个或者多个依赖。下面详细讲解每个依赖可以包含的元素:
groupId,artifactId和version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven根据坐标才能找到需要的依赖
type: 依赖的类型,对应于项目坐标定义的packaging。大部分情况下,该元素不必声明,其默认值是jar
scope: 依赖的范围,下面会进行详解
optional: 标记依赖是否可选
exclusions: 用来排除传递性依赖,下面会进行详解
大部分依赖声明只包含基本坐标。
· 依赖范围
Maven在编译主代码的时候需要使用一套classpath,在编译和执行测试的时候会使用另一套classpath,实际运行项目的时候,又会使用一套classpath。
依赖范围就是用来控制依赖与这三种classpath(编译classpath、测试classpath、运行classpath)的关系,Maven有以下几种依赖范围:
compile: 编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译、测试、运行三种classpath都有效。
test: 测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子就是JUnit,它只有在编译测试代码及运行测试的时候才需要。
provided: 已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven重复地引入一遍。
runtime: 运行时依赖范围。使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。典型的例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。
system: 系统依赖范围。该依赖与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围依赖时必须通过systemPath元素显式地指定依赖文件的路径。由于此类依赖不是通过Maven仓库解析的,而且往往与本机系统绑定,可能造成构建的不可移植,因此应该谨慎使用。systemPath元素可以引用环境变量,如:
Xml代码 INCLUDEPICTURE "http://tangyanbo.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <dependency>
2. <groupId>javax.sql</groupId>
3. <artifactId>jdbc-stdext</artifactId>
4. <version>2.0</version>
5. <scope></scope>
6. <systemPath>${java.home}/lib/rt.jar</systemPath>
7. </dependency>
<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<version>2.0</version>
<scope></scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
import(Maven 2.0.9及以上): 导入依赖范围。
在一个maven项目中,如果存在编译需要而发布不需要的jar包,可以用scope标签,值设为provided。如下:
<dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> <classifier /> </dependency>
scope参数值的说明:
--compile:默认值。表明是所有任务所需的资源
--test:运行所有的测试用例时所需资源
--runtime:表明是运行时所需资源
--provided:JDK部分或应用服务器的classpath所需的资源
· 传递性依赖
下面我们看一个简单的项目,读者可从附件中下载源码
POM.xml配置如下:
Xml代码 INCLUDEPICTURE "http://tangyanbo.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3. <modelVersion>4.0.0</modelVersion>
4.
5. <groupId>com.mycompany.app</groupId>
6. <artifactId>my-app-simple</artifactId>
7. <version>0.0.1-SNAPSHOT</version>
8. <packaging>jar</packaging>
9.
10. <name>my-app-simple</name>
11. <url>http://maven.apache.org</url>
12.
13. <properties>
14. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15. </properties>
16.
17. <dependencies>
18. <dependency>
19. <groupId>junit</groupId>
20. <artifactId>junit</artifactId>
21. <version>3.8.1</version>
22. <scope>test</scope>
23. </dependency>
24.
25. <dependency>
26. <groupId>org.springframework</groupId>
27. <artifactId>spring-core</artifactId>
28. <version>2.5.6</version>
29. </dependency>
30. </dependencies>
31. </project>
<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>com.mycompany.app</groupId>
<artifactId>my-app-simple</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>my-app-simple</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>2.5.6</version>
</dependency>
</dependencies>
</project>
我们可以看到此项目引入依赖junit和spring-core,我们可以在Maven仓库中查找spring-core构件,如图:
点击POM我们会看到该文件包含了一个commons-logging依赖:
Xml代码 INCLUDEPICTURE "http://tangyanbo.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <dependency>
2. <groupId>commons-logging</groupId>
3. <artifactId>commons-logging</artifactId>
4. <version>1.1.1</version>
5. </dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
那么该依赖会传递到当前项目中,这就是依赖的传递性,打开项目查看Maven dependencies:
· 可选依赖
有时候我们不想让依赖传递,那么可配置该依赖为可选依赖,将元素optional设置为true即可,例如:
Xml代码 INCLUDEPICTURE "http://tangyanbo.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <dependency>
2. <groupId>commons-logging</groupId>
3. <artifactId>commons-logging</artifactId>
4. <version>1.1.1</version>
5. <optional>true<optional>
6. </dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<optional>true<optional>
</dependency>
那么依赖该项目的另以项目将不会得到此依赖的传递
· 排除依赖
当我们引入第三方jar包的时候,难免会引入传递性依赖,有些时候这是好事,然而有些时候我们不需要其中的一些传递性依赖
比如上例中的项目,我们不想引入传递性依赖commons-logging,我们可以使用exclusions元素声明排除依赖,exclusions可以包含一个或者多个exclusion子元素,因此可以排除一个或者多个传递性依赖。需要注意的是,声明exclusions的时候只需要groupId和artifactId,而不需要version元素,这是因为只需要groupId和artifactId就能唯一定位依赖图中的某个依赖。换句话说,Maven解析后的依赖中,不可能出现groupId和artifactId相同,但是version不同的两个依赖。
如下是一个排除依赖的例子:
Xml代码 INCLUDEPICTURE "http://tangyanbo.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <dependency>
2. <groupId>org.springframework</groupId>
3. <artifactId>spring-core</artifactId>
4. <version>2.5.6</version>
5. <exclusions>
6. <exclusion>
7. <groupId>commons-logging</groupId>
8. <artifactId>commons-logging</artifactId>
9. </exclusion>
10. </exclusions>
11. </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>2.5.6</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
· 依赖归类
如果我们项目中用到很多关于Spring Framework的依赖,它们分别是org.springframework:spring-core:2.5.6, org.springframework:spring-beans:2.5.6,org.springframework:spring-context:2.5.6,它们都是来自同一项目的不同模块。因此,所有这些依赖的版本都是相同的,而且可以预见,如果将来需要升级Spring Framework,这些依赖的版本会一起升级。因此,我们应该在一个唯一的地方定义版本,并且在dependency声明引用这一版本,这一在Spring Framework升级的时候只需要修改一处即可。
Xml代码 INCLUDEPICTURE "http://tangyanbo.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3. <modelVersion>4.0.0</modelVersion>
4.
5. <groupId>com.mycompany.app</groupId>
6. <artifactId>my-app-simple</artifactId>
7. <version>0.0.1-SNAPSHOT</version>
8. <packaging>jar</packaging>
9. <name>my-app-simple</name>
10. <properties>
11. <springframework.version>2.5.6</springframework.version>
12. </properties>
13.
14. <dependencies>
15. <dependency>
16. <groupId>junit</groupId>
17. <artifactId>junit</artifactId>
18. <version>3.8.1</version>
19. <scope>test</scope>
20. </dependency>
21.
22. <dependency>
23. <groupId>org.springframework</groupId>
24. <artifactId>spring-core</artifactId>
25. <version>${springframework.version}</version>
26. </dependency>
27. <dependency>
28. <groupId>org.springframework</groupId>
29. <artifactId>spring-beans</artifactId>
30. <version>${springframework.version}</version>
31. </dependency>
32. </dependencies>
33. </project>
<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>com.mycompany.app</groupId>
<artifactId>my-app-simple</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>my-app-simple</name>
<properties>
<springframework.version>2.5.6</springframework.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
</project>
6. 在Eclipse中管理依赖
用eclipse来管理依赖。
如图,在该项目的pom.xml中点击Dependency Hierarchy可以看到依赖树:
点击Dependencies可以添加新的依赖,点击选择一个依赖,点击remove可以删除,点击Add可以新增一个依赖,如图:
如下图,搜素org.springframework(此处是从Maven中心仓库进行搜索),选择你想要的模块和版本,点击OK即可:
2.3. maven仓库2.3.1. 什么是Maven仓库
在不用Maven的时候,比如说以前我们用Ant构建项目,在项目目录下,往往会看到一个名为/lib的子目录,那里存放着各类第三方依赖jar文件,如log4j.jar,junit.jar等等。每建立一个项目,你都需要建立这样的一个/lib目录,然后复制一对jar文件,这是很明显的重复。重复永远是噩梦的起点,多个项目不共用相同的jar文件,不仅会造成磁盘资源的浪费,也使得版本的一致性管理变得困难。此外,如果你使用版本管理工具,如SVN(你没有使用版本管理工具?马上试试SVN吧,它能帮你解决很多头疼的问题),你需要将大量的jar文件提交到代码库里,可是版本管理工具在处理二进制文件方面并不出色。
Maven仓库就是放置所有JAR文件(WAR,ZIP,POM等等)的地方,所有Maven项目可以从同一个Maven仓库中获取自己所需要的依赖JAR,这节省了磁盘资源。此外,由于Maven仓库中所有的JAR都有其自己的坐标,该坐标告诉Maven它的组ID,构件ID,版本,打包方式等等,因此Maven项目可以方便的进行依赖版本管理。你也不在需要提交JAR文件到SCM仓库中,你可以建立一个组织层次的Maven仓库,供所有成员使用。
简言之,Maven仓库能帮助我们管理构件(主要是JAR)。
2.3.2. 本地仓库 vs. 远程仓库运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。
比如说,你的项目配置了junit-3.8的依赖,在你运行mvn test 的时候,Maven需要使用junit-3.8的jar文件,它首先根据坐标查找本地仓库,如果找到,就直接使用。如果没有,Maven会检查可用的远程仓库配置,然后逐个尝试这些远程仓库去下载junit-3.8的jar文件,如果远程仓库存在该文件,Maven会将其下载到本地仓库中,继而使用。如果尝试过所有远程仓库之后,Maven还是没能够下载到该文件,它就会报错。
Maven缺省的本地仓库地址为${user.home}/.m2/repository 。也就是说,一个用户会对应的拥有一个本地仓库。
你也可以自定义本地仓库的位置,修改${user.home}/.m2/settings.xml :
Xml代码 INCLUDEPICTURE "http://juvenshun.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <settings>
2. ...
3. <localRepository>D:\java\repository</localRepository>
4. ...
5. </settings>
<settings>
...
<localRepository>D:\java\repository</localRepository>
...
</settings>
你还可以在运行时指定本地仓库位置:
mvn clean install -Dmaven.repo.local=/home/juven/myrepo/
还有一点需要理解的是,当我们运行install的时候,Maven实际上是将项目生成的构件安装到了本地仓库,也就是说,只有install了之后,其它项目才能使用此项目生成的构件。
了解了本地仓库,接着了解一下Maven缺省的远程仓库,即Maven中央仓库。
安装好Maven之后,我们可以建立一个简单的项目,配置一些简单的依赖,然后运行mvn clean install,项目就构建好了。我们没有手工的去下载任何jar文件,这一切都是因为Maven中央仓库的存在,当Maven在本地仓库找不到需要的jar文件时,它会查找远程仓库,而一个原始的Maven安装就自带了一个远程仓库——Maven中央仓库。
这个Maven中央仓库是在哪里定义的呢?在我的机器上,我安装了maven-2.0.10,我可以找到这个文件:${M2_HOME}/lib/maven-2.0.10-uber.jar ,打开该文件,能找到超级POM:\org\apache\maven\project\pom-4.0.0.xml ,它是所有Maven POM的父POM,所有Maven项目继承该配置,你可以在这个POM中发现如下配置:
Xml代码 INCLUDEPICTURE "http://juvenshun.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <repositories>
2. <repository>
3. <id>central</id>
4. <name>Maven Repository Switchboard</name>
5. <layout>default</layout>
6. <url>http://repo1.maven.org/maven2</url>
7. <snapshots>
8. <enabled>false</enabled>
9. </snapshots>
10. </repository>
11. </repositories>
<repositories>
<repository>
<id>central</id>
<name>Maven Repository Switchboard</name>
<layout>default</layout>
<url>http://repo1.maven.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
关于远程仓库的配置,下面的小节我会详细解释,这里我们只要知道,中央仓库的id为central,远程url地址为http://repo1.maven.org/maven2,它关闭了snapshot版本构件下载的支持。
2.3.3. 在POM中配置远程仓库前面我们看到超级POM配置了ID为central的远程仓库,我们可以在POM中配置其它的远程仓库。这样做的原因有很多,比如你有一个局域网的远程仓库,使用该仓库能大大提高下载速度,继而提高构建速度,也有可能你依赖的一个jar在central中找不到,它只存在于某个特定的公共仓库,这样你也不得不添加那个远程仓库的配置。
这里我配置一个远程仓库指向中央仓库的中国镜像:
Xml代码
1. <project>
2. ...
3. <repositories>
4. <repository>
5. <id>maven-net-cn</id>
6. <name>Maven China Mirror</name>
7. <url>http://maven.net.cn/content/groups/public/</url>
8. <releases>
9. <enabled>true</enabled>
10. </releases>
11. <snapshots>
12. <enabled>false</enabled>
13. </snapshots>
14. </repository>
15. </repositories>
16. <pluginRepositories>
17. <pluginRepository>
18. <id>maven-net-cn</id>
19. <name>Maven China Mirror</name>
20. <url>http://maven.net.cn/content/groups/public/</url>
21. <releases>
22. <enabled>true</enabled>
23. </releases>
24. <snapshots>
25. <enabled>false</enabled>
26. </snapshots>
27. </pluginRepository>
28. </pluginRepositories>
29. ...
30. </project>
<project>
...
<repositories>
<repository>
<id>maven-net-cn</id>
<name>Maven China Mirror</name>
<url>http://maven.net.cn/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>maven-net-cn</id>
<name>Maven China Mirror</name>
<url>http://maven.net.cn/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
...
</project>
我们先看一下<repositories>的配置,你可以在它下面添加多个<repository> ,每个<repository>都有它唯一的ID,一个描述性的name,以及最重要的,远程仓库的url。此外,<releases><enabled>true</enabled></releases>告诉Maven可以从这个仓库下载releases版本的构件,而<snapshots><enabled>false</enabled></snapshots>告诉Maven不要从这个仓库下载snapshot版本的构件。禁止从公共仓库下载snapshot构件是推荐的做法,因为这些构件不稳定,且不受你控制,你应该避免使用。当然,如果你想使用局域网内组织内部的仓库,你可以激活snapshot的支持。
关于<repositories>的更详细的配置及相关解释,请参考:http://www.sonatype.com/books/maven-book/reference_zh/apas02s08.html。
至于<pluginRepositories>,这是配置Maven从什么地方下载插件构件(Maven的所有实际行为都由其插件完成)。该元素的内部配置和<repository>完全一样,不再解释。
2.3.4. 在settings.xml中配置远程仓库我们知道了如何在POM中配置远程仓库,但考虑这样的情况:在一个公司内部,同时进行这3个项目,而且以后随着这几个项目的结束,越来越多的项目会开始;同时,公司内部建立一个Maven仓库。我们统一为所有这些项目配置该仓库,于是不得不为每个项目提供同样的配置。问题出现了,这是重复 !
其实我们可以做到只配置一次,在哪里配置呢?就是settings.xml。
不过事情没有那么简单,不是简单的将POM中的<repositories>及<pluginRepositories>元素复制到settings.xml中就可以,setting.xml不直接支持 这两个元素。但我们还是有一个并不复杂的解决方案,就是利用profile,如下:
Xml代码 INCLUDEPICTURE "http://juvenshun.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <settings>
2. ...
3. <profiles>
4. <profile>
5. <id>dev</id>
6. <!-- repositories and pluginRepositories here-->
7. </profile>
8. </profiles>
9. <activeProfiles>
10. <activeProfile>dev</activeProfile>
11. </activeProfiles>
12. ...
13. </settings>
<settings>
...
<profiles>
<profile>
<id>dev</id>
<!-- repositories and pluginRepositories here-->
</profile>
</profiles>
<activeProfiles>
<activeProfile>dev</activeProfile>
</activeProfiles>
...
</settings>
这里我们定义一个id为dev的profile,将所有repositories以及pluginRepositories元素放到这个profile中,然后,使用<activeProfiles>元素自动激活该profile。这样,你就不用再为每个POM重复配置仓库。
使用profile为settings.xml添加仓库提供了一种用户全局范围的仓库配置。
2.3.5. 镜像如果你的地理位置附近有一个速度更快的central镜像,或者你想覆盖central仓库配置,或者你想为所有POM使用唯一的一个远程仓库(这个远程仓库代理的所有必要的其它仓库),你可以使用settings.xml中的mirror配置。
以下的mirror配置用maven.net.cn覆盖了Maven自带的central:
Xml代码 INCLUDEPICTURE "http://juvenshun.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <settings>
2. ...
3. <mirrors>
4. <mirror>
5. <id>maven-net-cn</id>
6. <name>Maven China Mirror</name>
7. <url>http://maven.net.cn/content/groups/public/</url>
8. <mirrorOf>central</mirrorOf>
9. </mirror>
10. </mirrors>
11. ...
12. </settings>
<settings>
...
<mirrors>
<mirror>
<id>maven-net-cn</id>
<name>Maven China Mirror</name>
<url>http://maven.net.cn/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
...
</settings>
这里唯一需要解释的是<mirrorOf>,这里我们配置central的镜像,我们也可以配置一个所有仓库的镜像,以保证该镜像是Maven唯一使用的仓库:
Xml代码 INCLUDEPICTURE "http://juvenshun.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <settings>
2. ...
3. <mirrors>
4. <mirror>
5. <id>my-org-repo</id>
6. <name>Repository in My Orgnization</name>
7. <url>http://192.168.1.100/maven2</url>
8. <mirrorOf></mirrorOf>
9. </mirror>
10. </mirrors>
11. ...
12. </settings>
<settings>
...
<mirrors>
<mirror>
<id>my-org-repo</id>
<name>Repository in My Orgnization</name>
<url>http://192.168.1.100/maven2</url>
<mirrorOf></mirrorOf>
</mirror>
</mirrors>
...
</settings>
关于更加高级的镜像配置,可以参考:http://maven.apache.org/guides/mini/guide-mirror-settings.html。
2.3.6. 分发构件至远程仓库mvn install 会将项目生成的构件安装到本地Maven仓库,mvn deploy 用来将项目生成的构件分发到远程Maven仓库。本地Maven仓库的构件只能供当前用户使用,在分发到远程Maven仓库之后,所有能访问该仓库的用户都能使用你的构件。
我们需要配置POM的distributionManagement来指定Maven分发构件的位置,如下:
Xml代码 INCLUDEPICTURE "http://juvenshun.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <project>
2. ...
3. <distributionManagement>
4. <repository>
5. <id>nexus-releases</id>
6. <name>Nexus Release Repository</name>
7. <url>http://127.0.0.1:8080/nexus/content/repositories/releases/</url>
8. </repository>
9. <snapshotRepository>
10. <id>nexus-snapshots</id>
11. <name>Nexus Snapshot Repository</name>
12. <url>http://127.0.0.1:8080/nexus/content/repositories/snapshots/</url>
13. </snapshotRepository>
14. </distributionManagement>
15. ...
16. </project>
<project>
...
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Nexus Release Repository</name>
<url>http://127.0.0.1:8080/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://127.0.0.1:8080/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
...
</project>
Maven区别对待release版本的构件和snapshot版本的构件,snapshot为开发过程中的版本,实时,但不稳定,release版本则比较稳定。Maven会根据你项目的版本来判断将构件分发到哪个仓库。
一般来说,分发构件到远程仓库需要认证,如果你没有配置任何认证信息,你往往会得到401错误。这个时候,如下在settings.xml中配置认证信息:
Xml代码 INCLUDEPICTURE "http://juvenshun.iteye.com/images/spinner.gif" \ MERGEFORMATINET
1. <settings>
2. ...
3. <servers>
4. <server>
5. <id>nexus-releases</id>
6. <username>admin</username>
7. <password>admin123</password>
8. </server>
9. <server>
10. <id>nexus-snapshots</id>
11. <username>admin</username>
12. <password>admin123</password>
13. </server>
14. </servers>
15. ...
16. </settings>
<settings>
...
<servers>
<server>
<id>nexus-releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>admin</username>
<password>admin123</password>
</server>
</servers>
...
</settings>
需要注意的是,settings.xml中server元素下id的值必须与POM中repository或snapshotRepository下id的值完全一致。将认证信息放到settings下而非POM中,是因为POM往往是它人可见的,而settings.xml是本地的。
2.3.7. 小结本文介绍了Maven仓库,它是什么?本地仓库,远程仓库,中央仓库具体是指什么?并介绍了如何在POM中配置项目层次的仓库,在settings中配置用户层次的仓库,以及mirror。本文还介绍了如何安装构件到本地仓库,如何分发构件至仓库。
2.4. maven的生命周期maven生命周期先介绍maven仓库MavenRepository:maven仓库,用于存放某公司或组织内所有使用的包。可以理解成一个存放包的地方,有本地和远程之分,本地仓库一般存在于C:/Documents and Settings/username/.m2/repository,windows为例。maven对项目的构建基于生命周期的概念。maven生命周期是指项目构建和发布的一个过程,并将这些过程作清晰的定义。maven有三个内置的生命周期:1.default:处理项目构建2.clean:处理项目的清理3.site:创建项目的网页文档
生命周期的构成例如下面是default生命周期的各个主要阶段:validate:验证项目是否正确,所有必需的信息是否可用。
Default 生命周期列表:compile:编译项目中的代码。test:用相关的单元测试框架测试编译后的代码,这些运行的测试并不会随项目打包和布署。package:将编译后的代码打包成相应的格式文件,如jar包。integration-test: 如果需要在一个综合环境中运行我们的测试,这个阶段将会运行和布署项目到该环境中。verify: 检查项目的包是否正确和符合要求。install:将包安装到本地maven仓库,可以让其他项目作为依赖使用该包。deploy:将包发布到远程的maven仓库,并提供给其他开发者使用。
Site 生命周期列表:
pre-site,
site,
post-site,
site-deploy
clean 生命周期列表:
pre-clean,
clean,
post-cleandefault
生命周期的各个阶段将会按顺序执行来完成这个生命周期。如果以上的default生命周期,将意味着项目将会先进行验证,再进行编译代码,运行相应的单元测试,打包,在集成环境中运行相关测试,验证包,安装验证后的包到本地仓库,最后布署该包到指定的仓库。比较麻烦的一个过程,但是我们所需要执行的命令只有:mvn deploy执行了deploy,deploy前的所有阶段均会被执行。例如只执行compile,那么compile后的阶段将不会被执行。
2.5. maven插件的使用2.5.1. 插件和生命周期的绑定使用命令 mvn clean install 构建一个最简单的Maven项目,会看到类似如下的输出:
E:\simple-server\simple-server>mvn clean install[INFO] Scanning for projects...[INFO] ------------------------------------------------------------------------[INFO] Building simple-server Maven Webapp[INFO] task-segment: [clean, install][INFO] ------------------------------------------------------------------------[INFO] [clean:clean] [INFO] Deleting directory E:\simple-server\simple-server\target[INFO] [resources:resources][INFO] Using default encoding to copy filtered resources.[INFO] [compiler:compile] [INFO] Compiling 3 source files to E:\simple-server\simple-server\target\classes[INFO] [resources:testResources] [INFO] Using default encoding to copy filtered resources.[INFO] [compiler:testCompile] [INFO] No sources to compile[INFO] [surefire:test] [INFO] No tests to run.[INFO] [war:war] [INFO] Packaging webapp[INFO] Assembling webapp[simple-server] in [E:\simple-server\simple-server\target\simple-server][INFO] Processing war project[INFO] Webapp assembled in[515 msecs][INFO] Building war: E:\simple-server\simple-server\target\simple-server.war[INFO] [install:install] [INFO] Installing E:\simple-server\simple-server\target\simple-server.war to C:\Documents and Settings\Administrator\.m2\repository\com\tnsoft\simple-server\1.0-SNAPSHOT\simple-server-1.0-SNAPSHOT.war[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESSFUL[INFO] ------------------------------------------------------------------------
该输出中加粗的地方,显示了在各个生命周期阶段中,很多插件执行的目标,它们分别是:
· clean阶段,clean插件执行clean目标。
· compile阶段,compiler插件执行compile目标。
· process-test-resources阶段,resources插件执行testResources目标。
· test-compile阶段,compiler插件执行testCompile目标。
· test阶段,surefire插件执行test目标。
· package阶段,war插件执行war目标。
· install阶段,install插件执行install目标。
1.1. 配置插件
插件可以被配置以完成一些自定义的行为,有一个对compiler的很常用的配置是:compiler插件默认是以Java 1.4的标准来编译源代码的,如果你用到了JAVA5的新特性,如泛型,那么Maven会报错,说不支持,此时,你需要配置compiler插件来支持Java 5。配置如下:
<project> [...] <build> [...] <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> [...] </build> [...]</project>
这里配置了compiler插件的参数source和target。如果你运行了 mvn help:describe -Dfull -Dplugin=compiler 你会看到如下的解释:
...[21] Name: sourceType: java.lang.StringRequired: falseDirectly editable: trueDescription:The -source argument for the Java compiler.-----------------------------------------------...[23] Name: targetType: java.lang.StringRequired: falseDirectly editable: trueDescription:The -target argument for the Java compiler.-----------------------------------------------....
help插件还描述了该插件有什么样的目标(goal)。
因此如何配置使用插件,你有两种参考,第一是直接看在线的文档,第二就是使用help插件来看你要配置插件的详细描述。
2.6. 聚合与继承2.6.1. 聚合我们拿study项目做例子
为了能够使用一条命令就能构建study-dao 和study-service两个模块,我们需要建立一个额外的名为study-parent模块,然后通过该模块构建整个项目的所有模块。Study-parent 本身也是个Maven项目,它的POM部分如下
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.maven.study</groupId>
<artifactId>study-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>../study-dao</module>
<module>../study-service</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.maven.study</groupId>
<artifactId>study-dao</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.maven.study</groupId>
<artifactId>study-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependencyManagement>
</project>
注意:packaging的类型为pom,module的值是一个以当前POM为主目录的相对路径。
2.6.2. 继承可声明父POM供子POM继承
父模块POM如下:
<groupId>com.maven.study</groupId>
<artifactId>study-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>../study-dao</module>
<module>../study-service</module>
</modules>
子模块声明继承如下:
<parent>
<groupId>com.maven.study</groupId>
<artifactId>study-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../study-parent/pom.xml</relativePath>
</parent>
<groupId>com.maven.study</groupId>
<artifactId>study-dao</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
注意:1、子模块没有声明groupId和version,这两个属性继承至父模块。但如果子模块有不同与父模块的groupId,version也可指定;
2、不应该继承artifactId,如果groupId,version,artifactId完全继承的话会造成坐标冲突;另外即使使用不同的groupId或version,同样的artifactId也容易产生混淆。
3、使用继承后parent也必须像子自模块一样加入到聚合模块中。也就是在在聚合模块的pom中加入<module>study-parent</module>
2.7. 使用Nexus创建私服2.7.1. 安装 Nexus我们从
Nexus提供了两种安装方式,一种是内嵌Jetty的bundle,只要你有JRE就能直接运行。第二种方式是WAR,你只须简单的将其发布到web容器中即可使用。
1)Bundle 方式安装
解压nexus-webapp-1.3. 4 -bundle.zip 至任意目录,如D:/ tools ,转到目录D:/ tools/nexus-webapp-1.3. 4 /bin/jsw/windows-x86-32 ,运行Nexus.bat ,如果你是在linux下安装,那么就下载nexus-webapp-1.3. 4 -bundle. tar .gz, 解压后转到${NEXUS_HOME}/ nexus-webapp-1.3.3/bin/jsw/linux-x86-32,它还支持solaris,macos等操作系统。当你看到"Started SelectChannelConnector@0.0.0.0:8081"之后,说明Nexus启动成功了,然后打开浏览器,访问http://127.0.0.1:8081/nexus,点击login通过admin的帐号(admin)和密码(admin123)登录你会看到如下的页面:
如果有新版本发布,会有提示在默认页面上。
这里,可以管理仓库,配置Nexus系统,管理任务,管理用户,角色,权限,查看系统的RSS源,管理及查看系统日志,等等。
2.7.2. War 方式安装
你可以同过war的方式以web应用的形式发布到你的应用服务器,比如tomcat。你所要做的就是下载war版本的文件,然后放到应用服务器的发布目录即可,这里就不多讲了。
到此我们已经安装好Nexus,下面我来介绍下一些我们常用的功能和使用:
2.7.3. 配置 中央仓库
先看一下界面:
在左边菜单栏里选择Repositories,然后会出现右边的画面,右边上半部分是列出来的repository,黑体字是类型为group的repository. 这里简单介绍下几种repository的类型:
· hosted,本地仓库,通常我们会部署自己的构件到这一类型的仓库。比如公司的第二方库。
· proxy,代理仓库,它们被用来代理远程的公共仓库,如maven中央仓库。
· group,仓库组,用来合并多个hosted/proxy仓库,当你的项目希望在多个repository使用资源时就不需要多次引用了,只需要引用一个group即可。
Maven central是Maven的中央仓库,点击它并选择configuration标签栏,我们会看到下面的页面:
这里有几个项目是我们可能会经常用到的:
1. Override local storage location: 在这个选项你可以配置你的Nexus本地仓库的存放地址,用来覆盖其默认的存放地址
2. Remote storage location: 这里是远程仓库的地址,为了提高代理速度,你可以修改为国内的镜像地址。默认值是http://repo1.maven.org/maven2/
3. Download remote indexes: 这里配置是否下载远程索引文件,模式是false, 建议配置为true,这样我们便可以通过索引文件来搜索我们需要的构件。
配置maven从Nexus下载构件
修改pom.xml如下:
<distributionManagement>
<repository>
<id>nexus-release</id>
<name>Nexus Release Repository</name>
<url>http://192.168.0.23:8081/nexus/content/repositories/releases/
</url>
</repository>
<snapshotRepository>
<id>nexus-snapshot</id>
<name>Nexus Snapshot Repository</name>
<url>http://192.168.0.23:8081/nexus/content/repositories/snapshots/
</url>
</snapshotRepository>
</distributionManagement>
使用已安装好的nexus服务器 url为http://192.168.0.23:8081/nexus/content/repositories/releases/
之后还需要再settings.xml里设置镜像即可下载,下一章节有提到
2.8. maven settings.xml的配置2.8.1. 本地仓库配置1. 打开 MAVEN_HOME/conf/settings.xml文件
2. 找到 <localRepository>/path/to/local/repo</localRepository>
3. 修改成功
<localRepository>E:\apache-maven-3.0.3\repos</localRepository>
这样maven就把maven指定到了此目录下.
在默认情况下:
1. WindowXp系统,用户是administrator的情况下,默认目录如下:
C:\Documents and Settings\Administrator\.m2\repository
2. Linux系统,用户是maven的情况下,默认目录如下:
/home/maven/.m2/repository
2.8.2. 镜像配置4. 打开 MAVEN_HOME/conf/settings.xml文件
5. 找到 < mirrors>标签
6. 添加如下
<mirror>
<id>mirrorId</id>
<mirrorOf></mirrorOf> //星符号表示所有
<name>Human Readable Name for this Mirror.</name> <url>http://192.168.0.23:8081/nexus/content/groups/public/</url>
</mirror>
这个表示镜像所有项目中pom.xml中
2.8.3. 服务用户配置7. 打开 MAVEN_HOME/conf/settings.xml文件
8. 找到 < servers>标签
9. 添加如下:
<server>
<id>nexus-release</id>
<username>admin</username>
<password>admin</password>
</server>
此配置可以对
distributionManagement.repository
distributionManagement.snapshotRepository
的部署气操作验证提供用户与密码的配置
2.8.4. 私有settings.xml配置10. 配置MAVEN_HOME/conf/settings.xml中是对一台PC机上所有用户都有效(在共用此maven的情况下)
11. 如果希望每个人都有各自的settings.xml配置,需要在当前的
· Window XP 系统
C:\Documents and Settings\[当前用户名]\.m2\
· Linux系统
/home/maven/.m2/
此目录下,复制一份MAVEN_HOME/conf/settings.xml到此目录下(注:此目录默认没有settrings.xml文件)
在 Maven 中使用 Nexus 配置settings.xml
到此为止我们介绍了如何安装和使用Nexus以及其基本配置, 下面我们介绍下如何让Maven来使用Nexus本地仓库用来替代使用远程仓库.
这里我们主要介绍如何配置镜像让maven只使用私服
在Maven使用Nexus本地仓库只需稍作配置, 在settings.xml中加入以下代码:
<servers>
<server>
<id>nexus-release</id>
<username>admin</username>
<password>admin</password>
</server>
<server>
<id>nexus-snapshot</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
<mirrors>
<mirror>
<id>mirrorId</id>
<mirrorOf></mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://192.168.0.23:8081/nexus/content/groups/public/</url>
</mirror>
</mirrors>
nexus-release和nexus-snapshot配置了登Nexus的账号密码
mirrorId我们之前安装的Nexus的地址, 这个地址可以是你们公司局域网内部的一台仓库服务器.
2.9. 生成项目站点
在项目的pom.xml中build节点加入site插件
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.0-beta-3</version>
<configuration>
<locales>zh_CN</locales>
</configuration>
</plugin>
</plugins>
</pluginManagement>
之后运行命令 mvn site,结果如下
之后就可以访问站点了
站点首页:
扩展 使用"mvn site:deploy"部署站点到服务器
1、启用WebDAV
启用Apache服务器的WebDAV功能
2、配置部署到哪里
在pom.xml中,使用"distributionManagement"标签配置将我们的站点部署到哪里。
pom.xml片段1<distributionManagement>
<site>
<id>xuejavaserver</id>
<url>dav:http://127.0.0.1/sites/</url>
</site>
</distributionManagement>
注意:前缀"dav"被添加到HTTP协议前面,这意味着通过WebDAV机制部署我们的站点。可选地,如果我们的服务器支持"scp"访问,我们可以使用"scp"来替代。
告诉Maven使用"wagon-webdav-jackrabbit"扩展用于部署。
pom.xml片段2<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-webdav-jackrabbit</artifactId>
<version>1.0-beta-7</version>
</extension>
</extensions>
</build>
下面是完整的pom.xml文件:
完整的pom.xml文件<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xuejava.core</groupId>
<artifactId>xuejava-core</artifactId>
<packaging>jar</packaging>
<version>1</version>
<name>xuejava.core</name>
<url>http://maven.apache.org</url>
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-webdav-jackrabbit</artifactId>
<version>1.0-beta-7</version>
</extension>
</extensions>
</build>
<distributionManagement>
<site>
<id>xuejavaserver</id>
<url>dav:http://127.0.0.1/sites/</url>
</site>
</distributionManagement>
</project>
3、配置WebDAV验证
正常地,WebDAV要求验证访问。所以,我们需要将相关的验证信息(用户名和密码)放在%MAVEN_PATH%/conf/settings.xml中。
settings.xml<servers>
<server>
<id>xuejavaserver</id>
<username>USERNAME</username>
<password>PASSWORD</password>
</server>
</servers>
什么是"xuejavaserver"id?在Maven的"settings.xml"文件中的服务器id将被"pom.xml"文件中的站点id所引用。
4、mvn site:deploy
使用"mvn site:deploy"命令进行部署:
部署过程D:\workspace\maven-text>xuejava-core>mvn site:deploy
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'site'.
[INFO] ------------------------------------------------------------------------
[INFO] Building xuejava-core
[INFO] task-segment: [site:deploy]
[INFO] ------------------------------------------------------------------------
[INFO] [site:deploy {execution: default-cli}]
http://127.0.0.1/sites/ - Session: Opened
//......
#http://127.0.0.1/sites//./css/maven-base.css - Status code: 201
Transfer finished. 4594 bytes copied in 0.044 seconds
18 April 2011 4:23:40 PM org.apache.commons.httpclient.auth.AuthChallengeProcessor
selectAuthScheme
INFO: digest authentication scheme selected
Uploading: ./css/maven-theme.css to http://127.0.0.1/sites/
//......
Transfer finished. 10120 bytes copied in 0.142 seconds
http://127.0.0.1/sites/ - Session: Disconnecting
http://127.0.0.1/sites/ - Session: Disconnected
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5 seconds
[INFO] Finished at: Mon Apr 18 16:23:43 SGT 2011
[INFO] Final Memory: 9M/16M
[INFO] ------------------------------------------------------------------------
D:\workspace\maven-text>xuejava-core
所有位于项目目录"target/site"之下的站点目录和文件,将被自动地部署到服务器中。
5、输出
部署以后,我们可以通过URL:http://127.0.0.1/sites访问部署的站点。
2.10. 使用Cargo插件自动化部署web容器Cargo是一组帮助用户操作Web容器的工具,它能够帮助用户实现自动化部署,而且它几乎支持所有的Web窗口,如Tomcat、JBoss、Jetty和Glassfish等。
部署至本地Web容器:
Cargo支持两种本地部署的方式,分别为standalone模式和existing模式。在standalone模式中,Cargo会从Web容器的安装目录复制一份配置到用户指定的目录,然后在此基础上部署应用,每次重新构建的时候,这个目录都会被清空,所有配置被重新生成。而且existing模式中,用户需要指定现有的Web容器配置目录,然后Cargo会直接使用这些配置并将应用部署到其对应的位置。
使用部署远程web容器
1.使用命令 mvn cargo:redeploy
更改pom.xml,如下
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<container>
<containerId>tomcat6x</containerId>
<type>remote</type>
</container>
<configuration>
<type>runtime</type>
<properties>
<cargo.remote.username>tomcat</cargo.remote.username>
<cargo.remote.password>tomcat</cargo.remote.password>>
<cargo.tomcat.manager.url>http://192.168.0.162:8099/manager</cargo.tomcat.manager.url>
</properties>
</configuration>
</configuration>
</plugin>
</build>
使用命令 mvn cargo:redeploy
(注意: 如果有些依赖包载不下来,可以在setting.xml更换中央仓库的地址 常用地址
)
最终发布成功,发布到tomcat6的webapp下
访问项目页面
2.在项目的pom.xml中的build节点下加入cargo插件,用jenkins构建发布
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>deploy</phase>
<goals>
<goal>redeploy</goal>
</goals>
</execution>
</executions>
<configuration>
<container>
<containerId>tomcat5x</containerId>
<type>remote</type>
</container>
<configuration>
<type>runtime</type>
<properties>
<cargo.remote.username>tomcat</cargo.remote.username>
<cargo.remote.password>tomcat</cargo.remote.password>>
<cargo.tomcat.manager.url>http://192.168.0.23:8099/manager</cargo.tomcat.manager.url>
</properties>
</configuration>
</configuration>
</plugin>
之后运行该项目即可,或者用jenkins进行构建
2.11. 使用WebLogic Maven Plugin插件自动化部署weblogic生成weblogic maven plugin的jar文件
cd weblogic路径\wlserver_10.3\server\lib
java -jar wljarbuilder.jar -profile weblogic-maven-plugin
这将生成一个weblogic-maven-plugin.jar文件
将生成的pom.xml 从weblogic-maven-plugin.jar文件中解压缩出来,放到 weblogic路径\wlserver_10.3\server\lib 目录
您可以用winrar,7zip或者任何解压缩工具,或者用文档介绍的办法:
jar xvf MW_HOME/wlserver_10.3/server/lib/weblogic-maven-plugin.jar META-INF/maven/com.oracle.weblogic/weblogic-maven-plugin/pom.xml
简化plugin的名称,方便使用
weblogic的maven plugin名字很长,使用时需要用全名,比如:com.oracle.weblogic:weblogic-maven-plugin:deploy
我们可以配置maven来使用缩写
修改 maven路径下\apache-maven-3.0.3\conf 下的settings.xml,找到pluginGroups,修改成:
<pluginGroups>
<pluginGroup>com.oracle.weblogic</pluginGroup>
</pluginGroups>
修改 weblogic路径\wlserver_10.3\server\lib 下的pom.xml文件为:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.oracle.weblogic</groupId>
<artifactId>weblogic-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>10.3.4</version>
<name>Maven Mojo Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>2.3</version>
<configuration>
<goalPrefix>weblogic</goalPrefix>
</configuration>
</plugin>
</plugins>
</build>
</project>
安装weblogic maven plugin到maven的本地repository
在weblogic路径\wlserver_10.3\server\lib 目录下执行:
mvn install:install-file -Dfile=.\weblogic-maven-plugin.jar -DpomFile=.\pom.xml
这样就可以把weblogic-maven-plugin的依赖包下载到本地仓库
(注意: 如果有些依赖包载不下来,可以在setting.xml更换中央仓库的地址 常用地址
)
在项目的的pom.xml中添加
<plugin>
<groupId>com.oracle.weblogic</groupId>
<artifactId>weblogic-maven-plugin</artifactId>
<version>10.3.4</version>
<configuration>
<adminurl>t3://192.168.0.162:7001</adminurl>
<user>weblogic</user>
<password>weblogic1</password>
<upload>true</upload>
<action>deploy</action>
<remote>false</remote>
<verbose>true</verbose>
<source>target/test-0.0.1-SNAPSHOT.war</source>
<name>test</name>
</configuration>
<executions>
<execution>
<phase> install </phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
其中source为项目的war包路径 必须先进行打包 修改下pom.xml的packaging节点为
<packaging>war</packaging>,运行mvn package
之后运用jenkins发布即可部署到weblogic中
如果不想以jenkins发布,也可以在项目路径下输入命令
mvn com.oracle.weblogic:weblogic-maven-plugin:deploy
2.12. maven和ant的比较第一:每次和别人说maven的时候,很多会认为是全新的东西而不肯放弃ant。其实,ant脚本是可以直接运行在maven中的。 如果要说maven和ant有什么差别,我觉得最大的差别就是在于maven的编译以及所有的脚本都有一个基础,就是POM(project object model)。这个模型定义了项目的方方面面,然后各式各样的脚本在这个模型上工作,而ant完全是自己定义,显然maven更胜一筹。 第二:Maven对所依赖的包有明确的定义,如使用那个包,版本是多少,一目了然。而ant则通常是简单的inclde 所有的jar。导致的最终结果就是,你根本无法确定JBoss中的lib下的common-logging 是哪个版本的,唯一的方法就是打开 META-INF 目录下MANIFEST.MF。估计JBoss迟早会转向Maven的。 第三:Maven是基于中央仓库的编译,即把编译所需要的资源放在一个中央仓库里,如jar,tld,pom,等。当编译的时候,maven会自动在仓库中找到相应的包,如果本地仓库没有,则从设定好的远程仓库中下载到本地。这一切都是自动的,而ant需要自己定义了。这个好处导致的结果就是,用maven编译的项目在发布的时候只需要发布源码,小得很,而反之,ant的发布则要把所有的包一起发布,显然maven又胜了一筹。 第四:maven有大量的重用脚本可以利用,如生成网站,生成javadoc,sourcecode reference,等。而ant都需要自己去写。试试 maven site 的效果
2.13. maven常用命令常用命令
1. 创建Maven的普通java项目:
mvn archetype:create
-DgroupId=packageName
-DartifactId=projectName
2. 创建Maven的Web项目:
mvn archetype:create
-DgroupId=packageName
-DartifactId=webappName
-DarchetypeArtifactId=maven-archetype-webapp
3. 编译源代码: mvn compile
4. 编译测试代码:mvn test-compile
5. 运行测试:mvn test
6. 产生site:mvn site
7. 打包:mvn package
8. 在本地Repository中安装jar:mvn install
9. 清除产生的项目:mvn clean
10. 生成eclipse项目:mvn eclipse:eclipse
11. 生成idea项目:mvn idea:idea
12. 组合使用goal命令,如只打包不测试:mvn -Dtest package
13. 编译测试的内容:mvn test-compile
14. 只打jar包: mvn jar:jar
15. 只测试而不编译,也不测试编译:mvn test -skipping compile -skipping test-compile
( -skipping 的灵活运用,当然也可以用于其他组合命令)
16. 清除eclipse的一些系统设置:mvn eclipse:clean
3. Svn3.1. 基本介绍svn(subversion)是近年来崛起的工具,是cvs的接班人。目前,绝大多数都使用svn作为代码版本管理软件。
总结
这个文档就是用来学习,以maven进行项目管理开发,由svn进行版本控制,用jenkins进行项目构建发布的过程
3.2. 安装3.2.1. 下载地址官网:
本地SHH 192.168.0.23/home/geosoft/soft
用户名root 密码admins
3.2.2. 安装步骤· 软件下载
下载Subversion服务器程序。
到官方网站的下载二进制安装文件,来到二进制包下载部分,找到 Windows NT, 2000, XP and 2003部分,然后选择Apache 2.0 或者 Apache 2.2,这样我们可以看到许多下载的内容,目前可以下载Setup-Subversion-1.5.3.msi 。
下载Subversion的Windows客户端TortoiseSVN。
TortoiseSVN是扩展Windows Shell的一套工具,可以看作Windows资源管理器的插件,安装之后Windows就可以识别Subversion的工作目录。
官方网站是TortoiseSVN ,下载方式和前面的svn服务器类似,在Download页面的我们可以选择下载的版本,目前的最高稳定版本的安装文件为TortoiseSVN-1.5.5.14361-win32-svn-1.5.4.msi。
· 服务器和客户端安装
服务器安装,直接运行Setup-Subversion-1.5.3.msi ,根据提示安装即可,这样我们就有了一套服务器可以运行的环境。
安装TortoiseSVN,同样直接运行TortoiseSVN-1.5.5.14361-win32-svn-1.5.4.msi按照提示安装即可,不过最后完成后会提示是否重启,其实重启只是使svn工作拷贝在windows中的特殊样式生效,与所有的实际功能无关,这里为了立刻看到好的效果,还是重新启动机器。
· 建立版本库(Repository)
运行Subversion服务器需要首先要建立一个版本库(Repository),可以看作服务器上存放数据的数据库,在安装了Subversion服务器之后,可以直接运行,如:
svnadmin create E:\svndemo\repository
就会在目录E:\svndemo\repository下创建一个版本库。
我们也可以使用TortoiseSVN图形化的完成这一步:
在目录E:\svndemo\repository下"右键->TortoiseSVN->Create Repository here...", 然后可以选择版本库模式, 这里使用默认即可, 然后就创建了一系列目录和文件。
· 配置用户和权限
来到E:\svndemo\repository\conf目录,修改svnserve.conf:
# [general]
# password-db = passwd
改为:
[general]
password-db = passwd
然后修改同目录的passwd文件,去掉下面三行的注释:
# [users]
# harry = harryssecret
# sally = sallyssecret
最后变成:
[users]
harry = harryssecret
sally = sallyssecret
在passwd文件中,"="前的字符就是用户名,后面的就是密码。还要注意"[users]"前面的注释"#"一定要删除掉。
· 运行独立服务器
在任意目录下运行:
svnserve -d -r E:\svndemo\repository 我们的服务器程序就已经启动了。注意不要关闭命令行窗口,关闭窗口也会把svnserve停止。
· 初始化导入
来到我们想要导入的项目根目录,在这个例子里是E:\svndemo\initproject,目录下有一个readme.txt文件:
右键->TortoiseSVN->Import...
在URL of repository输入"svn://localhost/trunk"
在Import Message中输入你的日志信息
完成之后目录没有任何变化,如果没有报错,数据就已经全部导入到了我们刚才定义的版本库中。
需要注意的是,这一步操作可以完全在另一台安装了TortoiseSVN的主机上进行。例如运行svnserve的主机的IP是133.96.121.22,则URL部分输入的内容就是"svn://133.96.121.22/trunk"。
4. Jenkins4.1. 基本介绍Jenkins,之前叫做Hudson,是基于Java开发的一种持续集成工具,用于监控秩序重复的工作,包括:
1、持续的软件版本发布/测试项目。
2、监控外部调用执行的工作。
4.2. 安装4.2.1. 下载地址官网 http://jenkins-ci.org/
本地SHH 192.168.0.23/home/geosoft/soft
用户名root 密码admins
4.2.2. 安装步骤把jenkins.jar下载到Linux服务器, 放入tomcat 的webapp下
启动tomcat
待部署好后 进入jenkins管理页面:
访问http://localhost:8080 , jenkins的主界面如下
4.3. Jenkins构建项目
注意:我们知道Jenkins通过master/slave来支持分布式的job运行,这里的项目运行在master,即Jenkins所在的机器。
创建Job任务
在ie中打开http://localhost:8080, 单击 新 job链接,新建job,且编译job的配置如下:
注意jenkins默认已经安装了svn的plugin了。
点击ok
源码管理选择svn 输入svn 的url 如果设置了用户名密码 会有提示输入。
如果没有安装maven,这里也会提示安装一下maven.点进去安装一下就可以 。
配置好后进入如下页面 点击立即构建
蓝色为成功构建,红色为失败
进入项目的主页面,点击build now链接进行build,build后可以在此主页面上看到所有的build历史:
然后还可以点击某个build的链接,查看某个build的详细日志,如下:
发布成功的话 之前项目启用的cargo插件会自动部署到web容器中,即可直接访问
5. 案例分析5.1. 下载在自己的本地目录安装svn客户端,在需要下拉的文件目录里右击SVN Checkout,弹出如下窗口
点击ok,就把案例项目下载到本地了
5.2. 现有项目目录结构项目存放在svn的现有环境地址中
Study-dao:数据访问模块,用来进行数据库的操作
Study-parent:所有模块的父模块,用来统一管理各个模块,统一构建项目
Study-service:服务模块,用来进行业务逻辑判断,并且依赖数据访问模块
Study-web:web网站,主要体现在表示层的页面,后台交互代码,依赖于数据访问模块和服务模块
依赖关系配置详见: 2.2.5
详细分析:
建立study-dao在src/main/java下建立实现类 用来对数据库user表的增删改查,添加insert方法
建立study-service在src/main/java下建立实现类, 添加login方法,里面需要调用study-dao模块的UserLoginDao的insert方法,需要在pom.xml添加对study-dao的依赖
如下: <dependency>
<groupId>com.maven.study</groupId>
<artifactId>study-dao</artifactId>
</dependency>
建立study-web在src/main/java下建立实现类,里面需要调用study-service模块的ILoginService的login方法,需要在pom.xml添加对study-service和study-dao的依赖
如下: <dependency>
<groupId>com.maven.study</groupId>
<artifactId>study-dao</artifactId>
</dependency>
<dependency>
<groupId>com.maven.study</groupId>
<artifactId>study-service</artifactId>
</dependency>
Web项目大体的模块依赖已经形成 ,现在需要建立一个父项目管理所有模块的依赖包和构建
父模块只需要一个pom.xml, 在study-dao, study-service,study-web的pom.xml中添加对parent的引用
<parent>
<groupId>com.maven.study</groupId>
<artifactId>study-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../study-parent/pom.xml</relativePath>
</parent>
Study-parent下的pom.xml添加modules对study-dao, study-service,study-web的统一管理
<modules>
<module>../study-dao</module>
<module>../study-service</module>
<module>../study-web</module>
</modules>
Study-parent下添加依赖包和插件和仓库,依赖包的版本在parent中可以得到统一, study-dao, study-service,study-web中依赖包不需要另注明版本,得以继承parent的依赖包版本