Jenkins HelloWorld插件在重新启动后不会保持配置

Jenkins HelloWorld插件在重新启动后不会保持配置,jenkins,jenkins-plugins,Jenkins,Jenkins Plugins,我一直在尝试创建我的第一个jenkins插件。一切都很好,只是在jenkins服务重新启动后,全局配置不会持久化 只要服务没有重新启动,配置就可以正常保存 全局配置文件 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"> 心满意足 假的 描述符本身如

我一直在尝试创建我的第一个jenkins插件。一切都很好,只是在jenkins服务重新启动后,全局配置不会持久化

只要服务没有重新启动,配置就可以正常保存

全局配置文件

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
心满意足 假的

描述符本身如下所示

// Overridden for better type safety.
// If your plugin doesn't really define any property on Descriptor,
// you don't have to do this.
@Override
public DescriptorImpl getDescriptor() {
    return (DescriptorImpl)super.getDescriptor();
}

/**
 * Descriptor for {@link HelloWorldBuilder}. Used as a singleton.
 * The class is marked as public so that it can be accessed from views.
 *
 * <p>
 * See <tt>src/main/resources/hudson/plugins/hello_world/HelloWorldBuilder/*.jelly</tt>
 * for the actual HTML fragment for the configuration screen.
 */
@Extension // This indicates to Jenkins that this is an implementation of an extension point.
public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
    /**
     * To persist global configuration information,
     * simply store it in a field and call save().
     *
     * <p>
     * If you don't want fields to be persisted, use <tt>transient</tt>.
     */
    private boolean useFrench;

    /**
     * Performs on-the-fly validation of the form field 'name'.
     *
     * @param value
     *      This parameter receives the value that the user has typed.
     * @return
     *      Indicates the outcome of the validation. This is sent to the browser.
     */
    public FormValidation doCheckName(@QueryParameter String value)
            throws IOException, ServletException {
        if (value.length() == 0)
            return FormValidation.error("Please set a name");
        if (value.length() < 4)
            return FormValidation.warning("Isn't the name too short?");
        return FormValidation.ok();
    }

    public boolean isApplicable(Class<? extends AbstractProject> aClass) {
        // Indicates that this builder can be used with all kinds of project types 
        return true;
    }

    /**
     * This human readable name is used in the configuration screen.
     */
    public String getDisplayName() {
        return "Say hello world";
    }

    @Override
    public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
        // To persist global configuration information,
        // set that to properties and call save().
        useFrench = formData.getBoolean("useFrench");
        // ^Can also use req.bindJSON(this, formData);
        //  (easier when there are many fields; need set* methods for this, like setUseFrench)
        save();
        return super.configure(req,formData);
    }

    /**
     * This method returns true if the global configuration says we should speak French.
     *
     * The method name is bit awkward because global.jelly calls this method to determine
     * the initial state of the checkbox by the naming convention.
     */
    public boolean getUseFrench() {
        return useFrench;
    }
}
//为更好的类型安全性而重写。
//如果你的插件没有在描述符上定义任何属性,
//你不必这么做。
@凌驾
公共描述符rimpl getDescriptor(){
return(DescriptorImpl)super.getDescriptor();
}
/**
*{@link HelloWorldBuilder}的描述符。用作独生子女。
*该类被标记为public,以便可以从视图访问它。
*
*
*请参阅src/main/resources/hudson/plugins/hello\u world/HelloWorldBuilder/*.jelly
*用于配置屏幕的实际HTML片段。
*/
@Extension//这向Jenkins表明这是一个扩展点的实现。
公共静态最终类描述符RIMPL扩展了BuildStepDescriptor{
/**
*要保留全局配置信息,
*只需将其存储在字段中并调用save()。
*
*
*如果不希望字段被持久化,请使用transient。
*/
私用法语;
/**
*对表单字段“name”执行动态验证。
*
*@param值
*此参数接收用户键入的值。
*@返回
*指示验证结果。此结果将发送到浏览器。
*/
public FormValidation doCheckName(@QueryParameter字符串值)
抛出IOException、ServletException{
如果(value.length()==0)
return FormValidation.error(“请设置名称”);
if(value.length()<4)
returnformvalidation.warning(“名称不是太短了吗?”);
返回FormValidation.ok();
}

公共布尔值是可应用的(类),因此这是hello world应用程序的问题。您需要在构造函数中定义要加载配置的值

public DescriptorImpl(){
        load();
    }

这解决了我看到的配置未持久化的问题。

对我不起作用……我缺少一些东西……你能发布完整源代码的链接吗
// Overridden for better type safety.
// If your plugin doesn't really define any property on Descriptor,
// you don't have to do this.
@Override
public DescriptorImpl getDescriptor() {
    return (DescriptorImpl)super.getDescriptor();
}

/**
 * Descriptor for {@link HelloWorldBuilder}. Used as a singleton.
 * The class is marked as public so that it can be accessed from views.
 *
 * <p>
 * See <tt>src/main/resources/hudson/plugins/hello_world/HelloWorldBuilder/*.jelly</tt>
 * for the actual HTML fragment for the configuration screen.
 */
@Extension // This indicates to Jenkins that this is an implementation of an extension point.
public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
    /**
     * To persist global configuration information,
     * simply store it in a field and call save().
     *
     * <p>
     * If you don't want fields to be persisted, use <tt>transient</tt>.
     */
    private boolean useFrench;

    /**
     * Performs on-the-fly validation of the form field 'name'.
     *
     * @param value
     *      This parameter receives the value that the user has typed.
     * @return
     *      Indicates the outcome of the validation. This is sent to the browser.
     */
    public FormValidation doCheckName(@QueryParameter String value)
            throws IOException, ServletException {
        if (value.length() == 0)
            return FormValidation.error("Please set a name");
        if (value.length() < 4)
            return FormValidation.warning("Isn't the name too short?");
        return FormValidation.ok();
    }

    public boolean isApplicable(Class<? extends AbstractProject> aClass) {
        // Indicates that this builder can be used with all kinds of project types 
        return true;
    }

    /**
     * This human readable name is used in the configuration screen.
     */
    public String getDisplayName() {
        return "Say hello world";
    }

    @Override
    public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
        // To persist global configuration information,
        // set that to properties and call save().
        useFrench = formData.getBoolean("useFrench");
        // ^Can also use req.bindJSON(this, formData);
        //  (easier when there are many fields; need set* methods for this, like setUseFrench)
        save();
        return super.configure(req,formData);
    }

    /**
     * This method returns true if the global configuration says we should speak French.
     *
     * The method name is bit awkward because global.jelly calls this method to determine
     * the initial state of the checkbox by the naming convention.
     */
    public boolean getUseFrench() {
        return useFrench;
    }
}
public DescriptorImpl(){
        load();
    }