持续集成之maven(一)

持续集成

创建一个以java maven形式打包的项目在jenkins这个持续集成服务中持续部署。同时将代码检查、质量把控也一并融入到项目中。

 

本文我是在linux下进行的这一系列的部署安装。


1 maven

1.1 maven安装

http://maven.apache.org 下载安装都有详细资料。

安装后配置环境变量MAVEN_HOME

将%MAVEN_HOME%/bin配置到path中

1.1.1 下载解压

1、将maven3.0.4文件解压

2、将maven3.0.4重命名放到linux的/usr/local/maven3

1.1.2 设置环境变量

1、这里环境变量的设置在linux下直接可以在如下目录中(/etc/profile.d/java.sh)设置一个shell脚本来生效。这里我将整个java环境相关的环境变量都设置到一个java.sh脚本文件。

2、当修改完成脚本后可以直接运行java.sh脚本生效设置,或者通过. java.sh来生效。如果还是不生效,直接重启系统吧。

3、这个java.sh脚本内容参考如下:

JAVA_HOME=/usr/java/jdk1.6.0_22
ANT_HOME=/usr/local/apache-ant-1.8.4
CATALINA_BASH=$TOMCAT_HOME
CATALINA_HOME=$TOMCAT_HOME
JRE=$JAVA_HOME/jre
MAVEN_HOME=/usr/local/maven3
CLASSPATH=$JAVA_HOME/lib:$JRE/lib
PATH=$MAVEN_HOME/bin:$ANT_HOME/bin:$JAVA_HOME/bin:$JRE/bin:$PATH
export JAVA_HOME JRE CLASSPATH PATH  CATALINA_BASH CATALINA_HOME  MAVEN_HOME ANT_HOME


http://www.dsmsmk.net/ 北京德胜门中医院 北京治疗精神分裂医院 http://www.haienedu.com/

1.2 maven配置项

1.2.1 指定本地文件仓库

1.Maven 建议使用远程资源库以便于集中维护,这样将会最大程度地实现项目之间资源的共享。为避免每次构建时都要下载文件,Maven 在首次下载必需的相关性资源时就自动地将其高速缓存在本地资源库中。本地资源库的windows默认位置:%USER_HOME%/.m2/repository(windows:我的文档)

linux默认位置:/root/.m2/repository(当前我用的是root账号在操作)

如果要修改的话在settings.xml中

 

<!-- localRepository
  |The path to the local repository maven will use to store artifacts.
  |
  |Default: ~/.m2/repository
  在windows下可以指定一个绝对路径,参考如下
 -->
 <localRepository>E:\m2</localRepository>
 
 <!--在linux下也可以指定一个绝对路径,参考如下-->
 <localRepository>/usr/local/m2</localRepository>


 

1.2.2 指定私服文件仓库

将本地的存储库放在一台web服务器上也同样是个便利之举,这样整个开发团队就能从此获益,每个人都没有必要去管理自己的存储库了。Maven优先使用本地资源库中的资源,如果不存在就会去配置到远程资源库中下载,如果没有配置默认使用:http://search.maven.org/maven2

但是这样的话如果每次都需要去远程下载,如果网络发生问题会导致项目无法执行,因此一般都有会在内网环境搭建自己的“内网资源库”(私服),这样本地没有的话会到“内网资源库”下载,“内网资源库”没有才会到远程资源库中下载。这样整个开发团队就能从此获益,每个人都没有必要去管理自己的存储库了。改变Maven的存储库路径只需简单地编辑其安装目录下conf文件夹下面的settings.xml文件即可。按照上文说的我们在linux下将maven安装的方式可以对/usr/local/maven3/conf/settings.xml进行修改。

 

<!--定义私服仓库的网络位置,将其放到settings.xml文件的profiles中-->
<profile>
    <id>my-repository-profile</id>
     <repositories>
      <repository>
        <id>my-repository</id>
        <name>hd custom repo</name>
        <url>http://192.168.119.159:8080/m2/repository</url>
      </repository>
     </repositories>
   </profile>
 </profiles>
 
<!--如果想让上边的仓库生效,还是需要激活一下,下边展示的激活方式-->
 <activeProfiles>
   <activeProfile>my-repository-profile</activeProfile>
<!--如果是多个私服仓库,每个都声明即可,参考如下,我定义了一个opensource私服-->
 <activeProfile>opensource</activeProfile>
</activeProfiles>


 

1.3 pom.xml配置项

Maven2的项目配置文件为pom.xml在项目根目录、详细配置参见,这里只说明核心步骤。

官方文档地址

http://maven.apache.org/guides/introduction/introduction-to-the-pom.html

 

IBM参考文档

