Jenkins Solutions

==========================================================

Jekins
—————————————————————————————————-
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的界面了。
其他也需要安装的是:
1,Jenkins是java程序,因此需要安装JDK。
2,同时运行job需要提供repository,也就是存放Jenkins定期poll源代码的地方。我们可以去github免费注册一个。
3,如果想在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)
+- jobs
+- [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)
+- builds
+- [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的目录就好了:
All the 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 up.

移动/拷贝/重命名 job

由于每个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 URL:
http://YOURHOST/jenkins/job/PROJECTNAME/build

Distributed builds
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 overhead.
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 Console
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” link。
也可以通过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

Jenkins 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目录的说明:
You can 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 home
我在脚本里,或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 executed.
比如在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配置参数是很让人崩溃的。


jenkins邮件配置
分类: 系统配置 2013-03-22 14:50 4621人阅读 评论(1) 收藏 举报
jenkins自带的邮件管理太弱了,为了能按自定义的方式发送邮件,需要安装一个插件: Jenkins Email Extension Plugin。

1.配置邮件:通过“系统管理”-“系统设置”,进行系统设置界面,上面的内容在“使用Jenkins配置自动化构建”中已经讲过,直接移动到设置页面的最下面,“邮件通知”部分,设置上“stmp服务器“和”用户默认邮件后缀“,如图:

如果成功安装了Jenkins Email Extension Plugin,在邮件通知的上面还有

到这里,系统级的邮件设置已经完成了。
2. 创建一个测试的自动构建项目,如svnTest
其他部分不说了,只说邮件部分,点”Add posts-build action“,选择”Editable Email Notification“,出现下面的界面:

这些内容都可以根据你的需要进行修改。
3. 完成之后,点”立即构建“看看是不是成功,如果成功了,就大功告成了。如果不成功,那就慢慢的调了^_^。
有一个地方要注意:如果配置的邮件服务器是stmp.126.com,好像就只能发送邮件到126邮箱,这个我配置的是这样,不知道是不是全部是这样。


Jenkins 邮件配置 (使用 Jenkins Email Extension Plugin)
本文主要对 jenkins 的邮件通知进行介绍,
jenkins 内置的邮件功能
使用插件扩展的邮件功能
1. 先介绍下 基本的Jenkins 邮件服务器 配置
1)system config 页面 (以公用的163邮件服务器为例):

可以勾选 “通过发送测试邮件配置” 测试此配置能否连通, 如果收到以下邮件,恭喜

This is test email #1 sent from Jenkins
 
2)下面接着对构建的job 添加邮件发送的步骤,

这样每次build后都会发送邮件给这个接收者, 到这里你会发现,只能发给 固定的对象,且格式单一(txt)

====好了,现在进入主题====

  1. 使用插件 “Email Extersion Plugin”进行扩展
    它可根据构建的结果,发送构建报告,给当前的committer (用git做代码管理)
    1) 该插件支持jenkins 1.5以上的版本,至少我的 1.486是不支持的啦。所以果断升级吧。。
    插件的安装此处略 ,若您可选插件的页卡的列表是空的,先去高级页面检查更新下。
    2)插件用于job配置页面,添加构建后步骤“Editable Email Notification”

    上面的配置 给出了 该工程的默认接收列表,当然抄送的话 直接 可以这么写 cc:[email protected]
    对于内容,你也许注意到了 这里调用了个 ‘html.jelly’ 的模板,这是插件内置的,直接用即可。(支持git每次变更的记录,mvn 及junit 等编译的结果报告)
    当然也可以自己写 jelly文件, 确保放置 jenkins/home/email-template下 以供jenkins调用。

    3)至此你也许会问 这不还是用的固定的接收列表嘛 (⊙_⊙) ,别着急 看到右下角的高级选项没, 继续配置,

    我设置了 build成功和失败都发给 默认的接收者和当前提交代码的家伙,而send to requester 是指手动触发构建时当前登陆jenkins的用户。

