jenkins插件学习之BuildUserVars和BuildNameDescriptionSetter插件执行顺序
之前一直在使用 BuildUserVars 和 BuildNameDescriptionSetter 这2个插件,
通过 BuildUserVars 能够获取到是哪个人触发了构建.这个插件会设置个类似的环境变量 BUILD_USER.
然后 通过 BuildNameDescriptionSetter 插件 把这个环境变量 BUILD_USER 设置到 构建的 name 上.
方便一眼看出来构建历史中哪个构建是哪个人触发的/或者哪个构建是定时器触发的等等.
BuildNameDescriptionSetter 插件有个 " Set build name before build starts " 和 " Set build name after build ends " 选项
发现 只有在 " Set build name after build ends " 的时候 才能获取到 BUILD_USER 这个变量. 为什么这样的???
通过研究发现 是 因为 BuildUserVars 在 BuildNameDescriptionSetter 之后执行了.
执行顺序 类似 下面这样
①先 BuildNameDescriptionSetter的 " Set build name before build starts "
②然后是 BuildUserVars 插件设置用户相关的环境变量
③最后 BuildNameDescriptionSetter的 " Set build name after build ends "
在job的配置界面 "Build Environment" 地方也可以看到 BuildNameDescriptionSetter 插件 在 BuildUserVars 插件上面的.
为什么这么个排序呢?
通过搜索发现 插件 Extension 的排序是 有个 ordinal 值提供排序的. 值越大 越靠前. 默认这2个插件的这个值都是0.
都是0的话 就会按照 插件的 displayName 排序了.
修改的话 可以 把 BuildUserVars 插件的 ordinal 值 设置 大于0.
第二种修改方法 就是 修改 displayName,让排序 换一下位置.
@Extension(ordinal = 1) // ordinal 值 设置 大于0
public static class DescriptorImpl extends BuildWrapperDescriptor {
@Override
public boolean isApplicable(AbstractProject<?, ?> item) {
return true;
}
@Override
public String getDisplayName() {
return EXTENSION_DISPLAY_NAME;
}
}
private static final String EXTENSION_DISPLAY_NAME = "Set jenkins user build variables";
/**
* Returns all the registered {@link BuildWrapper} descriptors.
*/
// for compatibility we can't use BuildWrapperDescriptor
public static DescriptorExtensionList<BuildWrapper,Descriptor<BuildWrapper>> all() {
// use getDescriptorList and not getExtensionList to pick up legacy instances
return Jenkins.getInstance().<BuildWrapper,Descriptor<BuildWrapper>>getDescriptorList(BuildWrapper.class);
}
public DescriptorExtensionList<T,D> getDescriptorList(Class<T> type) { //type = BuildWrapper.class hudson.tasks.BuildWrapper
return descriptorLists.computeIfAbsent(type, key -> DescriptorExtensionList.createDescriptorList(this, key));
//descriptorLists 中有key对应的值直接就获取到了. 如果没用通过 DescriptorExtensionList.createDescriptorList(this, key) 新建了.
}
descriptorLists 这个里面初始了很多的DescriptorExtensionList, 而我们要找的是 {Class@10416} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@13112} size = 2 这个对应的.
descriptorLists = {ConcurrentHashMap@13015} size = 14
{Class@10349} "class hudson.views.ListViewColumn" -> {DescriptorExtensionList@13102} size = 8
{Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@13103} size = 22
{Class@10272} "class hudson.model.JobProperty" -> {DescriptorExtensionList@13104} size = 3
{Class@10289} "class hudson.scm.SCM" -> {DescriptorExtensionList@13105} size = 1
{Class@8453} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@13106} size = 8
{Class@10312} "class hudson.tasks.Publisher" -> {Publisher$DescriptorExtensionListImpl@13107} size = 6
{Class@10253} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@13108} size = 7
{Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@13109} size = 6
{Class@10370} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@13110} size = 1
{Class@7731} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@13111} size = 4
{Class@10416} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@13112} size = 2
{Class@8443} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@13113} size = 3
{Class@10323} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@13114} size = 1
{Class@10317} "class hudson.tasks.Builder" -> {DescriptorExtensionList@13115} size = 6
public static DescriptorExtensionList<T,D> createDescriptorList(Jenkins jenkins, Class<T> describableType) {
if (describableType == (Class) Publisher.class) {
return (DescriptorExtensionList) new Publisher.DescriptorExtensionListImpl(jenkins);
}
return new DescriptorExtensionList<>(jenkins, describableType);
}
@Deprecated 这个方法已经不用了. 传入的参数是hudson 实例而已. 我们看到里面也是强制的把 hudson 转换为 jenkins 实例了.public class Hudson extends Jenkins
public static DescriptorExtensionList<T,D> createDescriptorList(Hudson hudson, Class<T> describableType) {
return (DescriptorExtensionList)createDescriptorList((Jenkins)hudson,describableType);
}
通过在 return descriptorLists.computeIfAbsent(type, key -> DescriptorExtensionList.createDescriptorList(this, key)); 加上断点 调试发现 如下
懒加载啊!
首先重启 debug. 也就是重启了jenkins.
descriptorLists = {ConcurrentHashMap@10542} size = 0 第1次 实例化这个 class hudson.node_monitors.NodeMonitor
descriptorLists = {ConcurrentHashMap@10541} size = 1 第2次. 准备实例化这个 class jenkins.model.GlobalConfiguration
{Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741} size = 6
到这个时候 jenkins 已经启动起来了. 后续 点击了job的话还会继续实例化 下面的.
descriptorLists = {ConcurrentHashMap@10541} size = 2 第3次 class hudson.model.PageDecorator
{Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11557} size = 22
{Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741} size = 6
descriptorLists = {ConcurrentHashMap@10541} size = 3
{Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11557} size = 22
{Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741} size = 6
{Class@8454} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11911} size = 8
descriptorLists = {ConcurrentHashMap@10541} size = 3 第4次 class jenkins.model.GlobalConfiguration
{Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11557} size = 22
{Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741} size = 6
{Class@8454} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11911} size = 8
到这时 是 点击 job 后 又加载的几个实例.
descriptorLists = {ConcurrentHashMap@10541} size = 4 第5次 interface hudson.model.TopLevelItem
{Class@8034} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11557} size = 22
{Class@8698} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@10741} size = 6
{Class@8440} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12854} size = 3
{Class@8454} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11911} size = 8
懒加载啊!
descriptorLists = {ConcurrentHashMap@10542} size = 5 第6次 class jenkins.model.BuildDiscarder
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
又增加了一个.class jenkins.model.BuildDiscarder!!!
descriptorLists = {ConcurrentHashMap@10542} size = 6
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637} size = 1
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
又增加了一个.class hudson.model.ParameterDefinition!!! 参数阶段
descriptorLists = {ConcurrentHashMap@10542} size = 7
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637} size = 1
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672} size = 7
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
又增加了一个.class hudson.scm.SCM!!
descriptorLists = {ConcurrentHashMap@10542} size = 8
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637} size = 1
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672} size = 7
{Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696} size = 1
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
又增加了一个.class jenkins.scm.SCMCheckoutStrategy!!!! 这个基本上就是 job 配置 页面 从上到下 各个阶段的配置了. 代码检出阶段.
descriptorLists = {ConcurrentHashMap@10542} size = 9
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637} size = 1
{Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722} size = 1
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672} size = 7
{Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696} size = 1
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
又增加了一个class hudson.triggers.Trigger!!!这个基本上就是 job 配置 页面 从上到下 各个阶段的配置了. 触发阶段了.
descriptorLists = {ConcurrentHashMap@10542} size = 10
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637} size = 1
{Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722} size = 1
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672} size = 7
{Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770} size = 4
{Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696} size = 1
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
又增加了一个class hudson.tasks.BuildWrapper, !!!! BuildWrapper 阶段了.构建环境设置.那一块了.
descriptorLists = {ConcurrentHashMap@10542} size = 11
{Class@10417} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@12804} size = 2
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637} size = 1
{Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722} size = 1
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672} size = 7
{Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770} size = 4
{Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696} size = 1
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
又增加了一个 class hudson.tasks.Builder !!! 构建阶段
descriptorLists = {ConcurrentHashMap@10542} size = 12
{Class@10417} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@12804} size = 2
{Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637} size = 1
{Class@10318} "class hudson.tasks.Builder" -> {DescriptorExtensionList@12845} size = 6
{Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770} size = 4
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722} size = 1
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672} size = 7
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696} size = 1
又增加了一个class hudson.tasks.Publisher
descriptorLists = {ConcurrentHashMap@10542} size = 13
{Class@10417} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@12804} size = 2
{Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637} size = 1
{Class@10318} "class hudson.tasks.Builder" -> {DescriptorExtensionList@12845} size = 6
{Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770} size = 4
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
{Class@10313} "class hudson.tasks.Publisher" -> {Publisher$DescriptorExtensionListImpl@13032} size = 6
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722} size = 1
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672} size = 7
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696} size = 1
descriptorLists = {ConcurrentHashMap@10542} size = 14
{Class@10417} "class hudson.tasks.BuildWrapper" -> {DescriptorExtensionList@12804} size = 2
{Class@10324} "class jenkins.model.BuildDiscarder" -> {DescriptorExtensionList@12637} size = 1
{Class@10318} "class hudson.tasks.Builder" -> {DescriptorExtensionList@12845} size = 6
{Class@7733} "class hudson.triggers.Trigger" -> {DescriptorExtensionList@12770} size = 4
{Class@8035} "class jenkins.model.GlobalConfiguration" -> {DescriptorExtensionList@11528} size = 22
{Class@10313} "class hudson.tasks.Publisher" -> {Publisher$DescriptorExtensionListImpl@13032} size = 6
{Class@10273} "class hudson.model.JobProperty" -> {DescriptorExtensionList@12571} size = 3
{Class@8699} "class hudson.node_monitors.NodeMonitor" -> {DescriptorExtensionList@11527} size = 6
{Class@10371} "class jenkins.scm.SCMCheckoutStrategy" -> {DescriptorExtensionList@12722} size = 1
{Class@8455} "class hudson.model.PageDecorator" -> {DescriptorExtensionList@11546} size = 8
{Class@10251} "class hudson.model.ParameterDefinition" -> {DescriptorExtensionList@12672} size = 7
{Class@8441} "interface hudson.model.TopLevelItem" -> {DescriptorExtensionList@12401} size = 3
{Class@10350} "class hudson.views.ListViewColumn" -> {DescriptorExtensionList@13278} size = 8
{Class@10290} "class hudson.scm.SCM" -> {DescriptorExtensionList@12696} size = 1
public abstract class Project<P extends Project<P,B>,B extends Build<P,B>>
extends AbstractProject<P,B> implements SCMTriggerItem, Saveable, ProjectWithMaven, BuildableItemWithBuildWrappers {
@Override
protected void submit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException {
super.submit(req,rsp);
JSONObject json = req.getSubmittedForm();
getBuildWrappersList().rebuild(req,json, BuildWrappers.getFor(this));
getBuildersList().rebuildHetero(req,json, Builder.all(), "builder");
getPublishersList().rebuildHetero(req, json, Publisher.all(), "publisher");
}
在 Project 类中的 submit()方法中会调用到 BuildWrappers.getFor(this) 方法. submit()方法 方法就是点了job配置里面的save按钮触发的.
public class BuildWrappers {
/**
* List up all {@link BuildWrapperDescriptor}s that are applicable for the given project.
*
* @return
* The signature doesn't use {@link BuildWrapperDescriptor} to maintain compatibility
* with {@link BuildWrapper} implementations before 1.150.
*/
public static List<Descriptor<BuildWrapper>> getFor(AbstractProject<?, ?> project) {
List<Descriptor<BuildWrapper>> result = new ArrayList<>();
Descriptor pd = Jenkins.getInstance().getDescriptor((Class)project.getClass());
for (Descriptor<BuildWrapper> w : BuildWrapper.all()) {
if (pd instanceof AbstractProjectDescriptor && !((AbstractProjectDescriptor)pd).isApplicable(w))
continue;
if (w instanceof BuildWrapperDescriptor) {
BuildWrapperDescriptor bwd = (BuildWrapperDescriptor) w;
if(bwd.isApplicable(project))
result.add(bwd);
} else {
// old BuildWrapper that doesn't implement BuildWrapperDescriptor
result.add(w);
}
}
return result;
}
}
通过 调用 BuildWrappers 中的 getFor()方法.
调用到 for (Descriptor<BuildWrapper> w : BuildWrapper.all()) { 时候会 执行到 public @Nonnull Iterator<T> iterator() { 里面
@Override
public @Nonnull Iterator<T> iterator() {
// we need to intercept mutation, so for now don't allow Iterator.remove
return new AdaptedIterator<ExtensionComponent<T>,T>(Iterators.readOnly(ensureLoaded().iterator())) {
protected T adapt(ExtensionComponent<T> item) {
return item.getInstance();
}
};
}
然后iterator() 方法里面会调用ensureLoaded() 方法
private List<ExtensionComponent<T>> ensureLoaded() {
if(extensions!=null)
return extensions; // already loaded
if (jenkins.getInitLevel().compareTo(InitMilestone.PLUGINS_PREPARED)<0)
return legacyInstances; // can't perform the auto discovery until all plugins are loaded, so just make the legacy instances visible
synchronized (getLoadLock()) {
if(extensions==null) {
List<ExtensionComponent<T>> r = load();
r.addAll(legacyInstances);
extensions = sort(r);
}
return extensions;
}
}
最后 ensureLoaded() 里面会对 List 进行 排序.
/**
* If the {@link ExtensionList} implementation requires sorting extensions,
* override this method to do so.
*
* <p>
* The implementation should copy a list, do a sort, and return the new instance.
*/
protected List<ExtensionComponent<T>> sort(List<ExtensionComponent<T>> r) {
r = new ArrayList<>(r);
Collections.sort(r);
return r;
}
排序的时候会调用到 ExtensionComponent 里面的 compareTo(ExtensionComponent<T> that) 方法.
DescriptorExtensionList 中有存放的 ExtensionComponent 的一个集合. 然后 ExtensionComponent 中会有个 compareTo 比较顺序的方法.
然后比较出来的顺序就是 BuildWrapper 类型插件 的执行的先后顺序.
如果设置了 ordinal 值. 值越大 越先执行的(也就是job设置界面里面越靠上)没有设置ordinal就比较 displayname. 按照字符串比较的.
如果比较displayname失败会比较getClass().getName(),也是按照字符串比较。
this = {DescriptorExtensionList@12209} size = 2
0 = {BuildNameSetter$DescriptorImpl@12212}
1 = {BuildUser$DescriptorImpl@12213}
/**
* Sort {@link ExtensionComponent}s in the descending order of {@link #ordinal()}.
*/
public int compareTo(ExtensionComponent<T> that) {
double a = this.ordinal();
double b = that.ordinal();
if (a>b) return -1;
if (a<b) return 1;
// make the order bit more deterministic among extensions of the same ordinal
if (this.instance instanceof Descriptor && that.instance instanceof Descriptor) {
try {
return Util.fixNull(((Descriptor)this.instance).getDisplayName()).compareTo(Util.fixNull(((Descriptor)that.instance).getDisplayName()));
} catch (RuntimeException | LinkageError x) {
LOG.log(Level.WARNING, null, x);
}
}
return this.instance.getClass().getName().compareTo(that.instance.getClass().getName());
}
这里我采用了修改build-user-vars-plugin插件的display的方法,本来就觉得他设置的displayname看着不爽。
private static final String EXTENSION_DISPLAY_NAME = "Set jenkins user build variables";
private static final String EXTENSION_DISPLAY_NAME = "Set Build User Variables";
可以参考 https://github.com/mamh-java/build-user-vars-plugin