Why Can't I update my custom rule's detail by API?

I defined a Custom rule using java. deployed it to sonarqube server, and sonarqube picked it up.

but why Can’t I update my custom rule’s detail by API ?

public void updateRule(Rule r) {
	    org.sonarqube.ws.client.rules.UpdateRequest ur = new org.sonarqube.ws.client.rules.UpdateRequest();
	    ur.setKey(r.getKey());
	    ur.setMarkdownDescription(r.getMdDesc());
	    ur.setMarkdownNote(r.getMdNote());
	    ur.setName(r.getName());
	    // TODO params
	    // ur.setParams(r.getParams());
	    ur.setRemediationFnBaseEffort(r.getRemFnBaseEffort());
	    ur.setRemediationFnType(r.getRemFnType());
	    ur.setRemediationFyGapMultiplier(r.getRemFnGapMultiplier());
	    ur.setSeverity(r.getSeverity());
	    ur.setStatus(r.getStatus().name());
	    List<String> tags = new ArrayList<String>();
	    for(int i = 0 ;i < r.getTags().getTagsCount(); i++) {
	        tags.add(r.getTags().getTags(i));
	    }
	    if(!tags.isEmpty()) {
	        ur.setTags(tags);
	    }
	    client.rules().update(ur);
	}
	
	public static void main(String[] args) {
        SonarApi sonarApi = new SonarApi("http://172.25.160.238:9876", "cac3b3c65347e87cdf1f9a7352935db79e2435f5");
        Rule r = sonarApi.getRule("custom-rules-java:ExampleRules01");
        sonarApi.updateRule(Rule.newBuilder(r).setMdNote("*注意,这仅仅是一个演示自定义规则的示例,并不具有实际意义!111*").build());
    }

exceptions:

Exception in thread "main" org.sonarqube.ws.client.HttpException: Error 400 on http://172.25.160.238:9876/api/rules/update : {"errors":[{"msg":"Not a custom rule"}]}
	at org.sonarqube.ws.client.BaseResponse.failIfNotSuccessful(BaseResponse.java:36)
	at org.sonarqube.ws.client.BaseService.call(BaseService.java:55)
	at org.sonarqube.ws.client.BaseService.call(BaseService.java:50)
	at org.sonarqube.ws.client.BaseService.call(BaseService.java:45)
	at org.sonarqube.ws.client.rules.RulesService.update(RulesService.java:200)
	at com.bgzchina.devops.cq.sonar.SonarApi.updateRule(SonarApi.java:456)
	at com.bgzchina.devops.cq.sonar.SonarApi.main(SonarApi.java:462)

the error message is confusing, my rule is obviously a custom rule.

my rule deinition and registrar if those matters:

// 规则定义
public class ExampleRulesDefinition implements RulesDefinition {
    // 元信息路径,不能修改,在CheckVerifier中是写死的
    private static final String RESOURCE_BASE_PATH = "org/sonar/l10n/java/rules/java";
    // 规则集-Key
    public static final String REPOSITORY_KEY = "custom-rules-java";
    // 规则集名称
    public static final String REPOSITORY_NAME = "示例自定义规则(仅供演示)";

    // 哪些规则应当被当成模板,本示例中无
    private static final Set<String> RULE_TEMPLATES_KEY = Collections.emptySet();

    private final SonarRuntime runtime;

    public ExampleRulesDefinition(SonarRuntime runtime) {
        this.runtime = runtime;
    }

    @Override
    public void define(Context context) {
        NewRepository repository = context.createRepository(REPOSITORY_KEY, "java").setName(REPOSITORY_NAME);
        RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH, runtime);
        ruleMetadataLoader.addRulesByAnnotatedClass(repository, new ArrayList<>(RulesList.getChecks()));
        setTemplates(repository);
        repository.done();
    }

    private static void setTemplates(NewRepository repository) {
        RULE_TEMPLATES_KEY.stream().map(repository::rule).filter(Objects::nonNull).forEach(rule -> rule.setTemplate(true));
    }

}
public class ExampleRegistrar implements CheckRegistrar {

    // 注册规则
    @Override
    public void register(RegistrarContext registrarContext) {
        // Call to registerClassesForRepository to associate the classes with the
        // correct repository key
        registrarContext.registerClassesForRepository(ExampleRulesDefinition.REPOSITORY_KEY, checkClasses(), testCheckClasses());
    }

    // 源码检查规则
    public static List<Class<? extends JavaCheck>> checkClasses() {
        return RulesList.getJavaChecks();
    }

    // 测试检查规则
    public static List<Class<? extends JavaCheck>> testCheckClasses() {
        return RulesList.getJavaTestChecks();
    }

}

the markdown note is actually can be updated on web UI… :face_exhaling:

I think I’ve kicked the “pay to perfect” limit, but I totally understand since I didn’t pay a dime.