ps:
1. 如果有人 git commit时候没有进行global的name和email设置,将不会发送到正确的邮箱(jenkins将按各自的机器名作为域名地址发送到错误的邮箱)

     2. 当然还可在jenkins 管理用户中 个别设置 邮箱。不过对于团队较多的话,你就苦了。 所以还是有必要请大家提交前进行实名设置。

http://www.cnblogs.com/GGHHLL/p/jenkins.html

http://blog.csdn.net/yanmingming1989/article/details/8557716
**Linux 环境下搭建 Jenkins(Hudson)平台
分类: CI 2013-01-30 21:38**

安装jenkins:
安装 jenkins 有两种方式:
安装方式一:
[java] view plaincopy
sudo java -jar jenkins.war –httpPort=18080 –ajp13Port=18009
但 是很多时候我们是使用SSH方式到目标机器上的,放我们关闭SSH连接时,这个命令也会被中断,jenkins服务会被终止,我们不可能一直保持这SSH 连接,怎么办?可以把这行命令写成 shell 脚本,然后使用 nohup sh jenkins.sh &
命令启动这个脚本,这样jenkins就能正常提供服务了。
安装方式二:安装 RPM包
为了能够使用jenkins库,首先需要导入jenkins库的 key:
[java] view plaincopy
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
开启服务(关闭,重启):
[java] view plaincopy
sudo service jenkins start|stop|restart
检查jenkins是否安装完成: localhost:8080 (默认是8080 端口,如果采用安装方式一,那么就需要指定的端口)
运行job时遇到的问题:
mvn:command not found
遇到的问题: 不能使用MVN命令;
排查过程:
①Jenkins 默认创建进程,启动任务的用户名是 jenkins,使用root权限查看passwd,可以看到这个用户默认情况下 ssh 为false,也就是说这个用户默认情况下是不能使用ssh进行登录的,除非修改 passwd中相应字段为 bash,然后sourse;
jenkins:x:500:500:mengqc:/home/jenkins:/bin/fasle
passwd文件的格式: 注册名:口令:用户标识号:组标识号:用户名:用户主目录:命令解释程序
②默认情况下 Jenkins 的安装目录是 /var/lib/jenkins/ ,项目根目录是 /var/lib/jenkins/jobs/workspace
从目录上看,就知道这个是需要 root 权限才能执行一些命令,但是我们通过界面 执行一些命令使用的是admin用户,纵使我们在 根目录下 能适应mvn命令,但是问题也不能解决。
还有一个简单的测试Maven 是否加入到了环境变量中的方法,在执行mvn命令时,填写maven安装的绝对路径,如果能够执行,说明不是权限的问题,而是环境变量的问题。

解决方案一:
①安装 ssh slave 插件;
②启动slave 服务;
③jenkins-系统管理-节点管理:重新设置 slave机器的 Remote FS root 为 /home/admin/xxx
(主要是添加了workspace的目录) $ITEM_ROOTDIR
④把master的节点数设为0,这样默认情况下就会使用 slave节点。
问题:
如果修改 工作目录(Remote FS root),可能会遇到:
[java] view plaincopy
“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
①安装jenkins
Java代码 (我们一般使用的是admin权限)
[java] view plaincopy
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

②. 配置jenkins
Java代码
// edit JENKINS_PORT, JENKINS_USER
sudo vi /etc/sysconfig/jenkins (把 JENKINS_USER 设置为 admin)
③. 修改jenkins权限(如果修改JENKINS_USER情况下)
Java代码
[java] view plaincopy

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)

④. 启动jenkins
Java代码
sudo /sbin/service jenkins start
或者 sudo service jenkins start


http://www.51testing.com/html/87/300987-815659.html
Linux安装Jenkins手册
一、前期准备工作
因为我是在Windows系统上连接Linux服务器以及需要把在Windows系统下载的安装包上传到Linux系统,所以需要用到两个工具—putty和FileZilla。
Putty是一个免费的、Windows 32平台下的telnet、rlogin和ssh客户端,但是功能丝毫不逊色于商业的telnet类工具。 用它来远程管理Linux十分好用。
FileZilla是一种快速、可信赖的FTP客户端以及服务器端开放源代码程式,具有多种特色、直觉的接口。
这两款工具都是免安装的,使用非常方便。

