浮生参半 发表于 2018-11-27 09:44

申请会员ID: Lming·Xie

1、申 请 I D: Lming丶Xie

2、个人邮箱:1611826890@qq.com
3、原创技术文章:16年开始学习Java技术,现在是一名java后台开发人员,参与工作时间不长,不过也有写过一些文章,今天分享一片关于Jenkins插件开发的文章,在CSDN上已发布。
4、加入吾爱的目的:1.吾爱资源丰富,有我当下可以学习的很多东西; 2.有能力编写一些文章,为吾爱做出一定贡献;3.最重要的还是吾爱环境好,大神多。


首先作为一名java后台开发人员,当下必备的技术应该会有Docker的k8s了,而其中Jenkins 的自动化部署也是很热的技术,之前在公司有需求需要将已有的系统集成jenkins,所以呢才有了下面的
Jenkins开发,遇到了很多坑,在下也初略的整理了一下,废话不多说上流程(绝对是本人原创的哦!):
CSDN链接:https://mp.csdn.net/postedit/81116455

一、环境依赖
JDK版本要求在1.6以上,Maven官方要求版本在3以上,此处本人使用的是JDK1.8 maven3.5.2
https://img-blog.csdn.net/20180719153341542?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​环境
然后呢就是你maven的 setting.xml(此setting文件直接放在了C:\Users\xie_7\.m2下)文件要变成这样:
<?xml version="1.0" encoding="UTF-8"?><settings><!-- 指定本地仓库的存放地址,可选 --><localRepository>E:\Jenkins\jar</localRepository> <!-- 下面的东西都不用管知道不,只需要copy就ok --><pluginGroups>    <pluginGroup>org.jenkins-ci.tools</pluginGroup></pluginGroups><profiles>    <!-- Give access to Jenkins plugins -->    <profile>      <id>jenkins</id>      <activation>      <activeByDefault>true</activeByDefault> <!-- change this to false, if you don't like to have it on per default -->      </activation>      <repositories>      <repository>          <id>repo.jenkins-ci.org</id>          <url>http://repo.jenkins-ci.org/public/</url>      </repository>      </repositories>      <pluginRepositories>      <pluginRepository>          <id>repo.jenkins-ci.org</id>          <url>http://repo.jenkins-ci.org/public/</url>      </pluginRepository>      </pluginRepositories>    </profile></profiles><mirrors>    <mirror>      <id>repo.jenkins-ci.org</id>      <url>http://repo.jenkins-ci.org/public/</url>      <mirrorOf>m.g.o-public</mirrorOf>    </mirror></mirrors></settings>data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
安装:去https://jenkins.io/官方下载jenkins的通用war包:
https://img-blog.csdn.net/20180719155358114?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​Jenkins下载
下载可能会很慢,完了之后呢,就把它网自己喜欢的地方copy,然后直接使用java -jar 运行就行,不过在这里需要重点提到的是Jenkins的工作目录默认是在 当前系统用户目录下的.jenkins目录下,这个一定得记住,当然你可以通过配置 JENKINS_HOME 环境变量来进行更改:
https://img-blog.csdn.net/20180719160325890?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​配置 JENKINS_HOME

二、插件开发    1.创建 插件程序
    好了,关于Jenkins的使用怎么就不去做过多解释了,网上多得是,此处阅读推荐:
    https://blog.csdn.net/shuizhihun07/article/details/80168076
    要开发插件首先就是 创建插件项目 如果你使用的Jenkins 和我的版本不同的话 创建项目的方式也会有所区别,推荐按以下方式操作:
https://img-blog.csdn.net/20180720083940245?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70​data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
   创建 插件程序 出现了错误,提示 mvn hpi:create 已经过期了,让我们使用
mvn archetype:generate -Dfilter=io.jenkins.archetypes:方式去创建,然后我们去运行以下:
https://img-blog.csdn.net/20180720084930805?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​创建maven插件项目
    jenkins提供给了我们五种 模板 :
1、空插件(Jenkins插件的框架)
2、全局配置插件(具有POM和全局配置示例的Jenkins插件的框架)
3、全局共享库
4、hello-world-plugin(带有POM的Jenkins插件的骨架和一个示例构建步骤)
5、脚本管道
   我们选择第四项,下面就会让你选择这么 模板 的版本我们选择最新的就行了,然后就是输入ArtifactId 和创建Maven项目一样GroupId呢这里就不能设置了,在Jenkins的老版本是可以设置的。
   再然后呢就是设置 version 指定插锁创建插件的版本,这里还是使用默认的,直接 Enter 就行,最后确认 信息输入 y 回车,第一次创建可能会花一点时间在 下载 驱动程序上面,后面就会比较快了,耐心等待!!!
   额,这样在我的 E盘 根目录下就生成了我的 JenkinsPlug 插件项目(大写的尴尬,创建了目录忘记cd进去再执行创建命令了)。2.使用Eclipse开发插件