www.ibm.com/developerworks/cn/java/j-maven/

 

1.3.1 maven的全局文件

Maven的全局文件是

%MAVEN_HOME%/settings.xml

这里的MAVEN_HOME就是maven的安装路径。当我们想让eclipse中的maven配置和我们安装的maven一样,修改eclipse中的maven文件位置指向这个文件。

 

1.3.2 maven本地资源库

Maven 建议使用远程资源库以便于集中维护,这样将会最大程度地实现项目之间资源的共享。为避免每次构建时都要下载文件,Maven 在首次下载必需的相关性资源时就自动地将其高速缓存在本地资源库中。本地资源库的默认位置:%USER_HOME%/.m2/repository(windows:我的文档)

如果要修改的话在settings.xml中

 

<!-- localRepository
   | The path to thelocal repository maven will use to store artifacts.
   |
   | Default:~/.m2/repository
  -->
  <localRepository>C:\m2</localRepository>


 

1.3.3 maven的远程资源库

将本地的存储库放在一台web服务器上也同样是个便利之举,这样整个开发团队就能从此获益,每个人都没有必要去管理自己的存储库了。Maven优先使用本地资源库中的资源,如果不存在就会去配置到远程资源库中下载,如果没有配置默认使用:http://repo1.maven.org/maven2

但是这样的话如果每次都需要去远程下载,如果网络发生问题会导致项目无法执行,因此一般都有会在内网环境搭建自己的“内网资源库”(私服),这样本地没有的话会到“内网资源库”下载,“内网资源库”没有才会到远程资源库中下载。这样整个开发团队就能从此获益,每个人都没有必要去管理自己的存储库了。改变Maven的存储库路径只需简单地编辑其安装目录下conf文件夹下面的settings.xml文件即可。

 

<profile>
    <id>my-repository-profile</id>
     <repositories>
      <repository>
        <id>my-repository</id>
        <name>public repo</name>
        <url>http://192.168.1.2:8080/m2/repository</url>
      </repository>
     </repositories>
   </profile>
 </profiles>
 
 
 <activeProfiles>
   <activeProfile>my-repository-profile</activeProfile>
</activeProfiles>


1.3.4 依赖库配置

配置依赖库

<dependencies>
    <!-- This project depends onthe JAR file "commons-beanutils-1.5.jar"
         in the Maven repository's commons-beanutils/jars subdirectory
         (more about repository later).
         声明类库依赖关系
     -->
     <!-- 第3方类库声明 -->                         
    <dependency>
     <groupId>commons-betwixt</groupId>
     <artifactId>commons-betwixt</artifactId>
     <version>1.0-beta-1</version>
</dependency>
</dependencies>


所有项目在正式环境运行时需要用到的类库都需要在pom.xml进行声明,只要有声明maven会在执行编译的时候自动去下载(参看前文),打包(package)的时候会发布到war包中;

  对于那些编译时需要,但是运行不需要的类库则需要单独声明作用域<scope>

<!-- 非运行时所需的类库 -->
     <dependency>
     <groupId>servletapi</groupId>
     <artifactId>servlet-api</artifactId>
     <version>2.4</version>
     <scope>provided</scope>
</dependency>


 

目前<scope>可以使用5个值:

compile,缺省值,适用于所有阶段,会随着项目一起发布。

provided,类似compile,期望JDK、容器或使用者会提供这个依赖。如servlet.jar。

runtime,只在运行时使用,如JDBC驱动,适用运行和测试阶段。

test,只在测试时使用,用于编译和运行测试代码。不会随项目发布。

system,类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它。

1.3.5 项目集

使用Project Aggregation的情况:如果你有一组projects常常需要同时进行maven build的操作,那么你就可以创建一个parent project,然后把这组projects作为该parent project的modules,这样你只需要maven parent project即可执行这组projects。一个典型的例子就是:project A是build jar,project B是package war,该war会把project A的jar纳入, project C是package ear,该ear会把project B的war纳入。

 

具体做法:

在打包的项目平级目录下新建一个普通项目,在项目中创建一个pom.,xml即可

在这个配置文件中按照执行顺序声明打包涉及到的项目

<modules>
    <module>../project1</module>
(需要指定实际目录位置以便maven找到该项目)
 <module>../project2</module>
 <module>../project3</module>
<module>../project4</module>
</modules>


然后在该目录下执行mvn clean install 就会生成各个项目的jar(按照版本号)并安装到本地资源库中以便其他工程引用(生成war包)

1.3.6 发布项目到本地私服上

类库包的安装在有些情况下,当前使用的类库可能在远程资源库中获取不到(MAVEN为开源项目,不可能将有所的第3类库都加载到他的资源库中),因此需要我们手动上传到我们的内网资源库中。