二、卸载和安装LINUX上的JDK
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
# rpm -e java-1.4.2-gcj-compat-l.4.2.0-27jpp

卸载其他自己安装的JDK就直接用rpm -e
卸载rpm版的jdk:
#rpm -qa|grep jdk
显示:jdk-1.6.0_10-fcs
卸载:#rpm -e –nodeps jdk-1.6.0_10-fcs

2.2安装JDK
去http://www.oracle.com/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服务器上,在shell下执行命令:
注:我的jdk安装包放在home目录下
[root@testdep home]# chmod 755 jdk-6u32-linux-i586-rpm.bin
[root@testdep home]# ./ jdk-6u32-linux-i586-rpm.bin

这时会有一段Sun的协议如下
准备中… ######################################## [100%]
1:jdk ######################################## [100%]
Unpacking JAR files…
rt.jar…
jsse.jar…
charsets.jar…
tools.jar…
localedata.jar…
plugin.jar…
javaws.jar…
deploy.jar…

Java(TM) SE Development Kit 6 successfully installed.

Product Registration is FREE and includes many benefits:
* Notification of new versions, patches, and updates
* Special offers on Oracle products, services and training
* 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 browser.

For more information on what data Registration collects and
how it is managed and used, see:
http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html

Press Enter to continue…..

Done.
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=.: JAVAHOME/lib/dt.jar: JAVA_HOME/lib/tools.jar
[root@ testdep home]# export PATH= PATH: JAVA_HOME/bin
当然这样设置环境变量是可以生效的,但是只对当前shell生效。如果从另外一个shell登陆,将不能使用刚才设置的变量。所以最好的方法还是修改.bashrc文件。
我用下面这个
cd ~ .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
export CLASSPATH=.: JAVAHOME/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 mode)

2.5测试环境变量是否安装成功
环境设置OK,看看JDK是否能正常工作,我们来写一个测试文件test.java
[root@LinuxServer rpm]#vi test.java
class test
{
public static void main(String[] args)
{
System.out.println(“Hello World!”);
}
}

