Rule already declared issue during redeployment

Hello,

I am using Sonar Community Edition 9.8.0.63668 and have successfully deployed four custom java rules in a custom rule plugin.
When i add a new rule to this custom plugin or just recompile and deploy the custom plugin with the existing four rules and restarting the server an error occurs that those rules already exist.

This is the error message of the first rule which is interrupting the server startup process:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdk.internal.loader.ClassLoaders$AppClassLoader@5bc2b487-org.sonar.server.rule.RegisterRules': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: The rule 'CompassEqualsNotOverriddenInSubclass' of repository 'compass-java' is declared several times
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:628)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:187)
	at org.sonar.server.platform.platformlevel.PlatformLevel.start(PlatformLevel.java:80)
	at org.sonar.server.platform.platformlevel.PlatformLevelStartup.access$001(PlatformLevelStartup.java:55)
	at org.sonar.server.platform.platformlevel.PlatformLevelStartup$1.doPrivileged(PlatformLevelStartup.java:127)
	at org.sonar.server.user.DoPrivileged.execute(DoPrivileged.java:45)
	at org.sonar.server.platform.platformlevel.PlatformLevelStartup.start(PlatformLevelStartup.java:124)
	at org.sonar.server.platform.PlatformImpl.executeStartupTasks(PlatformImpl.java:183)
	at org.sonar.server.platform.PlatformImpl$1.lambda$doRun$1(PlatformImpl.java:107)
	at org.sonar.server.platform.PlatformImpl$AutoStarterRunnable.runIfNotAborted(PlatformImpl.java:344)
	at org.sonar.server.platform.PlatformImpl$1.doRun(PlatformImpl.java:107)
	at org.sonar.server.platform.PlatformImpl$AutoStarterRunnable.run(PlatformImpl.java:328)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalArgumentException: The rule 'CompassEqualsNotOverriddenInSubclass' of repository 'compass-java' is declared several times
	at org.sonar.api.utils.Preconditions.checkArgument(Preconditions.java:43)
	at org.sonar.api.server.rule.internal.DefaultNewRepository.createRule(DefaultNewRepository.java:82)
	at org.sonar.api.server.rule.RulesDefinitionAnnotationLoader.loadRule(RulesDefinitionAnnotationLoader.java:82)
	at org.sonar.api.server.rule.RulesDefinitionAnnotationLoader.loadRule(RulesDefinitionAnnotationLoader.java:70)
	at org.sonar.api.server.rule.RulesDefinitionAnnotationLoader.load(RulesDefinitionAnnotationLoader.java:62)
	at org.sonarsource.analyzer.commons.RuleMetadataLoader.addAnnotatedRule(RuleMetadataLoader.java:112)
	at org.sonarsource.analyzer.commons.RuleMetadataLoader.addRuleByAnnotatedClass(RuleMetadataLoader.java:89)
	at org.sonarsource.analyzer.commons.RuleMetadataLoader.addRulesByAnnotatedClass(RuleMetadataLoader.java:78)
	at at.compass.infrastructure.rulesets.JavaRulesDefinition.define(JavaRulesDefinition.java:43)
	at org.sonar.server.rule.RuleDefinitionsLoader.load(RuleDefinitionsLoader.java:56)
	at org.sonar.server.rule.RegisterRules.start(RegisterRules.java:125)
	at org.sonar.core.platform.StartableBeanPostProcessor.postProcessBeforeInitialization(StartableBeanPostProcessor.java:33)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
	... 20 common frames omitted

I also tried starting the server without the custom plugin and then restarted again with the plugin and rules activated which again leds to the issue above.
I do not understand where the rules might be cached or referenced to trigger this error.

Thank you for your help.

greetings
Thomas

Hi Thomas,

Before we can support you in this, I need you to upgrade to at least SonarQube 9.9 LTS, if not 10.1. Older versions are not supported.

And then we can look at how you’re deploying your plugin. Are you doing a full restart of your instance? Because based on the error message, it sounds like your SonarQube already has the rule in memory when you try to load a new copy.

 
Ann

Hi Ann,

Thank you for your response,
we will upgrade and see if that fixes the issue.

We perform a full restart the service. Is there a way to clear the cache of the instance manually?

Thomas

Hi Thomas,

I’m not aware of one.

 
Ann

Hi Ann,

I used a fresh server instance running SonarQube 10.1.0.73491 to test if the issue remains.
Unfortunately, it does. I deployed my plugin containing 4 rules, after rebuilding my plugin with an additional rule, the server complains about a rule key being used twice (the first in the list).

Please advice.

Thank you and best regards
Thomas

Hi,

This is probably a question of the build of your plugin, then. Is it possible there’s some caching on that side?

 
Ann

Hi,

I will analyze the pom of our project in which i build the plugin to find a possible issue there.
Using SonarQube 10.1.0.73491 which are the correct version of the sonarqube and sonarjava plugins to specify in the pom?

Tom

Hi Tom,

No need to specify the sonarjava plugin; it’s bundled now & present by default.

 
Ann

Hi Ann,

I tracked the issue to my custom rules being added both to the JavaChecks as well as the JavaTestChecks list in class RulesList, since i want to both target source and test code with my rules.
The getChecks() method merges both lists into one, which leds to
ruleMetadataLoader.addRulesByAnnotatedClass(repository, new ArrayList<>(RulesList.getChecks())); in class JavaRulesDefinition receiving a list with duplicates.

What is the correct way to use the same rule to target both source and test code.

Thank you very much.
Tom

1 Like

Hi Tom,

Unfortunately, we don’t have a good way to do this.

I suppose you could create a 2nd class for each rule that inherits, but provides a different id? And then register that as the test rule?

 
Ann

Thank you, i will do that.

best wishes
Tom