首先说明 其实Jenkins提供了 直接使用Eclipse(IntelliJ IDEA)进行创建Jenkins插件项目的工具,但需要进行集成,这里为了方便就直接使用cmd的形式创建滴,有兴趣的可以直接去 https://jenkins.io/doc/developer/development-environment/ 官方有详细介绍!
1)、将JenkinsPlug导入Eclipse工程:
   右键选择 import导入工程,然后:
https://img-blog.csdn.net/2018072010162178?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70​data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
然后Root Directory 输入或选择到 E:\JenkinsPlug 目录,最后Finish,OK。
2)、项目结构详解
[*]src/main/java
[*]src/main/resources
[*]src/main/webapp

三个目录,第一个放 java类,第三个目录实现不存在,需要我们手动去创建,是用来存放静态资源(js/css之类),最后我们来介绍 src/main/resources 目录,这个目录就高级了,先上图:
https://img-blog.csdn.net/20180720103007394?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​
src/test/java目录下测试文件报错删掉即可,不必理会!还有就是导入项目可能也会话费一定时间!
首先 src/main/java 下的io.jenkins.plugins.sample 包中有 HelloWorldBuilder.java 文件,src/main/resources 下呢有io/jenkins/plugins/sample/HelloWorldBuilder 目录与之对应,这是Jenkins的规则,如果存在HelloWorldBuilder.java就必须存在HelloWorldBuilder目录与之对应,目录路径必须同HelloWorldBuilder.java包名一致。
我们Ctrl + r ==》cmd 然后到 E:\Jenkins路径下 执行 mvn hpi:run 运行插件,记住先删除 .jenkins 目录或者现更改 JENKINS_HOME 变量的值为另外一个目录。访问:http://localhost:8080/jenkins/ 选择 创建一个新任务==》随意输入project名称+选择自由风格软件项目+OK==》之后会进入项目配置页面看到:
https://img-blog.csdn.net/20180720105057864?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70​data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
https://img-blog.csdn.net/20180720105248112?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70​data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
   然后我们再来看HelloWorldBuilder目录,他下面有三类文件,config.jelly、*.properties、*.html ,观察 这些文件里面的内容你会发现 html对应的就是 上面的 帮助页面(单击问号后出现的),config.jelly就是整个的表单界面,properties是表单界面需要用到的属性配置,在HelloWorldBuilder同级下的其它*.properties则是校验后是需要输出的信息配置文件。
