[SonarQube] Error during initialization: NoClassDefFoundError in RulesRegistrant

Hello Java & SonarQube Community,

I hope this message finds you well. I’m currently facing an issue with my SonarQube instance, and I’m seeking your assistance in resolving it.

2023-11-15 00:11:29 2023.11.14 17:11:29 WARN  web[][o.s.c.a.AnnotationConfigApplicationContext] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdk.internal.loader.ClassLoaders$AppClassLoader@6ee6f53-org.sonar.server.rule.registration.RulesRegistrant': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/sonarsource/analyzer/commons/RuleMetadataLoader
2023-11-15 00:11:29 2023.11.14 17:11:29 ERROR web[][o.s.s.p.Platform] Background initialization failed. Stopping SonarQube
2023-11-15 00:11:29 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdk.internal.loader.ClassLoaders$AppClassLoader@6ee6f53-org.sonar.server.rule.registration.RulesRegistrant': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/sonarsource/analyzer/commons/RuleMetadataLoader

Contex: maven project
In the pom.xml :

<dependency>
            <groupId>org.sonarsource.api.plugin</groupId>
            <artifactId>sonar-plugin-api</artifactId>
            <version>10.2.0.1908</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <!-- packaged with the plugin -->
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.9</version>
        </dependency>

        <dependency>
            <groupId>org.sonarsource.java</groupId>
            <artifactId>sonar-java-plugin</artifactId>
            <version>7.28.0.33738</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.sonarsource.analyzer-commons</groupId>
            <artifactId>sonar-analyzer-commons</artifactId>
            <version>2.7.0.1482</version>
        </dependency>

Hey there.

Does this post help?

1 Like

I have followed the example, copied both the POM and source code, but I’m still facing issues.

In the JavaRulesDefinition.java :

tpackage org.sonar.samples.java;

import org.sonar.api.SonarRuntime;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.utils.AnnotationUtils;
import org.sonar.java.annotations.VisibleForTesting;
import org.sonarsource.analyzer.commons.RuleMetadataLoader;
import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKey;
import org.sonarsource.analyzer.commons.annotations.DeprecatedRuleKeys;

import java.util.Objects;

public class MyJavaRulesDefinition implements RulesDefinition {

    // don't change that because the path is hard coded in CheckVerifier
    private static final String RESOURCE_BASE_PATH = "src/main/resources/org/sonar/l10n/java/rules/java";

    public static final String REPOSITORY_KEY = "java-plugin";

    private final SonarRuntime sonarRuntime;

    public MyJavaRulesDefinition(SonarRuntime sonarRuntime) {
        this.sonarRuntime = sonarRuntime;
    }


    @Override
    public void define(Context context) {
        NewRepository repository = context
                .createRepository(REPOSITORY_KEY, "java")
                .setName(REPOSITORY_KEY);

        RuleMetadataLoader ruleMetadataLoader = new RuleMetadataLoader(RESOURCE_BASE_PATH, sonarRuntime);
        ruleMetadataLoader.addRulesByAnnotatedClass(repository, RuleList.getChecks());

        RuleList.getChecks().stream()
                .filter(rule -> !deprecatesRules(rule))
                .map(MyJavaRulesDefinition::ruleKey)
                .map(repository::rule)
                .filter(Objects::nonNull)
                .forEach(rule -> rule.addDeprecatedRuleKey("squid", rule.key()));

        repository.done();
    }

    private static String ruleKey(Class<?> rule) {
        return AnnotationUtils.getAnnotation(rule, org.sonar.check.Rule.class).key();
    }

    @VisibleForTesting
    static boolean deprecatesRules(Class<?> rule) {
        return AnnotationUtils.getAnnotation(rule, DeprecatedRuleKey.class) != null
                || AnnotationUtils.getAnnotation(rule, DeprecatedRuleKeys.class) != null;
    }
}

2 Likes

Hi Pongtayot,

Is the problem still relevant? I’m asking because it was marked as “Solved by Colin in post #2”, but you said you are still facing issues in post #3.

In case you are still facing issues, the following line is probably the cause and must be removed:

<scope>provided</scope>

It tells Gradle to not put the dependency classes into the generated JAR, because it is assumed they are provided by the environment in which your JAR is executed. But this is not the case due to class loader isolation between plugins. The classes must be provided within the JAR of your plugin.

Best,
Marco

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.