Fetchhttps nginx failedd: fatal: repository 'https://github.com/xxx/xxx.git/' not fo

[转载]Jenkins&Solutions我来了
Final Target to this solutions
Git/SVN/GitHub
Anlyst:&&&
Jenkins/Maven
Unit Test:&&&
Deployment:&&&
Jenkins/KVM(How to Rollback)
Accept Test:&&&
------------------------
jekins+maven+svn/gitHub+junit -&Windows
Implementation based on rhel
Implementation based on ubuntu
以下参考均为网络文章,出处如下,蓝色字体为亲历亲为
http://blog.csdn.net/onlyqi
==========================================================
----------------------------------------------------------------------------------------------------
Jenkins是一个CI工具。它可以持续编译,运行你的代码;运行UT或集成测试;将运行结果发送至邮件,或展示成报告。。。
这样做的最终目的是:
让项目保持健康的状态。如果任何checkin
break了build,每个人都会在最短的时间内通知到,然后问题被fix。接下来的开发将建立在一个健康正确的基础上,而不是任由问题累积,最后失控。
最后,你的项目随时可以被deliver给用户,因为,你的项目每一天都在健康,茁壮的生长。这就是CI的意义所在。
Jenkin和cruisecontrol
Jenkins和cruisecontrol都是CI工具,二者在CI中发挥的作用完全一致。
而Jenkins作为新一代的CI工具,渐渐开始取代cruisecontrol。二者都是java程序,但:
1,Jenkins提供更为友好的用户界面,而cruisecontrol在界面方面糟糕的几乎等于没有。
2,Jenkins内置的功能提供了极大的便利,不论是新建一个build,还是日常使用,你需要做的大部分时候仅仅是在用户界面上点击而已。
在cruisecontrol新建build是通过创建config.xml来完成的。它仅仅提供非常有限的功能,很多时候你会发现,需要自己完成很多工作。
3,Jenkins作为一个欣欣向荣的开源项目,有大批的plugin。当你发现需要一个Jenkins本身并不提供的功能是,搜索一下plugin,总会有收获。非常多的流行工具如JBehave,cobertura都提供jenkins插件。
而针对cruisecontrol的plugin却很少。
4,Jenkins友好的用户界面让学习成本很少,你可以在最短的时间内开始你的工作。
事实上,Jenkins是我见过的最好的开源项目之一,它简洁实用的用户界面设计,完善的文档,丰富的插件。当你开始使用它,你就会爱上它。
当你需要一个build工具时,Jenkins几乎是当下的不二选择。
Jenkins和Hudson
Jenkins起源于Hudson。Hudson在商业软件的路上继续前行,而Jenkins则作为开源软件,从hudson分支出来。
因此现在的jenkins和hudson非常类似,但是随着二者各自的发展,已经有了一些不同。
要想更多的了解Jenkins,当然最好是访问它的官方网站。也可以参考我的下一篇文章:
Jenkins(二)&
http://blog.csdn.net/onlyqi/article/details/7076915
至少和官网比起来,它是中文的~
官网:https://wiki.jenkins-ci.org/display/JENKINS/Meet+Jenkins
我的这篇文章仅仅是简单的根据上文,介绍Jenkins提供了哪些功能。具体大家还是要自己学习啦~
官网首页就提供了windows版本的Jenkins安装包。我们可以下载一个用于学习。安装后自动打开http://localhost:8080,你就能看见Jenkins的界面了。
其他也需要安装的是:
<span STYLE="color:#,Jenkins是java程序,因此需要安装JDK。
<span STYLE="color:#,同时运行job需要提供repository,也就是存放Jenkins定期poll源代码的地方。我们可以去github免费注册一个。
<span STYLE="color:#,如果想在Jenkins中使用ant,maven等,则还需要单独安装。但不是必须的。
启动Jenkins
Jenkins天生支持unix-like system。
好吧,Jenkins是一个java程序,所以要运行它,只需要:
$ java -jar jenkins.war
我们也可以使用nohup命令,让Jenkins在后台运行。
之后打开URL http://myServer:8080
就可以方便的操作Jenkins了
官网给了一个sh的例子,用于启动Jenkins。可以参考一下。
在Servlet container中运行
Alternatively, if you have a servlet container that supports
Servlet 2.4/JSP 2.0, such as Glassfish v2, Tomcat 5 (or any later
versions), then you can run them as services, and
deployjenkins.war as you would any other war file.
For example,
you could simply place the jenkins.war file in Tomcat’s webapps
directory.& 此时使用的URL默认就变成:
http://localhost:8080/jenkins
同时Jenkins提供一些默认不会启动的特殊的功能,参考下面的link来enable它们。
https://wiki.jenkins-ci.org/display/JENKINS/Features+controlled+by+system+properties
Jenkins的目录结构
和CruiseControler一样,Jenkins需要一个目录来存储相关文件:JENKINS_HOME。默认为
~/.jenkins。即为user的home目录下的一个隐藏目录。我们也可以更改JENKINS_HOME,指向我们希望的地方。
(注意因为是隐藏目录,所以需要使用ls -al 才能看到)
JENKINS_HOME
config.xml&&&&
(jenkins root configuration)
*.xml&&&&&&&&&
(other site-wide configuration files)
userContent&&&
(files in this directory will be served under your
http://server/userContent/)
fingerprints&& (stores
fingerprint records)
plugins&&&&&&&
(stores plugins)
[JOBNAME]&&&&&
(sub directory for each job)
config.xml&&&&
(job configuration file)
workspace&&&&&
(working directory for the version control system)
latest&&&&&&&&
(symbolic link to the last successful build)
&&&&&&&&&&&&
[BUILD_ID]&&&&
(for each build)
&&&&&&&&&&&&&&&&
build.xml&&&&&
(build result summary)
&&&&&&&&&&&&&&&&
log&&&&&&&&&&&
(log file)
&&&&&&&&&&&&&&&&
+- changelog.xml& (change log)
如果有权限管理,则在HOME目录下还会有users目录。
从目录结构来看,和CruiseController非常相似。其中config.xml是Jenkins重要的配置文件。我们都知道Jenkins用于monitor多个build,而jobs这个目录无疑就是存储每个build相关信息的地方。
总的来说,Jenkins目录结构非常直白,简洁。
备份和恢复
备份和恢复非常简单,就是简单的copy
Jenkins的目录就好了:
settings, build logs, artifact archives are stored under the
JENKINS_HOME directory. Simply archive this directory to make a
back up. Similarly, restoring the data is just replacing the
contents of the JENKINS_HOME directory from a back
移动/拷贝/重命名
由于每个jobs都有自己单独的目录,我们可以很容易的:
&&& 1,move a job
from one installation of Jenkins to another by simply copying the
corresponding job directory.
&& ,2,make a copy of an existing
job by making a clone of a job directory by a different name.
&&& 3,rename an
existing job by renaming a directory.
修改后执行下面的命令刷新:
http://[jenkins-server]/[command]
在这里[command]可以是:exit 退出,restart 重启, reload 重载。
创建一个Project
因为Jenkins可以用于运行各种CI,测试,批处理任务等等,所以在Jenkins中将这些任务统称为“free-style
software project”.
Jenkins也提供了其他类型的jobs,例如:
1,如果项目是Maven,Jenkins还提供了一种仅用于Maven Project的job。但其实free-style
software projec仍然可以用于创建Maven项目,只不过这种更适合Maven项目,结合的更好而已。
2,也可以创建一个"Monitor an external job“用于监控外部进程。
3,或者一个Matrix project,也就是multi-configuration project。
我不确定是否仅有这4种job,也许使用插件可以创建更多类型的job,大家自己看资料吧。
下面是如何创建一个最常见的“free-style software project"的过程:
Go to Jenkins top page, select "New Job", then choose "Build a
free-style software project". This job type consists of the
following elements:
optional SCM, such as CVS or Subversion where your source code
resides. 指定源代码在哪。
Note: In software engineering, software configuration
management (SCM) is the task of tracking and controlling
changes in the software.
optional triggers to control when Jenkins will perform builds.
指定Jenkins何时触发一次build。
some sort of build script that performs the build (ant, maven,
shell script, batch file, etc.) where the real work happens
触发build时,使用的脚本文件,例如ant。在这个脚本文件中,我们可以从svn下载最新代码,删除上次build的临时文件,创建必要目录,编译源
代码,运行,打包等一系列工作。
optional steps to collect information out of the build, such as
archiving the artifacts and/or recording javadoc and test results.
收集log信息。
optional steps to notify other people/systems with the build
result, such as sending e-mails, IMs, updating issue tracker, etc.
通知相关人员build的结果。
例如我们使用的build
script就是ant,在Jenkins中运行ant。在脚本文件中,可以直接使用Jenkins提供的一些变量。
同时,每个job可以有多个step。例如:将运行程序定义为step1,运行单元测试定义为step2,生成coverage报告定义为step3。
同时还可以定义post-build action。例如:生成javadoc,或清理程序运行的临时文件目录等。
自动运行Build
触发一个build有三种方式:
Builds in Jenkins can be triggered periodically (on a schedule,
specified in configuration)
这里定义schedule的语法是unix常见的cron语法。
Or when source changes in the project have been detected
可以设置Jenkins定时检查SVN是否发生了变化,也可以手动检查:http://YOURHOST
/jenkins/job/PROJECTNAME/pollong。也可以设置Jenkins为post-commit,这个方式尤其适用于那些检查是
否代码改变会花费很长时间的情况。
Or they can be automatically triggered by requesting the
http://YOURHOST/jenkins/job/PROJECTNAME/build
Distributed
Jenkins supports the "master/slave" mode, where the workload of
building projects are delegated to multiple "slave" nodes, allowing
single Jenkins installation to host a large number of projects, or
provide different environments needed for builds/tests.
在现实中需要使用distributed builds情况很多,例如:一个web
application的build,需要分别验证firefox和IE的行为,那么就需要到windows机器上运行IE。
或因为性能问题,将build分布到多个slave节点去。
到Jenkins的管理界面,就可以方便的添加节点。配置节点时,需要提供节点所在的机器,登陆用户名密码,使用的目录等。
但是slave并不需要再安装Jenkins。jenkins会自动启用slave
agent,将build需要tools考到远程机器上。
需要注意的是:the build results and artifacts will always end up on the
master server. 因此不需要跑到各个节点去查看build产生的文件,log等。
其实在slave节点,会创建一个本地的workspace,并在运行时使用这个workspace。因为毕竟build运行在slave节点上,所以这个节点肯定要有运行build需要的所有因素。
总之添加节点并远程运行build真是太方便了~
添加节点后,在master Jenkins home目录下会出现关于该节点的配置文件。
Jenkins将自动决定在哪个节点上运行build,根据下列策略:
Some slaves are faster, while others are slow. Some slaves are
closer (network wise) to a master, others are far away. So doing a
good build distribution is a challenge. Currently, Jenkins employs
the following strategy:
If a project is configured to stick to one computer, that's
always honored.
Jenkins tries to build a project on the same computer that it
was previously built.
Jenkins tries to move long builds to slaves, because the amount
of network interaction between a master and a slave tends to be
logarithmic to the duration of a build (IOW, even if project A
takes twice as long to build as project B, it won't require double
network transfer.) So this strategy reduces the network
Jenkins通过运行slave agents来完成分布式build。最常见的情况是:slave agent运行在各个slave
节点。master通过SSH远程启动/停止slave agent,进而控制各个节点的行为。
一共有下列4种方式启动slave agent:
&The master starts the slave agents via ssh
& Starting the slave agent manually using Java Web Start
& Installing the slave agent as a Window service
& Starting the slave agent directly from the command line on the
slave machine from the command line
需要注意的是这4种方式适用于不同的情况,例如slave节点在防火墙后,导致master无法通过SSH启停slave
agent。此时只能用后三种方式,但是往往有一些弊端,比如master无法自动停止/重启 slave agent.
一旦添加node成功,你就可以在job中指定这个job在哪个node运行:
Restrict where this project can be run
(如果不指定则由Jenkins自行决定,即可以在slave节点运行,也可以在master节点运行,甚至在一次build中就可以自行来回切换)。
配置Jenkins,让它收集更多的log
https://wiki.jenkins-ci.org/display/JENKINS/Logging
我想这对于初学Jenkins的人,用来判断问题所在太有用了。
在流行持续集成的今天,我们在各个环境:alpha,beta和production 都部署了唯一的Jenkins服务器。
Jenkins服务器统一负责该环境内所有组件的持续集成。也就是说,一个Jenkins服务器会有很多个build。所以有时会用到上面提到的”Monitor
an external job“。
但不是Distributed Builds。
同时由于Jenkins会进入每个环境,包括production,因此会使用auto
deployment的方式,自动完成Jenkins在各个环境的部署。
毫无疑问Jenkins中需要有用户管理的功能,因为除开发人员外,有多种角色的人需要查看build的结果。
在Jenkins中的系统管理中,可以设置“任何用户可以做任何事” 或 “登录用户可以做任何事”。
因此前一个选项意味着,任何浏览JenkinsURL的用户都可以修改Jenkins。或只有登录用户才能做修改。
所以我把Jenkins中的用户划分为两类:可登录用户和不可登录用户。
1,只要是修改过repository,即对build产生过影响的用户,都会被Jenkins记录在本地的database中。这类用户我们可以在Jenkins界面-&查看用户中浏览。
但这类用户不是正式的Jenkins用户,也不能登录Jenkins。这类用户的权限由上面说的系统管理中的配置决定。通常只有查看build的权限,没有修改权限。
2,只有在Jenkins中明确注册的用户,才能够登录Jenkins,并且有权限控制。同时注册过的用户,在
JENKINS_HOME目录下的users目录下,都有一个单独的目录来存储相关信息。我不太清楚是否能够通过copy/paste将用户部署到其他地
方去,回头测试一下。
既然要满足各种人对jenkins使用的各种需求,因此权限管理远没有这么简单。具体大家还得自己去看啊~
Jenkins Script
Jenkins提供了一个script console&Groovy script which
allows to run arbitrary scripts on the Jenkins server or on slave
nodes. This feature can be accessed from the "manage Jenkins"
也可以通过URL直接访问:http://myserver:8080/hudson/script
可惜只能用Groovy 反证我不懂。
在使用Jenkins的过程中,当然也会遇到一些问题。在这里我把我遇到的,比较奇怪的问题列出来,供大家参考。
我在一个slave node上运行job时发现,被启动的程序显示找不到环境变量。
原来,当Jenkins在slave上启动一次build时,不会应用当前用户的profile。因此我们得自己解决这个问题。
解决方式有很多:
1,在创建slave node时,可以指定要传递的环境变量。这种方法不好的地方就是,相当于hard
code,当实际的环境变量改变时,也需要手工修改slave node的配置。
2,想办法自己应用:运行shell前运行:. /usr/usr_account/.profile
(注意第一个点后面有空格),这个是最好的方法,因为所有的环境变量都会生效,而不是仅仅某一个。
或者在调用的ant中,或ksh script中指定某个具体的环境变量。
进程被kill
需求是这样的:在Jenkins中一个job运行完毕时,可以配置它触发下一个job运行。这种情况很常见,例如一个
job中启动一个程序并运行了UT,当运行完毕时,我们可能会希望一个集成测试的job被触发。这里隐含的意思就是,我们希望程序能一直运行,直到所有的
测试结束,最后再显式的停止这个程序。
然而在实施的过程中,我遇到了一个大问题:在第一个job运行结束后,程序就被杀掉了。第二个job没有运行测试的时间。
来看看这个人遇到的类似的问题:
I am trying to run a shell script to stop/start the JBoss
instance, but when the Hudson job completes, the JBoss instance
shutdowns.& Does anybody have any recommendations
on how we can spawn an instance of JBoss from a Hudson job without
using the daemonize script?
由于现实中事情的复杂性(在Jenkins中调用了ant,ant调用了ksh,ksh最终启动了程序),我绕了很大一圈才怀疑到Jenkins上。在这之前,我尝试在ant中使用,在调用ksh时使用nohup,但是问题依旧。
而问题的根本在于是Jenkins使用processTreeKiller杀掉了所有子进程,而且这是Jenkins的
默认行为。其实回头来看这个问题,就发现Jenkins的做法非常合理。当一次build异常结束,或被人终止时,必然需要结束所有这次build启动的
子进程。下面的link提供了更多细节,以及解决方法。
https://wiki.jenkins-ci.org/display/JENKINS/ProcessTreeKiller
home目录下的tools目录没有被同步到slave node
在Jenkins的home目录下,有两个自动生成的目录: tools
and usercontent。
当我在使用slave node时,我注意到在每个slave
node的上,Jenkins自动建了一个tools目录。因此我想当然的以为,tools目录是用来存放用户自己需要的第三方工具的。
例如,我在project中需要使用ant 1.8.2。而tools中则存放了ant
1.8.2,同时在建立slave node时,Jenkins自动将ant1.8.2拷贝到了slave
node的tools下。
然而在之后的使用中,我发现在master node的tools中放置其他的第三方工具后,slave
node的tools中并没有增加。因此slave
node上的project并不能使用对应的第三方工具。
事实真相是,我应该使用usercontent目录,而不是直接使用tools目录。
当用户需要某个第三方工具时,正确的做法是将安装包放到usercontent目录。然后在Jenkins
system management中要求安装这个工具。
userContent目录的说明:
use this directory to place your own custom content onto your
Jenkins server. You can access files in this directory at
http://myserver/hudson/userContent (if you are running
Jenkins on an application server) or http://myserver/userContent
(if you are running in standalone mode).
之后Jenkins会自动将该工具安装到tools目录下,同时也会同步到slave
node的tools下。像我这样直接扔在master
node的tools下,是不会自动同步的。
还有一种解决方案:
Jenkins 并没有机制自动将master node上的tools目录下的内容同步到slave
node上。这意味着如果在slave node上运行project需要某些特殊工具(或jar包),只能事先在slave
node所在的box上安装好(或准备好)。
但是在某些极端条件下,slave node并没有准备好这些工具。
例如,我们使用Jenkins来自动deployment最新的release到production,而安装release意味着很多附加功能,例如环境检查,安装程序,自动启停程序,启动cluster等复杂操作。
我们使用Ant script来完成这些操作。但Ant在production环境没有安装。
因此我希望将ant相关的jar放到master jenkins根目录的tools目录,然后将tools同步到slave
node的tools目录下,之后在slave node上运行Ant就可以使用这些jar包了。
但是目前我们只能通过使用一个工具rsync来将tools下的内容同步到slave node:
On master, I have a little shell script that uses rsync to
synchronize master's/var/jenkins to slaves
(except/var/jenkins/workspace) I use this to replicate
tools on all slaves.
如何取得slave node上的jenkins
我在脚本里,或Ant中使用环境变量JENKINS_HOME的时候发现一个问题: 尽管限制了job在slave
node上运行,但是这个变量的值还是master node的JENKINS_HOME。而不是在slave
node的配置中配置的“Remote FS root”
一个解决方案是,在创建slave node时,在配置页面下方的node
properties中添加一个环境变量:SLAVE_HOME=上面配置的“Remote FS root”目录。这样就可以在slave
node上使用这个变量了。
You can also specify environment variables. These will be
passed into your build jobs, and can be a good way to allow your
build jobs to behave differently depending on where they are being
比如在ant中,加入:
来获取所有的环境变量。
之后用就可以了。
这里顺便提一下,有一个plugin可以显示每次build时,jenkins自动生成的环境变量。在shell,
ant中都可以方便的使用这些变量。
在所有的projects中传递参数一个需求:有3个projects,run.program, run.ut,
run.integration.test
它们使用在一个project完成后自动trigger另外一个的方式,形成了一个chain。同时第一个project是parameterized-
project,即build时需要提供输入参数。其中一个输入参数是,boolean ifRunUT,是否运行UT。
现在,如果在第一个project中选择不运行UT,则skip后面的那个project,之后继续运行第三个project,也就是集成测试。
解决方法是安装这个plugin:https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Trigger+Plugin
同时将后面的run.ut改为parameterized-project,同时有唯一的一个输入参数ifRunUT。
上面的plugin可以将第一个project的输入参数传递到它触发的下一个project。这样当后面的run.ut发现ifRunUT=false时,就自动返回successful,之后该project继续触发之后的run.integration.test。
听上去有点无聊,但是试想一下,如果有两个关于ut的project:run.ut.1
run.ut.2。上面的方法就可以一次配置,skip掉两个projects,而不需要配置多次。
更重要的是,这种做法使得整个chain的配置都集中在一个地方,而不是分散在各个project中。每次build都需要去多个projects配置参数是很让人崩溃的。
------------------------------------------------------
14:50 4621人阅读 (1)
jenkins自带的邮件管理太弱了,为了能按自定义的方式发送邮件,需要安装一个插件:&。
1.配置邮件:通过“系统管理”-“系统设置”,进行系统设置界面,上面的内容在“使用Jenkins配置自动化构建”中已经讲过,直接移动到设置页面的最下面,“邮件通知”部分,设置上“stmp服务器“和”用户默认邮件后缀“,如图:
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://img.my.csdn.net/uploads//_2248.png" ALT=""
TITLE="[转载]Jenkins&Solutions我来了" />
如果成功安装了,在邮件通知的上面还有
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://img.my.csdn.net/uploads//_1406.png" ALT=""
TITLE="[转载]Jenkins&Solutions我来了" />
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://blog.csdn.net/littlechang/article/details/8706322" ALT="" STYLE=""
TITLE="[转载]Jenkins&Solutions我来了" />
到这里,系统级的邮件设置已经完成了。
创建一个测试的自动构建项目,如svnTest
其他部分不说了,只说邮件部分,点”Add posts-build action“,选择”Editable Email
Notification“,出现下面的界面:
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://img.my.csdn.net/uploads//_8275.png" ALT="" NAME="image_operate_52312"
TITLE="[转载]Jenkins&Solutions我来了" />
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://blog.csdn.net/littlechang/article/details/8706322" ALT="" STYLE=""
TITLE="[转载]Jenkins&Solutions我来了" />
这些内容都可以根据你的需要进行修改。
完成之后,点”立即构建“看看是不是成功,如果成功了,就大功告成了。如果不成功,那就慢慢的调了^_^。
有一个地方要注意:如果配置的邮件服务器是,好像就只能发送邮件到126邮箱,这个我配置的是这样,不知道是不是全部是这样。
--------------------------------------------
本文主要对 jenkins
的邮件通知进行介绍,
内置的邮件功能
使用插件扩展的邮件功能
1. 先介绍下 基本的Jenkins 邮件服务器
& &1)system config 页面
(以公用的163邮件服务器为例):
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/blog/308/-ee2dfe9b8f6fd095cc2b2af.png" ALT=""
TITLE="[转载]Jenkins&Solutions我来了" />
可以勾选 “通过发送测试邮件配置” &测试此配置能否连通, 如果收到以下邮件,恭喜
is test email #1 sent from Jenkins
& &2)下面接着对构建的job
添加邮件发送的步骤,
<img src="/blog7style/images/common/sg_trans.gif" real_src ="/blog/308/-ae725fcaa7074e6cab50c68d2f175b54.png" ALT=""
TITLE="[转载]Jenkins&Solutions我来了" />
&这样每次build后都会发送邮件给这个接收者, 到这里你会发现,只能发给
固定的对象,且格式单一(txt)
&====好了,现在进入主题====
2. &使用插件
“”进行扩展
&它可根据构建的结果,发送构建报告,给当前的committer (用git做代码管理)
& &1) 该插件支持jenkins
1.5以上的版本,至少我的 1.486是不支持的啦。所以果断升级吧。。
& & 插件的安装此处略
,若您可选插件的页卡的列表是空的,先去高级页面检查更新下。
&2)插件用于job配置页面,添加构建后步骤“Editable Email
Notification”
&<img src="/blog7style/images/common/sg_trans.gif" real_src ="/blog/308/6be14a8114bca98121ad6dcf1c1ee.png" ALT=""
TITLE="[转载]Jenkins&Solutions我来了" />
& &上面的配置 给出了 该工程的默认接收列表,当然抄送的话
直接 可以这么写 cc:
& &对于内容,你也许注意到了 这里调用了个
的模板,这是插件内置的,直接用即可。(支持git每次变更的记录,mvn 及junit 等编译的结果报告)
& &当然也可以自己写 jelly文件, 确保放置
jenkins/home/email-template下 以供jenkins调用。 &
& & 3)至此你也许会问 这不还是用的固定的接收列表嘛
(&#8857;_&#8857;) ,别着急 看到右下角的高级选项没, 继续配置,
& &&<img src="/blog7style/images/common/sg_trans.gif" real_src ="/blog/308/32e53bdc.png" ALT="" NAME="image_operate_83735"
TITLE="[转载]Jenkins&Solutions我来了" />
& & &我设置了
build成功和失败都发给 默认的接收者和当前提交代码的家伙,而send to requester
是指手动触发构建时当前登陆jenkins的用户。
& &1. 如果有人 git
commit时候没有进行global的name和email设置,将不会发送到正确的邮箱(jenkins将按各自的机器名作为域名地址发送到错误的邮箱)
& &2. 当然还可在jenkins 管理用户中 个别设置
邮箱。不过对于团队较多的话,你就苦了。 所以还是有必要请大家提交前进行实名设置。
/GGHHLL/p/jenkins.html
------------------------------------------------
http://blog.csdn.net/yanmingming1989/article/details/8557716
安装jenkins:
安装 jenkins 有两种方式:
安装方式一:&
sudo&java&-jar&jenkins.war&&httpPort=18080&&ajp13Port=18009&&
是很多时候我们是使用SSH方式到目标机器上的,放我们关闭SSH连接时,这个命令也会被中断,jenkins服务会被终止,我们不可能一直保持这SSH
连接,怎么办?可以把这行命令写成 shell 脚本,然后使用 nohup sh jenkins.sh &
命令启动这个脚本,这样jenkins就能正常提供服务了。
安装方式二:安装 RPM包
为了能够使用jenkins库,首先需要导入jenkins库的 key:
sudo&wget&-O&/etc/yum.repos.d/jenkins.repo&http://pkg.jenkins-ci.org/redhat/jenkins.repo&sudo&rpm&&import&http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key&&
安装软件(以jenkins-x.x.x.rpm为例):yum install jenkins-x.x.x.rpm
& &删除软件:yum remove
jenkins-x.x.x.rpm或者yum erase jenkins-x.x.x.rpm
& &升级软件:yum upgrade jenkins或者yum
update jenkins
& &查询信息:yum info jenkins
开启服务(关闭,重启): &
sudo&service&jenkins&start|stop|restart&&
检查jenkins是否安装完成: localhost:8080 (默认是8080
端口,如果采用安装方式一,那么就需要指定的端口)
运行job时遇到的问题:
&mvn:command not found
遇到的问题: 不能使用MVN命令;
排查过程:
&#9312;Jenkins 默认创建进程,启动任务的用户名是 jenkins,使用root权限查看passwd,可以看到这个用户默认情况下
ssh 为false,也就是说这个用户默认情况下是不能使用ssh进行登录的,除非修改 passwd中相应字段为
bash,然后sourse;
jenkins:x:500:500:mengqc:/home/jenkins:/bin/fasle
passwd文件的格式:
&注册名:口令:用户标识号:组标识号:用户名:用户主目录:命令解释程序
&#9313;默认情况下 Jenkins 的安装目录是 /var/lib/jenkins/ ,项目根目录是
/var/lib/jenkins/jobs/workspace
从目录上看,就知道这个是需要 root 权限才能执行一些命令,但是我们通过界面 执行一些命令使用的是admin用户,纵使我们在
根目录下 能适应mvn命令,但是问题也不能解决。
还有一个简单的测试Maven
是否加入到了环境变量中的方法,在执行mvn命令时,填写maven安装的绝对路径,如果能够执行,说明不是权限的问题,而是环境变量的问题。
解决方案一:
&#9312;安装 ssh slave 插件;
&#9313;启动slave 服务;
&#9314;jenkins-系统管理-节点管理:重新设置 slave机器的 Remote FS root 为
/home/admin/xxx
(主要是添加了workspace的目录) $ITEM_ROOTDIR
&#9315;把master的节点数设为0,这样默认情况下就会使用 slave节点。
如果修改 工作目录(Remote FS root),可能会遇到:
“main”java.lang.NoclassDefFoundError:hudson/maven/agent/Main&&
原因:我们修改了slave的工作目录,但是slave服务没有重启导致;
解决方法:使用我们的脚本 对slave进行 重启操作。
解决方案二:
在 /home/admin/目录下新建一个工作目录,然后将 /var/lib/jenkins目录设置成一个跳转链接
,链接到admin目录下 [sudo ln -s /home/admin/xxx/
&/var/lib/jenkins] ,然后将/var/lib/jenkins 目录下的文件 mv
到/home/admin/xxx/ 目录下。
mvn和一些基本的命令是可以运行了,但是运行shell脚本时还是没有权限,因为 新建的这个跳转连接user=root
,group=root,并且对这个链接 使用chown/chgrp 都是没有效果的,执行一些操作命令是还是没有权限;
解决方案三:修改默认 jenkins 用户为 admin
&#9312;安装jenkins&
Java代码 &(我们一般使用的是admin权限)
sudo&wget&-O&/etc/yum.repos.d/jenkins.repo&http://pkg.jenkins-ci.org/redhat/jenkins.repo&&&&
sudo&rpm&--import&http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key&&&&
sudo&yum&install&jenkins&&&&
rpm&-ql&jenkins&&&&
&#9313;. 配置jenkins&
Java代码 &
// edit JENKINS_PORT, JENKINS_USER &
sudo vi /etc/sysconfig/jenkins &(把 JENKINS_USER
设置为 admin)
&#9314;. 修改jenkins权限(如果修改JENKINS_USER情况下)&
Java代码 &
sudo&chown&-R&admin&/usr/lib/jenkins&&&&
sudo&chgrp&-R&admin&/usr/lib/jenkins&&&
sudo&chown&-R&admin&/var/log/jenkins&&&
sudo&chgrp&-R&admin&/var/log/jenkins&&&&
sudo&chown&-R&admin&/var/lib/jenkins&&&&
sudo&chgrp&-R&admin&/var/lib/jenkins&&&&
sudo&chown&-R&admin&/var/cache/jenkins&&&
sudo&chgrp&-R&admin&/var/cache/jenkins&(这个如果不改,会出现404)&&
&#9315;. 启动jenkins&
Java代码 &
sudo /sbin/service jenkins start&
或者 &sudo service jenkins start
&-------------------------------------------------------------
/html/87/659.htmlLinux安装Jenkins手册
一、前期准备
因为我是在系统上连接服务器以及需要把在Windows系统下载的安装包上传到Linux系统,所以需要用到两个工具---putty和FileZilla。
Putty是一个免费的、Windows 32平台下的telnet、rlogin和ssh,但是功能丝毫不逊色于商业的telnet类工具。 用它来远程管理Linux十分好用。
FileZilla是一种快速、可信赖的FTP以及服务器端开放源代码程式,具有多种特色、直觉的接口。
这两款工具都是免安装的,使用非常方便。
2.1卸载linux上自带的jdk
用root用户登陆到系统,打开一个终端输入
# rpm -qa|grep gcj显示内容其中包含下面两行信息
# java-1.4.2-gcj-compat-1.4.2.0-27jpp
java-1.4.2-gcj-compat-devel-l.4.2.0-27jpp卸载
# rpm -e java-1.4.2-gcj-compat-devel-l.4.2.0-27jpp
java-1.4.2-gcj-compat-l.4.2.0-27jpp
卸载其他自己安装的JDK就直接用rpm
&&卸载rpm版的jdk:
#rpm -qa|grep jdk
&&显示:jdk-1.6.0_10-fcs
&&卸载:#rpm -e&
jdk-1.6.0_10-fcs
2.2安装JDK
去/technetwork/java/javase/downloads/jdk-6u32-downloads-1594644.html拿1.6.0举例,下载一个Linux
Platform的JDK,建议下载RPM格式的(我下载的是&Linux x86 (32-bit)的名称为jdk-6u32-linux-i586-rpm.bin的jdk)
2.2&&&把刚才第一步下载的bin文件上传到Linux服务器上,在下执行命令:
注:我的jdk安装包放在home目录下
[root@testdep home]# chmod 755
jdk-6u32-linux-i586-rpm.bin
[root@testdep home]# ./
jdk-6u32-linux-i586-rpm.bin
&这时会有一段Sun的协议如下
########################################
######################################## [100%]
Unpacking JAR
&&&&&&&rt.jar...
&&&&&&&jsse.jar...
&&&&&&&charsets.jar...
&&&&&&&tools.jar...
&&&&&&&localedata.jar...
&&&&&&&plugin.jar...
&&&&&&&javaws.jar...
&&&&&&&deploy.jar...
Development Kit 6 successfully installed.
Product Registration is FREE and
includes many benefits:
* Notification of new versions,
patches, and updates
* Special offers on
products, services and
* Access to early releases and
documentation
Product and system data will be
collected. If your configuration
supports a browser, the JDK Product
Registration form. will
be presented. If you do not register,
none of this information
will be saved. You may also register
your JDK later by
opening the register.html file
(located in the JDK installation
directory) in a
For more information on what data Registration collects
how it is managed and used,
/javase/registration/JDKRegistrationPrivacy.html
Press Enter to continue.....
2.3安装jdk主程序包
程序会自动生成一个jdk-6u32-linux-i586.rpm文件,这是主程序包,下面来安装;
[root@testdep home]#rpm &ivh
jdk-6u32-linux-i586.rpm
2.4设置环境变量
&&&&&通常都喜欢用export命令直接在shell下设置
[root@ testdep home]# export
JAVA_HOME=/usr/java/jdk1.6.0_32
[root@ testdep home]# export
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
[root@ testdep home]# export
PATH=$PATH:$JAVA_HOME/bin当然这样设置环境变量是可以生效的,但是只对当前shell生效。如果从另外一个shell登陆,将不能使用刚才设置的变量。所以最好的方法还是修改.bashrc文件。我用下面这个
.bashrc是在根目录下
[root@testdep ~]#vi .bashrc
export JAVA_HOME=/usr/java/jdk1.6.0_32(这里的jdk的版本号可以通过cd /usr/java查看)
export JAVA_HOME
export PATH=$PATH:$JAVA_HOME/bin
export PATH
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export CLASSPATH
注:保存成功后需要通过.
.bashrc使此脚本生效。
当然也可以通过更改/etc/profile来实现,不过不推荐这么做,因为这样的设置将对所有用户的shell都生效,对系统安全会产生影响。下面来验证一下变量设置是否生效(在验证前先logout一下,再重新登陆);
[root@testdep home]# echo $JAVA_HOME
/usr/java/jdk1.6.0_32/
[root@testdep home]# echo $CLASSPATH
/usr/java/jdk1.6.0_32/lib/dt.jar:/usr/java/jdk1.6.0_32/lib/tools.jar
[root@testdep home]# echo $PATH
/usr/java/jdk1.6.0_32/bin/:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
[root@testdep home]# JAVA-version
JAVA version "jdk1.6.0_32"
JAVA(TM) 2 Runtime Environment, Standard Edition (build
1.4.2_06-b03)
JAVA HotSpot(TM) Client VM (build 1.4.2_06-b03, mixed
2.5环境变量是否安装成功
环境设置OK,看看JDK是否能正常工作,我们来写一个测试文件.java
[root@LinuxServer rpm]#vi
class test
public static void main(String[] args)
&&&&&&&&&&&&&
System.out.println("Hello World!");
保存退出,下面来编译、执行;
[root@testdep home]# javac
[root@testdep home]# java test
Hello World!
OK,工作正常。
2.6&&如果要使某个用户具有运行java命令的权限,只要修改其bash初始化文件即可。比如要给用户longware以运行java命令的权限,
[root@LinuxServer root]# vi /home/longware/.bashrc
export JAVA_HOME=/usr/java/jdk1.6.0_32
export JAVA_HOME
export PATH=$PATH:$JAVA_HOME/bin
export PATH
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export CLASSPATH
2.7&&&至此,Linux上JDK的安装完毕。
三、在下配置Tomcat服务器
&&Tomcat是一个免费的开源的Serlvet容器,它是Apache基金会的Jakarta项目中的一个核心项目,由Apache,Sun和其它一些公司及个人共同开发而成。由于有了Sun的参与和支持,最新的Servlet和Jsp规范总能在Tomcat中得到体现。
  Tomcat是稳固的独立的服务器与Servlet Container,不过,其Web服务器的功能则不如许多更健全的Web服务器完整,如Apache Web服务器(举例来说,Tomcat没有大量的选择性模块)。不过,Tomcat是自由的开源软件,而且有许多高手致力于其发展。
3.1安装jdk
在安装Tomcat之前需要安装j2sdk( 2
Software Development Kit),也就是JDK。
请参考第一部分。
3.2下载tomcat
在&下载tomcat6.0,
<img STYLE="cursor:" TITLE="点击图片可在新窗口打开" HEIGHT="192" BORDER="0" WIDTH="554"
ALT="[转载]Jenkins&Solutions我来了" />&&&请选择上图红色所示的tomcat版本。
3.3解压tomcat安装包
解压缩刚才的tomcat安装包(apache-tomcat-6.0.35.tar.gz)。
注:我把tomcat安装包暂时通过FileZilla上传到了home目录下。
[root@testdep
home]#tar &zxvf apache-tomcat-6.0.35.tar.gz
3.4为压缩包指定目录
把解压缩的文件放在一个新建的目录下
[root@testdep
home]#cp -R apache-tomcat-6.0.35 /usr/local/tomcat
//拷贝apache-tomcat-6.0.35到/usr/local/下并重命名为tomcat
3.5设置tomcat的路径
[root@testdep home]cd
[root@testdep home]vi
//在第一步卸载和安装Linux JDK设置jdk的路径后面加上tomcat的路径
//vi编辑器的使用方法请大家一下
TOMCAT_HOME=/usr/local/tomcat
注:修改过.bashrc文件后需要通过一下命令使.bashrc生效。
[root@testdep home]. .bashrc
安装完后,重新启动tomcat以使JAVA_HOME和TOMCAT_HOME的设置生效.
3.6启动tomcat运行命令:
[root@testdep
home]#/usr/local/tomcat/bin/startup.
//正常情况下可以见到如下的信息:
&Using CATALINA_BASE:
/usr/local/tomcat
  Using CATALINA_HOME:
/usr/local/tomcat
CATALINA_TEMDIR: /usr/local/tomcat/temp
Using JAVA_HOME:
/usr/java/jdk1.6.0_35
3.7关闭tomcat
运行命令:
[root@testdep
home]#/usr/local/tomcat/bin/shutdown.
四、在Tomcat里边配置Jenkins
4.1&&在下载Jenkins的war包。
4.2&&通过FileZilla把刚下载的Jenkins包从本机PC上传到Linux服务器的webapps目录下。
[root@testdep home]cd
/usr/local/tomcat/webapps
<img STYLE="cursor:" TITLE="点击图片可在新窗口打开" HEIGHT="176" BORDER="0" WIDTH="492"
ALT="[转载]Jenkins&Solutions我来了" />
可看出刚刚上传的jenkins
4.3&Jenkins安装完成,可以通过本地PC连接上Linux上的Tomcat服务器。
&&&&在本地PC的浏览器窗口输入:
http://192.168.3.182:8080/jenkins/
4.4&&&&&&至此Jenkins的配置安装完成。
五、Jankins的相关配置
5.1&&&&&&首次进入Jenkins的主页面会出现如下截图所示的错误提示:
<img STYLE="cursor:" TITLE="点击图片可在新窗口打开" HEIGHT="75" BORDER="0" WIDTH="554"
ALT="[转载]Jenkins&Solutions我来了" />
意思是tomcat容器没有使用UTF-8编码,所以不能使用中文作为任务名称,可以在tomcat中进行配置。
[root@testdep home]# cd
/usr/local/tomcat/conf
[root@testdep home]#vi .xml
connectionTimeout="20000"
redirectPort="8443"URIEncoding="UTF-8"/&
注:增加了utf-8的编码格式URIEncoding="UTF-8"
5.2默认情况下,JENKINS_HOME会在当前用户的家目录下建立,名称为.jenkins,
在linux下:~/.jenkins
----------------------------------------------
持续集成Jenkins API常见用法
jenkins(持续集成开源工具)提供了丰富的api接口,基本上所有的操作都可以使用curl来从后台调度,包括:创建项目,禁用项目,启用项目,获取项目描述,获取配置文件,普通触发,scm触发,带参数触发,带补丁触发。
【背景】:部门在搞持续集成,使用jenkins作为核心调度,要再其基础上进行二次封装,所以需要研究下jenkins的api。笔者主要负责搭建平台,在研究用法也花费了些时间,本文主要做个简要的记录,希望能为各位朋友节省时间。
【环境】:(默认读者已经具备了基本的持续集成经验和jenkins用法)
2. 系统Suse
3. Tomcat&6.0.37
4. Java&1.6.0_26
【API介绍】
&Jenkins提供了html、json、python API,实质都是以http
get/post方式调用的。查看http://www.xxx.xxx/jenkins/api/ 即可得到相应的说明,如图:
【API实践】
curl -X POST http://www.xxx.xxx/jenkins/createItem?name=JavaStd
&--user peterguo:peterguo --data-binary
"@javastd.config.xml" -H "Content-Type: text/xml"
curl -X POST http://www.xxx.xxx/jenkins/job/JavaStd/disable
&--user peterguo:peterguo
curl -X POST http://www.xxx.xxx/jenkins/job/JavaStd/enable
--user peterguo:peterguo
curl -X POST http://www.xxx.xxx/jenkins/job/JavaStd/doDelete
--user peterguo:peterguo
5.获取项目描述&
curl -X GET http://www.xxx.xxx/jenkins/job/JavaStd/description
--user peterguo:peterguo
6.获取配置文件&
curl -X GET http://www.xxx.xxx/jenkins/job/JavaStd/config.xml
--user peterguo:peterguo
7.触发SCM检查&
curl -X GET http://www.xxx.xxx/jenkins/job/JavaStd/polling
--user peterguo:peterguo
8.普通触发&
curl -X GET http://www.xxx.xxx/jenkins/job/JavaStd/build --user
peterguo:peterguo
9.带参数触发
curl -X GET
"http://www.xxx.xxx/jenkins/job/helloworld-freestyle/buildWithParameters?bAllTest=&Choices=2&strParam=abc"
--user peterguo:peterguo
10.带参数和补丁触发
curl -X POST
"http://www.xxx.xxx/jenkins/job/helloworld-freestyle/buildWithParameters?bAllTest=&Choices=2&strParam=abc"
--user peterguo:peterguo -F "action=upload" -F
"patch.diff=@OtherTest.java.patch"
注:带补丁触发需要先安装补丁插件,并设置项目的补丁参数
<img ALT="持续集成Jenkins API常见用法" src="/blog7style/images/common/sg_trans.gif" real_src ="http://static./lib/uploadImg/_353.png" HEIGHT="202" WIDTH="259"
TITLE="[转载]Jenkins&Solutions我来了" />
【Python调用】
&提供python使用pycurl调用的例子片段,实际和curl调用一样,优点是易整合。
import&pycurl
url&=&"http://10.129.145.112:8081/jenkins/job/helloworld-freestyle/config.xml"
crl&=&pycurl.Curl()
crl.setopt(pycurl.VERBOSE,1)
crl.setopt(pycurl.FOLLOWLOCATION,&1)
crl.setopt(pycurl.MAXREDIRS,&5)
crl.setopt(pycurl.USERPWD,&"peterguo:peterguo")
crl.setopt(pycurl.CONNECTTIMEOUT,&60)
crl.setopt(pycurl.TIMEOUT,&300)
crl.setopt(pycurl.HTTPPROXYTUNNEL,1)
crl.fp&=&StringIO.StringIO()
crl.setopt(pycurl.URL,&url)
crl.setopt(crl.WRITEFUNCTION,&crl.fp.write)
crl.perform()
ret&=&crl.fp.getvalue()
来自:http://my.oschina.net/sanpeterguo/blog/197931
----------------------------------------
Jenkins 有两类config.xml:
在Jenkins home之下的config.xml是Jenkins server的配置文件。
另外在每个job或project自己的目录下,还有一个config.xml。它包含了是这个job的配置信息。
The Jenkins home directory contains all the details of your
Jenkins server configuration, details that you configure in the
Manage Jenkins screen.
A user appearing in this list cannot necessarily log on to
(People who make changes to code in a source
code repository that Jenkins is monitoring)
It is a good idea for developers to use their SCM username here:
this case, Jenkins will be able to work out what users contributed
to the SCM changes
that triggered a particular build.
Post-build Actions 对应了 config.xml中的
builder 就对应build
Source Code Management&
portfolio controller builder-maven , publishers:ant
merge.results
portfolio package:builder-ant&
target:portfolio.packaging。 publishers没有。
每个job下面都有一个workspace,里面有hudson_migration需要的所有ant脚本。
同时 workspace/trunk下 对于一个项目有两个文件:
portfolio_pom.xml
https://sami.cdt./svn/searchandnavigation_searchandnavigation/Development/CP1.5/trunk/SourceCode/Controller/portfolio
Indeed, Continuous Delivery can be viewed as Continuous
Deployment
with the final step (deployment into production) being a manual one
dictated by
the business rather than the development team.
----------------------------------------------------------------------------------------------------
当我们在IDE中开发时,经常需要使用maven。现在流行的java的IDE有eclipse,intellij等等。对于maven而言,我们可以将IDE分为两类:
1,Eclipse等和maven结合的不够紧密的IDE。
Eclipse和Maven结合的并不算好,如果在eclipse中想使用maven,需要安装插件:m2e
安装该插件之后,你才能在eclipse中看到关于maven的菜单,并且可以创建maven项目,执行maven
为了在命令行中使用maven,我们往往会在本地再单独安装一个maven。这样就会有一个问题:eclipse中运行maven
goal时,即可以选择使用embedded maven,也可以选择单独安装的maven。如下:
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://img.my.csdn.net/uploads//_3894.png" ALT="" NAME="image_operate_89999"
TITLE="[转载]Jenkins&Solutions我来了" />
为了在命令行中使用maven的效果和在eclipse中执行maven
goal的效果一致,建议在eclipse中选择单独安装的maven而不是内嵌的maven。
2,Intellij,Netbeans等较为紧密的IDE。
在intellij这类IDE中,不需要单独安装maven插件了。我们还是需要自己安装maven,同时也可以配置所使用的maven(默认是按环境变量M2_HOME):
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://img.my.csdn.net/uploads//_4094.png" ALT="" NAME="image_operate_91299"
TITLE="[转载]Jenkins&Solutions我来了" />
在导入一个maven项目时,往往需要下载很多本地repository中没有的dependency。如果出现连不上互联网的repository时,我们可以:
1,打开maven
settings.xml,配置代理。或让maven去指定的repository下载。注意maven有默认的settings.xml在maven
home的conf目录下。
user settings.xml默认是没有的,但是可以创建且其将覆盖默认的settings.xml
2,修改完后,在命令行运行mnv
package重新开始下载。我在intellij中遇到过maven无法下载所有的dependency,但在命令行中执行则可以的情况。可能和IDE和maven的集成有关系。
在IDE中安装了maven插件之后,就可以直接运行maven package来打包了。
如果没有在IDE中安装插件而是单独安装了maven程序,则可以在命令行中直接执行mvn package来打包。
二者没有本质区别,本文以在IDE中直接为例。
要将项目打包,有两种选择:生成一个jar包;或一个包含jar包,配置文件,脚本文件等等的一个zip文件(assembly)。
如果没有在pom中显示的指定,则会使用默认的插件(通过查看effective
pom可以看到)并按默认方式打包。
我们常用maven-jar-plugin来生成jar包。如果希望生成assembly,则除了maven-jar-plugin外,再使用插件maven-assembly-plugin来生成zip包。
&&/span&plugin&&&
&&&&&&&&&&&&&&&&&&/span&artifactId&maven-jar-plugin&/&/span&artifactId&&&
&&&&&&&&&&&&&&&&&&/span&version&2.3.1&/&/span&version&&&
&&&&&&&&&&&&&&&&&&/span&executions&&&
&&&&&&&&&&&&&&&&&&&&&&/span&execution&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&/span&id&default-jar&/&/span&id&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&/span&phase&package&/&/span&phase&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&/span&goals&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&goal&jar&/&/span&goal&&&
&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&goals&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&/span&configuration&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&archive&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&manifest&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&addClasspath&true&/&/span&addClasspath&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&mainClass&com.thomsonreuters.PALFullExtractor.ExtractorMain&/&/span&mainClass&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&manifest&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&archive&&&
&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&configuration&&&
&&&&&&&&&&&&&&&&&&&&&/&/span&execution&&&
&&&&&&&&&&&&&&&&&/&/span&executions&&&
&&&&&&&&&&&&&/&/span&plugin&&&
在上例中,指定mainClass将在manifest文件中加入mainclass,这样jar就可以直接运行了。
&&/span&plugin&&&
&&&&&&&&&&&&&&&&&&/span&artifactId&maven-assembly-plugin&/&/span&artifactId&&&
&&&&&&&&&&&&&&&&&&/span&version&2.2&/&/span&version&&&
&&&&&&&&&&&&&&&&&&/span&executions&&&
&&&&&&&&&&&&&&&&&&&&&&/span&execution&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&/span&id&make-assembly&/&/span&id&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&/span&phase&package&/&/span&phase&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&/span&goals&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&goal&single&/&/span&goal&&&
&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&goals&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&/span&configuration&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&archive&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&manifest&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&mainClass&com.thomsonreuters.PALFullExtractor.ExtractorMain&/&/span&mainClass&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&manifest&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&archive&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&descriptorRefs&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&descriptorRef&jar-with-dependencies&/&/span&descriptorRef&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&descriptorRefs&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&descriptors&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/span&descriptor&D:projectnamesrcmainassembly/assembly.xml&/&/span&descriptor&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&descriptors&&&
&&&&&&&&&&&&&&&&&&&&&&&&&/&/span&configuration&&&
&&&&&&&&&&&&&&&&&&&&&/&/span&execution&&&
&&&&&&&&&&&&&&&&&/&/span&executions&&&
&&&&&&&&&&&&&/&/span&plugin&&&
注意其中2点:
1,descriptorRef -- jar-with-dependencies
就是将程序依赖的所有第三方类库都打入jar包,这样就不需要在运行时指定class-path了。
2,descriptor --
指定assembly文件所在的位置。我们还需要创建一个assembly.xml来详细说明package的目录结构和内容。
assembly.xml文件的示例:
&&/span&assembly&&&
&&&&&&/span&id&package&/&/span&id&&&
&&&&&&/span&formats&&&
&&&&&&&&&&/span&format&zip&/&/span&format&&&
&&&&&/&/span&formats&&&
&&&&&&/span&includeBaseDirectory&false&/&/span&includeBaseDirectory&&&
&&&&&&/span&fileSets&&&
&&&&&&&&&&/span&fileSet&&&
&&&&&&&&&&&&&&/span&directory&src/main/resources/config&/&/span&directory&&&
&&&&&&&&&&&&&&/span&outputDirectory&config&/&/span&outputDirectory&&&&
&&&&&&&&&&&&&&/span&includes&&&
&&&&&&&&&&&&&&&&&&/span&include&*.xsd&/&/span&include&&&
&&&&&&&&&&&&&&&&&&/span&include&*.dtd&/&/span&include&&&
&&&&&&&&&&&&&&&&&&/span&include&*.xml&/&/span&include&&&
&&&&&&&&&&&&&&&&&&/span&include&*.properties&/&/span&include&&&
&&&&&&&&&&&&&&&&&&/span&include&*.key&/&/span&include&&&
&&&&&&&&&&&&&/&/span&includes&&&
&&&&&&&&&&&&&&/span&lineEnding&lf&/&/span&lineEnding&&&
&&&&&&&&&/&/span&fileSet&&&
&&&&&&&&&&/span&fileSet&&&
&&&&&&&&&&&&&&/span&directory&src/main/resources/script&/&/span&directory&&&
&&&&&&&&&&&&&&/span&outputDirectory&&/&/span&outputDirectory&&&
&&&&&&&&&&&&&&/span&includes&&&&
&&&&&&&&&&&&&&&&&&/span&include&*.ksh&/&/span&include&&&&
&&&&&&&&&&&&&&&&&&/span&include&*.cmd&/&/span&include&&&&
&&&&&&&&&&&&&/&/span&includes&&&&
&&&&&&&&&&&&&&/span&lineEnding&lf&/&/span&lineEnding&&&&
&&&&&&&&&/&/span&fileSet&&&&
&&&&&/&/span&fileSets&&&
&&&&&&/span&dependencySets&&&&
&&&&&&&&&&/span&dependencySet&&&
&&&&&&&&&&&&&&/span&outputDirectory&lib&/&/span&outputDirectory&&&
&&&&&&&&&/&/span&dependencySet&&&&
&&&&&/&/span&dependencySets&&&
&/&/span&assembly&&&
这样打好的package名叫例如:project-1_0.zip中解压后就会得到脚本文件以及另外两个目录config(包含配置文件),和lib目录(包含所有依赖的第三方类库和projectName.jar)
我们还可以在assembly按需要构建更复杂的package结构。
从maven-jar-plugin和maven-assembly-plugin的pom文件可以看到它们都指定了:package
这会导致运行mvn package命令时运行这两个插件。
直接搜索这两个插件的名字可以找到maven官网中队插件更详细的介绍。
http://maven.apache.org/guides/introduction/introduction-to-the-pom.html
本文基本上是翻译+一点点理解。
POM(Project Object Model)
是Maven的基础。它是一个XML文件,包含了Maven用来build项目所需要的项目配置的信息。
(译者:在使用ant进行build时,我们需要通过script告诉ant每一步要做什么,同时提供每一步需要的信息。
例如,首先要编译,编译的源代码在哪里,目标代码放哪里等等。
在Maven中我们不需要告诉Maven应该做些什么,仅需要在pom中提供一些必要的信息即可。对于那些在pom中没有提到的信息,Maven就会使用默认值。
例如Maven默认源代码在src/main/java中。因此Maven在最大程度上简化了项目build的过程。)
它包含了可用于大部分项目的默认值。例如,build directory默认使用定义;source
directory,默认使用了src/main/java;test source
directory默认使用了src/main/test等等。
在Maven1中(Maven的早期版本)POM的名字是project.xml,而在Maven
2中改为pom.xml。
(译者:通常认为Maven从1到2发生了根本性的改变,因此尽管可能你使用的Maven是3.x的版本,仍然会发现很多以m2命名的目录。)
同时,以前在maven.xml中包含的goal,plugin等信息现在也被放到了pom.xml中。当执行一个task或goal时,Maven搜索当前目录下的pom文件,从其中取出需要的配置信息并执行goal。
(译者:plugin和goal的概念非常重要,请参考我的另外一篇介绍Maven中的lifecycle的文章。)
另外一些需要在POM中配置的信息是project dependencies,也就是那些需要被执行的plugin或goal,build
profile等等。其他项目相关信息,包括项目版本,项目描述,开发人员列表,邮件列表等等也可以在POM中。
Super POM是Maven的默认POM。所有的POM都继承了super POM。也就是说,所有的POM中的信息都来自于Super
POM,但在子POM中的配置信息会覆盖Super POM中的重复项。
(译者:文中分别写出了Maven2.0.x和2.1.x的super POM的具体内容。这里请参考原文)
最简单的pom.xml
一个最简单的POM文件需要包括的内容如下:
(译者:也就是说,如果想建立一个简单的Maven项目,提供一个如此简单的POM就够了。Maven会自动完成剩下的事情)
project root
modelVersion - should be set to 4.0.0
groupId - the id of the project's group.
artifactId - the id of the artifact (project)
version - the version of the artifact under the specified
具体的例子:
& com.mycompany.app
一个POM必须配置项目的groupId, artifactId, 和version。这三个值构成了项目的fully
qualified artifact name。那就是::。对于上面的例子,fully qualified artifact
name就是“com.mycompany.app:my-app:1”
同时,正如在第一节提到的,如果一些配置信息没有被提供,Maven将会使用默认值。这些默认值之一是packaging
type。如果POM中没有配置它,将会使用默认值jar。
此外,如同你在最简单的POM中看到的,这个POM并没有配置所使用的repositories。
(译者:repository是Maven中的另外一个重要概念,不清楚的同学请参考我的另外一篇关于Maven中repository的文章。)
如果你使用这个POM来build你的项目,它将从Super
POM继承repository的配置。因此,当Maven发现需要下载POM中的dependency时,它会到Super
POM中配置的默认repository,http://repo1.maven.org/maven2去下载。
Project Inheritance
(译者:project inheritance
和下面要提到的project aggregation
是理解项目间POM父子关系的关键,必须理解。)
另外一些可包含在POM中的信息是:
dependencies
developers and contributors
plugin lists (including reports)
plugin executions with matching ids
plugin configuration
其实Super POM就是项目继承的的一个例子。然而你同样可以通过在POM中加入,来引入其他的父POM。
在前面的例子中我们已经引入了“com.mycompany.app:my-app:1”这个项目,现在我们再引入另一个项目“com.mycompany.app:my-module:1”并以此为例,讲述如何让my-app成为my-module的父项目。
& com.mycompany.app
& my-module
同时让它们的目录结构如下:
&|-- my-module
&`-- pom.xml
my-module/pom.xml
指的是my-module这个项目的POM,而pom.xml指my-app的POM。
现在,我们把my-module的POM修改成下面:
com.mycompany.app
&&& my-app
& com.mycompany.app
& my-module
注意现在我们加了一个配置,parent。这个配置允许我们设置哪个项目(artifact)是当前项目的父项目。我们
需要设置父POM的fully qualified artifact
name。配置好之后,my-module的POM就可以从my-app的POM中继承一些配置信息了。
另外,如果我们希望my-module的groupId和/或version与父项目保持一致,我们甚至可以删除my-module的POM中的groupId和/或version。
然而上例是有局限性的。只有当父项目已经安装到local
repository中,或者必须是特殊的文件结构(父项目的pom.xml在子项目的pom.xml的父一级目录里)时,上例才工作。
(译者:我工作的就是类似的父子项目。子项目依赖于父项目。每次修改了父项目的代码后,必须运行:
mvn install
//将父项目编译并加入到repository中
之后才能顺利的运行子项目。)
如果父项目没有安装到local repository中,同时目录结构如下(父子项目在平行的目录结构中)就会有问题:
&|-- my-module
&`-- parent
`-- pom.xml
为了解决这个目录结构(也可以是其他目录结构)导致的问题,我们必须在parent section中使用。
com.mycompany.app
&&& my-app
&&& .../parent/pom.xml
& my-module
如同的字面意思(相对路径),它是module的pom.xml到父pom.xml的相对路径。
Project Aggregation
project aggregation 和project inheritance类似。但与project
inheritance在my-module中设置父POM不同的是,project
aggregation是在父POM中设置my-module。
通过这种方式,父项目在知道它的子模块。同时,如果在父项目上执行Maven命令,父项目和所有的子模块都会执行该命令。
(译者:这就是为什么在Maven的POM中既有父子关系,又有子父关系。)
要使用project aggregation, 必须:
1, 将父POM的改为“pom”。
2, 在父POM中设置子模块的路径。
再次使用之前的pom示例和目录结构,如下:
com.mycompany.app:my-app:1's POM
& com.mycompany.app
com.mycompany.app:my-module:1's POM
& com.mycompany.app
& my-module
目录结构:
&|-- my-module
&`-- pom.xml
如果我们想把my-module加到my-app中,可以简单的讲my-app的pom.xml改为如下:
& com.mycompany.app
在这个修改过的pom中,加入了和。前者的值被设置为“pom”,后者设置为my-module。
的值是从com.mycompany.app:my-app:1的pom到com.mycompany.app:my-module:1的pom的相对路径(在例子中使用module的artifactId,即my-module作为目录名,所以设置的不是module名,而是目录的名字)。
现在,对于my-app运行的任何一个Maven命令(或者说phase或goal),同时也会在my-module上运行。
但是如果我们将目录改为:
&|-- my-module
&`-- parent
`-- pom.xml
父pom应该怎么设置呢?
& com.mycompany.app
&&& ../my-module
答案是,使用和实例三同样的方法,将路径加到中。
Project Inheritance和Project
aggregation的使用
如果你有好几个Maven项目,同时它们有着类似的配置信息,你可以重构你的这些项目,通过将这些相同的配置抽取出来,放到一个父项目中去。
这样,你需要做的所有事情就是让你的Maven项目继承父项目,然后这些共同的配置就会生效了。
同时,如果你有一组项目,它们需要在一起build和process,你可以创建一个父项目,同时将这些子项目配置成父项目的modules。通过这种方式,你只需要build父项目而子项目就都会build了。
(译者:例如我工作的项目,多个项目,比如项目A,B,C共享同样的核心代码。采取的方式就是将核心代码抽取出来做成一个父项目称为core,将)这些项目配置为父项目的modules。
可以通过build
core项目,就build了所有的modules。
但有时也需要变通一下:当运行比如A项目的daily
build时,我们并不需要build所有的项目。这时的做法就是,对于core项目,实际有4个pom文件:
pom.xml, A_pom.xml, B_pom.xml,
C_pom.xml。当运行A的daily
build时,实际在build环境中使用的是A_pom.xml。同时该pom文件中,core的子模块只有A一个。
另外需要注意的一点是:如何build的问题
例如我前面提到的我工作的项目,如果修改了core中的代码,并想重新build项目A时,有三种方法。
<span STYLE="color:#,在core项目上运行mvn build。这样core, A, B,
C4个项目都会被build。
<span STYLE="color:#,如果只想build项目A,就用A_pom.xml覆盖core的pom文件,然后运行mvn
build。则会build项目core和A。
<span STYLE="color:#,或者,对core项目运行mvn
install(该命令会编译,build并将build出来的jar包安装到repository中去), 之后再在A项目运行mvn
但是,当然了,你也可以同时使用项目集成和项目继承。意思是,你可以在子项目的pom中配置parent,同时在父项目中配置modules。你只需要明确下面3个规则:
1, 在每一个子项目pom中都要配置parent。
2,将父项目pom的packaging改为“pom”。
3,在父pom中配置子modules。
(译者:到此项目间的关系已经讲完了,让我们来总结一下:
当我们拿到了几个相关项目时,一定要先搞清楚这些项目间的父子关系。我们不仅要考察每一个项目的pom文件,弄清楚他们之间的集成和继承关系,也需要留意项目的目录结构,以防止有些设置并没有生效。
只有弄清楚了项目的关系,我们才能正确的使用Maven的功能)
(译者:原文中还有一个示例五,是关于将上面3点都融合在一起的pom文件,我觉得没有必要再累述了。)
(另外需要说明的一点,如果打开本地的repository,你会发现每个artifact(通常是jar包)也有自己的pom文件。其实原因很简单:Maven也要管理这些artifact。比如类库A,同时也依赖于类库B,C。
因此repository中的artifact也需要pom文件来说明它们之间的关系)
项目的插入值和变量
Maven鼓励的一种做法是,不要自我重复。然而,有时候还是需要在几个不同的地方使用相同值。为了保证仅在唯一的地方定义值,Maven允许你在pom中使用你自己定义的变量。
例如,为了在pom几个不同的地方使用相同的值,project.version,你可以这样做:
${project.version}
同时,在pom文件中定义:
&&& &&span
style="color:#000000"&version&1.0.4&&tt&/version&
需要注意的是,这些变量是在继承机制生效后赋值的。这意味着,如果一个父项目pom包含变量,这些变量会被子项目继承并可以在子项目中直接使用。
这里有三种可使用的变量:
Project Model Variables
所有在pom中的独立的element都可以作为一个变量。例如${project.groupId},${project.version},${project.build.sourceDirectory}
等等。参考POM reference来得到所有的properties。
所有这些变量使用时都应加上前缀"project."。你也可能看到一些以“pom.”为前缀的情况,但是已经不赞成这么做了。
Special Variables
The directory that the current project resides
project.baseUri
The directory that the current project resides in,
represented as an URI.Since Maven 2.1.0
maven.build.timestamp
The timestamp that denotes the start of the build.
Since Maven 2.1.0-M1
对于build timestamp的格式问题,可以通过指定,如下:
yyyyMMdd-HHmm
日期格式需要遵守的规则可以参考
SimpleDateFormat(java的)的API文档。如果没有设置这个值,则使用上例中的默认值。
最后一种就是前面提到的,不累述。
原文到此结束,但我还想加一点关于POM中的dependency的内容。
dependency描述了当前项目对其他项目的依赖关系。如下例,表示当前项目依赖于log4j
artifact(并非父子关系)。
&&&&&&&log4j
同样我们使用的很多第三方工具,如JUnit等等,都需要使用dependency加入到项目的POM中(当然也可以使用项目继承的方法,从父项目继承)。
在eclipse中使用Maven插件时,可以使用图形化界面添加dependency。过程是:
1,点击添加dependency。
2,输入名字,如JUnit。此时Maven插件会到使用的remote repository中搜索相应的类库。
3,搜索到以后,点击希望添加的artifact,确定。此时POM文件已经被修改了,加入了新增的dependency。
4,点击保存。这时Maven就会开始从remote repository下载artifact。
如果没有按照Maven插件,另外一种方法就是直接修改pom.xml,加入dependency部分。保存后Maven即开始下载artifact。
不过这里有一个问题,直接修改pom.xml时,往往不知道要添加的类库的完整名称, 即::,进而也不知道该怎么填
写等内容。
这里有一个方法,下面的网站是browse repository的:
使用方法类似:搜索后,找到想要的类库,然后就能看到对应的&的内容。直接将该段xml复制到自己的pom.xml中就可以了。
关于POM,可以参考http://maven.apache.org/pom.html 得到更详细的解释。
看完了Maven中的几个重要概念一,二和三,相信对Maven已经有比较全面的了解了。
这个时候开始看Maven的完全参考手册就会非常轻松了。
----------------------------
首先是Maven的官网guide,包含了相当多的内容。有时间的时候应该全部浏览一遍。
参考原文:
http://maven.apache.org/guides/introduction/introduction-to-repositories.html
在Maven出现之前,如果我们希望在自己的程序中使用第三方类库,需要怎么做呢?
首先,得到这个类库的jar包。可以从官网上下载,也可以从别的地方copy过来。
然后把这个包import到IDE中的JRE System Library中,就可以开始使用了。
不算复杂,但使用Maven更简单。你只需要告诉Maven,我需要用某个类库,就OK了。
Maven将自动去获取你需要的这个类库,从哪?repository。
A repository in Maven is used to hold build artifacts and
dependencies of varying types.
repository只有两种:local and
remote。所以当你告诉Maven要使用某类库时(即当一个项目声明要使用一个dependency),Maven做的事情就是:
从它在网络上的远程repository 找到这个类库,下载到你本地的repository(默认在c盘
....m2repository)中。
如果Maven发现你本地的repository已经有这个类库,那就什么都不做。
因此,remote
repository包含了相当丰富的流行的类库/框架/工具。如果你需要使用某个很偏门儿的类库,那么,通常还是只能用老方法,自己去下载先。
下载后可以在命令行中运行mvn install,将类库安装到自己本地的repository中去。
远程repository有两种,一种是由公共组织提供的:
a third party to provide their artifacts for downloading (for
house Maven's
central repository).
我们通常都会使用这些repository。这些repository有两个问题:
1,网络问题。例如你所在的环境没有网络。或者公司对互联网访问有限制,导致你无法访问到。
2,由于Maven已经相当流行,有时这些repository服务器会因为负载过高而出现问题。
默认情况下,会去默认的repository 下载artifact。
http://repo1.maven.org/maven2/
(从前提供了browse的功能,但是现在被禁止了)
如果不想使用这个默认的repository,可以在settings.xml中使用mirrors来指定别的。但是在POM中可以指定使用的repository所以这个设置可能被覆盖。
(关于settings.xml,可以参考 。个人认为要必要把这个也好好看看。)
另一种可以是公司自己搭建的,用于公司内部人员共享的repository。这样通常就不会有网络和负载的问题了。
文章最后讲述了如何搭建internal repository。有兴趣的同学自行参考。
需要说明的一点是:
Such an internal repository can be downloaded from using HTTP or
the file system (using afile:// URL), and uploaded to
using SCP, FTP, or a file copy.
Note that as far as Maven is concerned, there is nothing special
about this repository: it is anotherremote
repository that contains artifacts to download to a user's
local cache, and is a publish destination for artifact
因此repository没有什么特别,它可以是任何一个文件系统,上传和下载可以使用多种协议。
但需要使用repository manager来搭建一个repository server。
http://maven.apache.org/repository-management.html
讲述了3种repository manager工具,及其作用。
最后再提一下关于settings.xml。有两种settings.xml:
The Maven install: $M2_HOME/conf/settings.xml
A user's install: ${user.home}/.m2/settings.xml
第一个settings.xml,也称为global settings。第二种,也称为user
settings。这里有一点及其重要的!不论是global settings还是user
settings,settings.xml都不会被自动创建。
例如,你现在想把local repository放到一个你自己指定的地方,而不是默认的地方,就可以创建一个user
settings,同时在其中指定你需要的位置。
创建方法很简单,到官网上copy一个例子,并修改相应的内容就可以了。user settings中的配置优先级更高。
原文:http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
当我们在使用Maven做一些工作,如打包,编译,运行测试等等任务时,我们已经使用到了Maven中的几个重要概念:
lifecycle, phase and goal。
例如,如果我们使用ant打包,我们需要清晰的在脚本中告诉ant:
源代码在哪,打包的目标文件类型如jar,目标文件夹在哪。首先要编译,然后运行测试,最后打包。
而Maven为了在最大程度上简化我们的工作,因而定义了lifecycle, phase and
goal。我们仅仅需要简单的运行:
mvn package(package是一个phase), 包就自动打好了。
而实际上,mvn
package这个命令会运行以下6个步骤(左边这列是步骤名,同时也是phase的名字,右边是对应的goal):
process-resources
resources:resources
compiler:compile
process-test-resources
resources:testResources
test-compile
compiler:testCompile
surefire:test
因此使用Maven打包时,用到的信息和步骤一点都不比用ant少,只不过使用到的信息,定义在了POM文件中(本文并不涉及);而步骤定义在了lifecycle,
phase and goal中。
也就是说,Maven定义了一系列的best
practice。
在这里,对与打包这个任务,我们仅需要使用Maven中已经定义好的这些best
practice,就能简单的完成日常工作了。
下面我们首先介绍这些best practice,也就是定义好的lifecycle, phase, goal。
之后介绍如果我们不想使用best
practice,比如,我们想在打包时,在上面的test-complie(这个步骤仅编译测试代码,但不会运行测试用例)之后,运行测试。同时,还希
望能使用一个第三方工具检查测试用例的代码覆盖率,并形成一个报表。也就是说,我们希望在打包结束时,同时得到一个测试代码覆盖率的报告,应该怎么做。
There are three built-in
build lifecycles: default, clean and
有三种内置的build lifecycle:The default lifecycle
handles your project deployment, the clean
lifecycle handles project cleaning, while thesite
lifecycle handles the creation of your project's site
documentation.
Each of these build
lifecycles is defined by a different list of build phases, wherein
a build phase represents a stage in the
lifecycle.
For example, the default lifecycle has the following build
phases (这里并不包含所有的phase,只是举例):
1,validate - validate the project is correct and all
necessary information is available
2,compile - compile the source code of the
3,test - test the compiled source code using a suitable
unit testing framework. These tests should not require the code be
packaged or deployed
4,package - take the compiled code and package it in
its distributable format, such as a JAR.
5,integration-test - process and deploy the package if
necessary into an environment where integration tests can be
6,verify - run any checks to verify the package is
valid and meets quality criteria
7,install - install the package into the local
repository, for use as a dependency in other projects
8,deploy - done in an integration or release
environment, copies the final package to the remote repository for
sharing with other developers and projects.
执行一个phase将会执行这个lifecycle前面的所有phase。
下面这个例子执行了clean lifecycle和default
lifecycle到install为止的所有phase。
mvn clean install
Phase is made up of goals
However, even though a build phase is responsible for a specific
step in the build lifecycle, the manner in which it carries out
those responsibilities may vary.
And this is done by declaring the goals bound to those build
A goal represents a specific task (finer than a build phase)
which contributes to the building and managing of a
也就是说,执行phase实际执行的是goal。如果一个phase没有绑定goal,那这个phase就不会被执行。
一些phase默认已经绑定了一些goal。对于default lifecycle来说,
这些被绑定的goal并不完全相同,而是和packaging value相关。所谓的packaging value就是
jar//这个很好理解,对于不同的包类型,打包的过程不尽相同,因此需要执行的goal也不同。
一个goal是独立的,它可以被绑定到多个phase中去,也可以一个phase都没有。如果一个goal没有被绑定到任何一个lifecycle,它仍然可以直接被调用,而不是被lifecycle调用。
因此可以这样理解phase与goal的关系:
phase其实就是goal的容器。实际被执行的都是goal。phase被执行时,实际执行的都是被绑定到该phase的goal。
goal与goal之间是独立的。因此单独执行一个goal不会导致其他goal被执行。
下面的例子
dependency:copy-dependencies package
clean是phase。
dependency:copy-dependencies是plugin-in dependency 的goal
copy-dependencies。
package也是一个phase。
maven会顺序执行这3个对象中包含的所有goal。
另外一种将goal绑定到phase的方法就是在project中使用plugin。即在POM中配置。
Plugins are artifacts that provide goals to
Maven. Furthermore, a plugin may have one or more goals
wherein each goal represents a capability of that plugin.
这里我们先思考一个问题,goal的本质是什么?
例如我们上面提到的需要,希望在打包时得到一个测试代码覆盖率的报告。
实现的方法就是:
1,将计算代码覆盖率的工具,例如cobertura,安装到Maven的repository中。此时cobertura就是一个plugin。
最简单的方法就是将cobertura加到项目的dependency中就行了。Maven会自动去网上的公共repository中下载项目依赖的的dependency到本地的repository中。
2,修改POM文件(可参考下面的pom的例子),将这个plugin,连同要执行的goal,加到package这个phase中去。
由于现在Maven已经非常流行,所以这些工具的官网上都会提供在Maven中使用该工具时,应使用什么命令。
参考cobertura网站,我们可以知道对于这个工具,对应的命令是:
mvn cobertura:cobertura (即phase和goal的名字都是cobertura)
3,此时再运行mvn package,就会运行cobertura这个plugin的goal,也就是cobertura。
之后我们就会在默认的位置找到生成的报表。
因此,goal其实是由存在于Maven的repository中的plugin提供的一个个小的功能程序。
它是Maven的lifecycle以及phase的基本组成元素。同时,我们也可以通过将各种各样的goal加入到Maven的phase中,从而根据自己的实际需求,灵活实现各种定制功能。
下面是一个更general的例子,该POM中展示了,如何将display-maven-plugin中的goal
time绑定到process-test-resources这个phase中。
&& com.mycompany.example
&& display-maven-plugin
process-test-resources
通过前面的例子我们明白,完全可以自行开发一个java程序,作为goal绑定到phase中后执行。
但Maven对嵌入到它之中的plugin有一些标准,在开发程序时需要遵循。
下面链接中列出了主要的Maven plugin。
http://maven.apache.org/plugins/index.html
同时关于plugin还可以参考下面链接中的plugin文档,得到更详细的解释。
http://maven.apache.org/guides/index.html
-----------------------------------
基本上运行maven有两种形式:
1,Maven&phase name
比如:Maven Build--Build是一个phase。
2,Maven plug-in:goal
比如:Maven assembly:assembly 指运行assembly plug-in 中的assemly
在运行Maven项目时经常可以看到大量的类似信息:
[INFO] &&& maven-assembly-plugin:2.2:assembly
(default-cli)
//这里的插件全称是maven-assembly-plugin&2.2是版本号?
assembly&是goal
//嗯,回头还得再扫一眼maven。(default-cli) @&project
name&不知道是啥。
[WARNING] The POM for opensymphony:quartz-all:jar:1.6.3 is missing,
no dependency information available
[INFO] --- maven-resources-plugin:2.4.3:resources
(default-resources) @ name---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 12 resources --后面紧跟这个插件的运行结果。
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @
[INFO] Nothing to compile - all classes are up to date
[INFO] --

我要回帖

更多关于 https status failed 的文章

 

随机推荐