整个config.jelly使用的是jelly开发的,然后再看HelloWorldBuilder.java:
@DataBoundConstructor   public HelloWorldBuilder(String name) {           this.name = name;   }    /**   * We'll use this from the <tt>config.jelly</tt>.   */   public String getName() {           return name;   }data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
类中的name属性映射了config.jelly 中 <f:entry title="${%Name}" field="name"> 的field属性,当执行这个项目的构建操作时在 HelloWorldBuilder.java 就会获得页面的name值,也就是存在关联关系。如此我们你就能得到.jelly中想要的值,并且也能在类中对参数进行校验。
注意:<f:*/>(*代表泛指)标签中的field通过类中属性的get方法进行绑定。
下面就是对Builder提供的几个重要方法的介绍,知道这些方法能让你更好的进行开发:
/*perform 真正开始执行的地方 你所有构建时的任务都将在此内完成   * 在此之内你可以执行 任意想执行的业务操作,Web Service等    */    public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener) throws InterruptedException, IOException {                    if (useFrench) {            listener.getLogger().println("Bonjour, " + name + "!");      } else {            listener.getLogger().println("Hello, " + name + "!");      }    }    @Symbol("greet")    @Extension//通过此注解 告诉系统该内部类是作为BuildStepDescriptor的扩展出现    public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {                      /*           * 对页面传来的参数进行校验,第一个参数为 传来的值,第二个 是否通过校验           */      public FormValidation doCheckName(@QueryParameter String value, @QueryParameter boolean useFrench)                throws IOException, ServletException {            if (value.length() == 0)                return FormValidation.error(Messages.HelloWorldBuilder_DescriptorImpl_errors_missingName());            if (value.length() < 4)                return FormValidation.warning(Messages.HelloWorldBuilder_DescriptorImpl_warnings_tooShort());            if (!useFrench && value.matches(".*[éáàç].*")) {                return FormValidation.warning(Messages.HelloWorldBuilder_DescriptorImpl_warnings_reallyFrench());            }            return FormValidation.ok();      }      @Override      public boolean isApplicable(Class<? extends AbstractProject> aClass) {            return true;      }                @Override      public String getDisplayName() {            return Messages.HelloWorldBuilder_DescriptorImpl_DisplayName();//            return "对应页面上选择增加构建步骤时所显示的值,默认为 Say hello world";      }    }data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
在DescriptorImpl中可自定义方法,然后在对应的jelly文件中通过${descriptor.getLanguageNames()}进行引用,如:(实例中的forEach、if标签可参考官方解释,一html中无异。)
在这里再补充如下几点:
一、在jelly中使用List:
https://img-blog.csdnimg.cn/20181107100835223.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==,size_16,color_FFFFFF,t_70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​
https://img-blog.csdnimg.cn/20181107101401690.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==,size_16,color_FFFFFF,t_70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​
https://img-blog.csdnimg.cn/201811071107395.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==,size_16,color_FFFFFF,t_70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​二、两种方式定义jelly标签数据与Map集合使用
在DescriptorImpl内部类中定义:
https://img-blog.csdnimg.cn/20181107101813974.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==,size_16,color_FFFFFF,t_70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
直接在定义全局方法:
https://img-blog.csdnimg.cn/20181107104002977.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==,size_16,color_FFFFFF,t_70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​
个人建议在两者中都进行定义,以避免出现空数据的问题!!
*.jelly使用迭代Map:
https://img-blog.csdnimg.cn/20181107110727906.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==,size_16,color_FFFFFF,t_70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​
三、*.jelly中引入js、css
<?jelly escape-by-default='true'?><j:jelly xmlns:j="jelly:core" xmlns:l="/lib/layout" xmlns:st="jelly:stapler">        <l:layout title="伪页面">                <l:side-panel>                        <st:include page="sidepanel.jelly" it="${it.run}" optional="true"/>                </l:side-panel>                <l:main-panel>                        <link rel="stylesheet" href="${resURL}/plugin/CodesecJenkinsPlugin/view.css"/>                        <script type="text/javascript" src="${resURL}/plugin/CodesecJenkinsPlugin/jquery.min.js"></script>                        <script type="text/javascript" src="${resURL}/plugin/CodesecJenkinsPlugin/echarts.common.min.js"></script>                        <script type="text/javascript" src="${resURL}/plugin/CodesecJenkinsPlugin/echartsOne.js"></script>                        <j:if test="${it.isSize}">                                <div class="myTitle">                                        <span class="myS">${it.projectName}</span>                                </div>、                </l:main-panel>        </l:layout></j:jelly>data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
${resURL}:获取主目录地址。
四、开发遇到的坑
      ① pom文件找不到jar包并且尝试连网maven update依旧无效,检查是否项目使用时使用的maven jenkins 命令按步骤生成,在生成过程中会修改本地仓库;
      ② jelly页面取值为空,检查类中和DescriptorImpl内部类中是否有定义同名的GET方法,如果全局属性取不到值,检查是否有定义getting、setting方法,jelly采用此种方式进行的取值赋值;
      ③ 项目无缘无故报红色叉叉https://img-blog.csdnimg.cn/20181107114450615.pngdata:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​,请手动重新编译项目;
      ④ *.jelly文件存放的路径必须和Builder类完全路径名一致。
https://img-blog.csdnimg.cn/20181107114729894.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODY1MjEzNg==,size_16,color_FFFFFF,t_70data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​
   ⑤ 注意需要引入的库,不然标签会失效
总结:因为工作的原因文章写得有点断断续续的,但个人认为还是比大多数文章要完整一线,有什么问题的话可以留言,看都会回复的。然后后期如果发现有什么错误,笔者也会进行修改,最后希望对有Jenkins插件开发有需求的程序猿有所帮助!

Hmily 发表于 2018-11-28 10:53

这帖子编辑的没法看,外链那地址也没法浏览。

浮生参半 发表于 2018-11-28 13:59

Hmily 发表于 2018-11-28 10:53
这帖子编辑的没法看,外链那地址也没法浏览。

还好吧,我是新手,文笔确实有待提升{:1_907:} ,外链接地址贴错了,是

https://blog.csdn.net/weixin_38652136/article/details/81116455

Hmily 发表于 2018-11-28 15:30

浮生参半 发表于 2018-11-28 13:59
还好吧,我是新手,文笔确实有待提升 ,外链接地址贴错了,是

https://blog.csdn.net/weixin ...

看了下帖子内容一般,多数以总结为主,原创内容较少啊,有没有自己的东西?

浮生参半 发表于 2018-11-29 08:50

Hmily 发表于 2018-11-28 15:30
看了下帖子内容一般,多数以总结为主,原创内容较少啊,有没有自己的东西?

我主要能分享的好像确实都是一下工作时的心得和经验的总结,因为我学Java一直都是摸着石头过河这种慢慢探索的,进吾爱其实更多也是抱着学习的心态,不过后期我应该能分享一些架构或者Web攻防方面的原创,因为所在公司就是做软件安全方面的。主要还是自己的知识面不够,没有经过大学的学习什么的。

Hmily 发表于 2018-11-29 10:48

浮生参半 发表于 2018-11-29 08:50
我主要能分享的好像确实都是一下工作时的心得和经验的总结,因为我学Java一直都是摸着石头过河这种慢慢探 ...

那暂时还是无法达到这个渠道的申请要求,要不等开放注册吧。
页: [1]
查看完整版本: 申请会员ID: Lming·Xie