操作步骤:

1、将类库安装到本地类库中

mvn install:install-file-Dfile=servlet-api.jar -DgroupId=servletapi -DartifactId=servlet-api-Dversion=2.4 -Dpackaging=jar -DgeneratePom=true


 

2、安装成功后进入本地资源库将文件目录copy到我们的内网资源库中,这样其他人再用到这个包maven就会直接从内网资源库中下载。

1.3.7 指定打包文件

Maven默认编译动作只会生成class文件到编译结果目录,这样在生成jar、war时就会缺少一些必要的配置文件,因此需要在pom.xml中生命包含这些资源。

 

<build>
 <!—
除了生成class文件外,还需要将src中的配置文件copy到编译目录中以便包含在jar中
-->
<resources>
      <resource>
       <directory> src </directory>
       <includes>
         <include> **/*.xml </include>
         <include> **/*.properties </include>
         <include> **/*.tld </include>
         <include> **/*.vm </include>
       </includes>
      </resource>
</resources>
……(其他配置项)
< build>


 

1.3.8 设置maven使用内存

当Maven项目很大,或者你运行诸如 mvn site 这样的命令的时候,maven运行需要很大的内存,在默认配置下,就可能遇到java的堆溢出。

解决方法:找到文件%M2_HOME%\bin\mvn.bat ,这就是启动Maven的脚本文件,在该文件中你能看到有一行注释为:

@REM set MAVEN_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE...


它的意思是你可以设置一些Maven参数,我们就在注释下面加入一行:

set MAVEN_OPTS= -Xms128m -Xmx512m


之后,当你运行Maven命令如 mvn -version 的时候,你会看到如下的输出:

E:\test>mvn -version
 
E:\test>set MAVEN_OPTS= -Xms128m -Xmx512m
Maven version: 3.0.3
Java version: 1.6.0_07
OS name: "windows 2003" version:"5.2" arch: "x86" Family: "windows"


我们看到,配置的Maven选项生效了,OutOfMemoryError也能得以相应的解决。

 

如果你使用Jenkins:

用 Jenkins+ Maven做持续集成,并不幸也遇到了类似的错误,那么上述两种方式都将不再起作用了,因为Jenkins使用自己的maven-agent来启动Maven,不会去调用Maven的脚本,自然相应的配置也就无效了。

好在Jenkins也给为我们提供了配置点,在Jenkins的项目配置页面中,有一块Build区域,这里我们已经设置了Root Pom和Goals。注意该区域的右下角有一个"Advanced..."按钮,点击会看到MAVEN_OPTS输入框,这里输入"-Xmx512m"就OK了。

1.3.9 maven的项目依赖设置

我们的工程通常都依赖系统中的其他工程、在打包的时候需要将这些工程jar包含在我们发布的war包中,因此在工程的pom.xml需要特别声明依赖关系

 

<!-- mmt工程依赖 -->
     <dependency>
       <groupId>hd</groupId>
       <artifactId>hdlogutils</artifactId>
       <version>1.2.0</version>
     </dependency>
     
     <dependency>
       <groupId>hd</groupId>
       <artifactId>b2b2c</artifactId>
       <version>1.2.0</version>
     </dependency>
     
     <dependency>
       <groupId>hd</groupId>
       <artifactId>hd</artifactId>
       <version>1.2.0</version>
 </dependency>


只要声明了依赖,那么在工程打war包的时候会自动加载这些工程jar(前提是这些工程都可以通过最顶部的build工程中的pom.xml定位到参看前文)

1.3.10 版本号的设定

版本号变的极为重要,因为maven要通过

<groupId>hd</groupId>
<artifactId>hd</artifactId>
<version>1.2.0</version>


这3个属性定位所依赖的资源,因此同一个工程的不同分支(包括主干)都要有唯一的版本号,否则在打包的时候会发生将错误的版本打入到发布包中。

1.3.11 打包命令

执行编译、测试、打包、findbugs、测试用例代码覆盖率的maven命令

mvn clean compile packagefindbugs:findbugs cobertura:cobertura


1.3.12 单元测试支持

为了运行单元测试,在detail_build(打包项目)pom增加参数

<properties>
    <!-- 单元用例测试数据来源 -->
    <test_db>22</test_db>
 </properties>


用于确定使用哪套测试数据库进行测试,同时在项目的test目录增加测试用hibernate数据源配置文件(为了生成测试用的mmt-test.jar),这个文件需要各工程负责人定时与发布版本的hibernate配置文件同步,以保证持久类的一致。

1.3.13 测试报告相关

