首页 » 软件开发 » 敏捷开发CI工具实战:Jenkins+Maven(仓库项目依赖配置构件)

敏捷开发CI工具实战:Jenkins+Maven(仓库项目依赖配置构件)

admin 2024-07-24 17:02:47 0

扫一扫用手机浏览

文章目录 [+]

CI流程

1. 已部署环境地址

Jenkins:http://192.168.0.23:8099/jenkins/

Nexus: http://192.168.0.23:8081/nexus/

敏捷开发CI工具实战:Jenkins+Maven(仓库项目依赖配置构件) 软件开发
(图片来自网络侵删)

站点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的依赖包版本

标签:

相关文章

语言中的借用,文化交融的桥梁

自古以来,人类社会的交流与发展离不开语言的传播。在漫长的历史长河中,各民族、各地区之间的文化相互碰撞、交融,产生了许多独特的语言现...

软件开发 2025-01-01 阅读1 评论0

机顶盒协议,守护数字生活的新卫士

随着科技的飞速发展,数字家庭逐渐走进千家万户。在这个时代,机顶盒成为了连接我们与丰富多彩的数字世界的重要桥梁。而机顶盒协议,作为保...

软件开发 2025-01-01 阅读1 评论0

语言基础在现代社会的重要性及方法步骤

语言是人类沟通的桥梁,是社会发展的基础。语言基础作为语言学习的基石,对于个人、社会乃至国家的发展具有重要意义。本文将从语言基础在现...

软件开发 2025-01-01 阅读2 评论0

粤语电影,传承文化,点亮时代之光

粤语电影,作为中国电影产业的一朵奇葩,以其独特的地域特色、丰富的文化内涵和鲜明的艺术风格,赢得了广大观众的喜爱。本文将从粤语电影的...

软件开发 2025-01-01 阅读1 评论0

苹果游戏语言,塑造未来娱乐体验的基石

随着科技的飞速发展,游戏产业逐渐成为全球娱乐市场的重要支柱。在我国,游戏产业更是蓬勃发展,吸引了无数玩家和投资者的目光。而在这其中...

软件开发 2025-01-01 阅读1 评论0