保存退出,下面来编译、执行;
[root@testdep home]# javac test.java
[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
export CLASSPATH=.: JAVAHOME/lib/dt.jar: JAVA_HOME/lib/tools.jar
export CLASSPATH

2.7 至此,Linux上JDK的安装完毕。

三、在Linux下配置Tomcat服务器
Tomcat是一个免费的开源的Serlvet容器,它是Apache基金会的Jakarta项目中的一个核心项目,由Apache,Sun和其它一些公司及个人共同开发而成。由于有了Sun的参与和支持,最新的Servlet和Jsp规范总能在Tomcat中得到体现。
  Tomcat是稳固的独立的Web服务器与Servlet Container,不过,其Web服务器的功能则不如许多更健全的Web服务器完整,如Apache Web服务器(举例来说,Tomcat没有大量的选择性模块)。不过,Tomcat是自由的开源软件,而且有许多高手致力于其发展。
3.1安装jdk
在安装Tomcat之前需要安装j2sdk(Java 2 Software Development Kit),也就是JDK。
请参考第一部分卸载和安装LINUX上的JDK。

3.2下载tomcat
在http://tomcat.apache.org/download-60.cgi 下载tomcat6.0,
[转载]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 .bashrc
//在第一步卸载和安装Linux JDK设置jdk的路径后面加上tomcat的路径
//vi编辑器的使用方法请大家百度一下
export 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.sh;
//正常情况下可以见到如下的信息:
Using CATALINA_BASE: /usr/local/tomcat
  Using CATALINA_HOME: /usr/local/tomcat
  Using 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.sh;

四、在Tomcat里边配置Jenkins
4.1 在http://mirrors.jenkins-ci.org/war/1.466/下载Jenkins的war包。
4.2 通过FileZilla把刚下载的Jenkins包从本机PC上传到Linux服务器的webapps目录下。
[root@testdep home]cd /usr/local/tomcat/webapps
[转载]Jenkins Solutions我来了
可看出刚刚上传的jenkins war包。

4.3 Jenkins安装完成,可以通过本地PC连接上Linux上的Tomcat服务器。
在本地PC的浏览器窗口输入: http://192.168.3.182:8080/jenkins/

4.4 至此Jenkins的配置安装完成。
五、Jankins的相关配置
5.1 首次进入Jenkins的主页面会出现如下截图所示的错误提示:
[转载]Jenkins Solutions我来了
意思是tomcat容器没有使用UTF-8编码,所以不能使用中文作为任务名称,可以在tomcat中进行配置。
[root@testdep home]# cd /usr/local/tomcat/conf
[root@testdep home]#vi server.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用法)
1. Jenkins1.455
2. 系统Suse
3. Tomcat 6.0.37
4. Java 1.6.0_26
5. patch-parameter
【API介绍】
Jenkins提供了html、json、python API,实质都是以http get/post方式调用的。查看http://www.xxx.xxx/jenkins/api/ 即可得到相应的说明,如图:
持续集成Jenkins API常见用法
【API实践】
1.创建
curl -X POST http://www.xxx.xxx/jenkins/createItem?name=JavaStd –user peterguo:peterguo –data-binary “@javastd.config.xml” -H “Content-Type: text/xml”
2.禁用
curl -X POST http://www.xxx.xxx/jenkins/job/JavaStd/disable –user peterguo:peterguo
3.启用
curl -X POST http://www.xxx.xxx/jenkins/job/JavaStd/enable –user peterguo:peterguo
4.删除
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 “[email protected]
注:带补丁触发需要先安装补丁插件,并设置项目的补丁参数
持续集成Jenkins API常见用法
【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


config.xml of Jenkins

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 Jenkins.
SCM user
(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: in
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
Trigger

portfolio controller builder-maven , publishers:ant merge.results
portfolio package:builder-ant target:portfolio.packaging。 publishers没有。

每个job下面都有一个workspace,里面有hudson_migration需要的所有ant脚本。
同时 workspace/trunk下 对于一个项目有两个文件:
portfolio
portfolio_pom.xml

https://sami.cdt.int.thomsonreuters.com/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.

Maven

当我们在IDE中开发时,经常需要使用maven。现在流行的java的IDE有eclipse,intellij等等。对于maven而言,我们可以将IDE分为两类:
1,Eclipse等和maven结合的不够紧密的IDE。
Eclipse和Maven结合的并不算好,如果在eclipse中想使用maven,需要安装插件:m2e
安装该插件之后,你才能在eclipse中看到关于maven的菜单,并且可以创建maven项目,执行maven goal等。

为了在命令行中使用maven,我们往往会在本地再单独安装一个maven。这样就会有一个问题:eclipse中运行maven goal时,即可以选择使用embedded maven,也可以选择单独安装的maven。如下:

为了在命令行中使用maven的效果和在eclipse中执行maven goal的效果一致,建议在eclipse中选择单独安装的maven而不是内嵌的maven。

2,Intellij,Netbeans等较为紧密的IDE。
在intellij这类IDE中,不需要单独安装maven插件了。我们还是需要自己安装maven,同时也可以配置所使用的maven(默认是按环境变量M2_HOME):

在导入一个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包。
[html] view plaincopy

maven-jar-plugin

Junit

Git/GitHub

SVN

java打包

jar包
http://docs.oracle.com/javase/tutorial/deployment/jar/basicsindex.html

The Java™ Archive (JAR) file format enables you to bundle multiple files into a single archive file. Typically a JAR file contains the class files and auxiliary resources associated with applets and applications.
jar使用的是zip压缩技术,我们也可以选择不压缩。
基本命令
基本的打jar包的命令很简单:
jar cf test.jar input-file(s)
cf的意思是打一个jar文件。其他参数请自己查询。
test.jar是指定的jar文件的名字。
input-file(s)是 指定哪些文件应该被包括到jar中去。通常是代码编译后产生的class文件。另外如果代码中引用了其他类库,也就是jar包。我们可以一并和源代码打到 一个jar包里,这样运行时,一个jar包就够了。如果选择仅将源代码打进jar包,则在程序运行时,还必须将需要的类库放到合适的地方并加入 classpath中。
manifest 文件
执行完上面的命令后,就生成了一个jar包。如果我们解压这个jar包,可以看到这样一个文件:
META-INF/MANIFEST.MF,内容是:
Manifest-Version: 1.0
Created-By: 1.7.0 (Oracle Corporation)
这是自动生成的manifest文件。
此时如果运行:
java -jar test.jar
将会返回:
Failed to load Main-Class manifest attribute from test.jar
程序无法运行,因为java不知道程序的入口在哪。
Main-Class header in manifest file
通过在manifest file中指定Main-Class属性,就可以告诉程序入口了。有两种方法:
1,手工修改mafifest file。
We first create a text file named Manifest.txt with the following contents:
Main-Class: MyPackage.MyClass
然后运行:
jar cfm MyJar.jar Manifest.txt MyPackage/*.class
m的意思是使用一个已有的manifest文件。此时java -jar MyJar.jar就可以工作了。
2,使用参数e
jar cfe app.jar MyApp MyApp.class
参数e将manifest文件中的Main-class设置为:MyApp 。这样就不用手工修改文件了。

另外说一下引用第三方类库的问题。前面说了,可以将java代码依赖的第三方类库一并打包进一个jar文件,也可以只将java代码放进jar文件,在程序运行时再另外指定classpath。
对于第二种方式,manifest文件中,还有一个属性,class-path。使用这个属性,我们就可以直接指定classpath了,而不是在每次运行的时候麻烦的单独指定。
注意,这种方式有以下限制:
The Class-Path header points to classes or JAR files on the local network, not JAR files within the JAR file or classes accessible over internet protocols. To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes. For example, if MyJar.jar contains another JAR file calledMyUtils.jar, you cannot use theClass-Path header inMyJar.jar’s manifest to load classes inMyUtils.jar into the class path.

例如,MyApp.jar在运行时需要一个MyUils.jar。首先造一个manifest文件,加入以下内容:
class-path: directory-name/MyUils.jar
和前面一样,运行jar cfm,使用已有的manifest文件生成jar文件,该jar文件仅包含MyApp的class文件:
jar cfm MyJar.jar Manifest.txt MyPackage/*.class
然后MyApp.jar就可以直接运行,而不必指定classpath了:
java -jar MyApp.jar

我们还可以在manifest文件中指定package的版本:
http://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html

对于第一种方式,即在运行时指定classpath:
java -cp CLASSPATHmainclass {CLASSPATH} 不能使用类似/folder/* 这样来指定将一个目录下的所有jar包都加到class-path中,注意下面的话:
For a .jar or .zip file that contains .class files, the class path ends with the name of the .zip or .jar file

因此只能是这样的:
CLASSPATH=” codeHome/lib/commonscollections3.2.1.jar: codeHome/lib/commons-io-2.0.jar:$codeHome/lib/saxon-xpath-8.7.jar”
但如果要运行的程序的是.class文件而不是jar包时,classpath可以直接指定成目录:
CLASSPATH=.;D:JAVALIB;C:DOCJavaT
java解释器会去目录search class文件
CLASSPATH contains one or more directories that are used as roots in a search for .class files. Starting at that root, the interpreter will take the package name and replace each dot with a slash to generate a path name off of the CLASSPATH root (so package foo.bar.baz becomes foobarbaz or foo/bar/baz or possibly something else, depending on your operating system). This is then concatenated to the various entries in the CLASSPATH.

There’s a variation when using JAR files, however. You must put the actual name of the JAR file in the classpath, not just the path where it’s located. So for a JAR named grape.jar your classpath would include:
CLASSPATH=.;D:JAVALIB;C:flavorsgrape.jar

最后,由于现在maven在广泛使用,因此很少直接用jar命令去打包了。关于如何用maven打包,请参看我的另外一篇文章Maven的使用经验(二)–打包




http://blog.sina.com.cn/s/blog_626341eb0102vlmw.html

你可能感兴趣的:(笔记)