为了定位测试报告生成目录以及hd-test目录,需要在hd工程以及应用项目工程下的pom.xml增加参数

<properties>
 <build_detail_workspace>../build_detail</build_detail_workspace>
</properties>


 

1.3.14 pom文件继承

为了继承一些公用配置方便使用logutils、b2b2c、hd、应用项目的pom.xml都继承了打包项目的pom.xml,这个配置项要根据各工程位置的不同自行修改。

 <!-- 设定继承关系-->

<parent>
    <groupId>hd</groupId>
    <artifactId>build_detail</artifactId>
    <version>1.2.0</version>
    <relativePath>../build_detail/pom.xml</relativePath>
 </parent>


 

1.4 maven版本规则

Maven主要是这样定义版本规则的:

<主版本>.<次版本>.<增量版本>

比如说1.2.3,主版本是1,次版本是2,增量版本是3。

主版本一般来说代表了项目的重大的架构变更,比如说Maven 1和Maven 2,在架构上已经两样了,将来的Maven 3和Maven 2也会有很大的变化。次版本一般代表了一些功能的增加或变化,但没有架构的变化,比如说Nexus 1.3较之于Nexus 1.2来说,增加了一系列新的或者改进的功能(仓库镜像支持,改进的仓库管理界面等等),但从大的架构上来说,1.3和1.2没什么区别。至于增量版本,一般是一些小的bug fix,不会有重大的功能变化。

一般来说,在我们发布一次重要的版本之后,随之会开发新的版本,比如说,myapp-1.1发布之后,就着手开发myapp-1.2了。由于myapp-1.2有新的主要功能的添加和变化,在发布测试前,它会变得不稳定,而myapp-1.1是一个比较稳定的版本,现在的问题是,我们在myapp-1.1中发现了一些bug(当然在1.2中也存在),为了能够在段时间内修复bug并仍然发布稳定的版本,我们就会用到分支(branch),我们基于1.1开启一个分支1.1.1,在这个分支中修复bug,并快速发布。这既保证了版本的稳定,也能够使bug得到快速修复,也不同停止1.2的开发。只是,每次修复分支1.1.1中的bug后,需要merge代码到1.2(主干)中。

上面讲的就是我们为什么要用增量版本。

以jms为例,比如我们的async_client项目增加一些新的功能,但是在开发周期时会不断更新那么在未产生稳定版本的时候我们会在版本号后面追加SNAPSHOT 比如4.3.0版本的限定版本为4.3.0-SNAPSHOT的其在pom.xml中的依赖关系为

<dependency>
      <groupId>jms</groupId>
     <artifactId>async-client</artifactId>
     <version>4.3.0-SNAPSHOT</version>
</dependency>


1.5 maven发布到仓库中

内部项目的生成包一般不和第3类库放在一次,有单独的发布路径对应在仓库的配置分别为

      

<!-- 第3方类库资源库 -->
      <repository>
        <id>nexus-thirdparty-repository</id>
        <name>thirdparty repo</name>
        <url>http://192.168.119.159/nexus/content/repositories/thirdparty/</url>
      </repository>
 
 
 
 
       <!-- 内部项目类库资源release版本库 -->
      <repository>
        <id>nexus-releases-repository</id>
        <name>mmt project release repo</name>
        <url>http://192.168.119.159/nexus/content/repositories/releases/</url>
      </repository>
 
        <!-- 内部项目类库资源sanpshot版本库 -->
      <repository>
        <id>nexus-snapshots-repository</id>
        <name>mmt project snapshots repo</name>
        <url>http://192.168.119.159/nexus/content/repositories/snapshots/</url>
      </repository>

 

每个repository都需要设置权限账号,否则是无法发布到服务器上的,该账号可以通过Nexus仓库创建。

 

<server>     
     <id>nexus-snapshots-repository</id>     
     <username>admin</username>     
     <password>admin123</password>     
    </server>   
    <server>    
     <id>nexus-releases-repository</id>     
     <username>admin</username>     
     <password>admin123</password>     
    </server>
    <server>    
     <id>nexus-thirdparty-repository</id>     
     <username>admin</username>     
     <password>admin123</password>     
    </server>


对于发布版本的项目包要发布到nexus-releases-repository上,对于开发中的项目包发布到nexus-snapshots-repository上。

 

上述工作都做好后,每次deploy,maven都会将SNAPSHOT改成一个当前时间的timestamp,比如B-1.0-SNAPSHOT.jar到nexus中后,会成为这个样子:B-1.0-20081017-020325-13.jar。Maven在处理A中对于B的SNAPSHOT依赖时,会根据这样的timestamp下载最新的jar。

转载于:https://my.oschina.net/abcijkxyz/blog/722024

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值