Custom Java rules are not executed after Sonar API upgrade from 9.x to 10.x

Hi,

We have developed a plugin for Sonar that adds rules for Java and Python. Here is the link to the Github repository: Sonar Cryptography Plugin.

Recently we tried to update the plugin to support Sonar 10.x and we ran into a problem:

In a nutshell: After updating the API version to 10.x, our custom rules are no longer executed.

Details

Everything works fine using the following versions:

  • SonarQube 9.9.6.92038
  • SonarScanner for Maven 4.0
  • Dependencies in the plugin:
    • sonar-java 8.1.0.36477
    • sonar-plugin-api 9.17.0.587

We do not get any output (neither success nor failure) or errors when we use the following versions:

  • SonarQube 10.6.0.92116
  • SonarScanner for Maven 4.0
  • Dependencies in the plugin:
    • sonar-java 8.1.0.36477
    • sonar-plugin-api 10.10.0.2391 (tested also with 10.2.0.1908)

For testing we run SonarQube using Docker with a deployed postgres database.

Since we are not getting any errors (build and runtime), it is not clear what went wrong and there is not really a clear way how we could fix it. I tried to check what is actually executed and my impression is that the method in CheckRegister which is used for registering our Java rules is not executed. However, the rules are displayed in the SonarQube UI, so creating a new repository should have worked.

Hope you can help here, many thanks!

2 Likes

Hi,

It looks like you upgraded your version of SonarQube and of the plugin API, but not of sonar-java?

My first thought is that that’s probably relevant. Since sonar-java is bundled, you shouldn’t need to explicitly declare a dependency to make sure it’s available. So what happens if you drop the dependency?

 
Ann

Hi Ann,

thanks for your help!

So, i set the sonar-java dependency to provided and run the plugin again.

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

The mvn plugin throws an exception, that the CheckRegistar class from the sonar-java package is missing.

[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:4.0.0.4121:sonar (default-cli) on project client-encryption: Execution default-cli of goal org.sonarsource.scanner.maven:sonar-maven-plugin:4.0.0.4121:sonar failed: A required class was missing while executing org.sonarsource.scanner.maven:sonar-maven-plugin:4.0.0.4121:sonar: org/sonar/plugins/java/api/CheckRegistrar
[ERROR] -----------------------------------------------------
[ERROR] realm =    plugin>org.codehaus.mojo:sonar-maven-plugin:4.0.0.4121
[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
[ERROR] urls[0] = file:/.m2/repository/org/sonarsource/scanner/maven/sonar-maven-plugin/4.0.0.4121/sonar-maven-plugin-4.0.0.4121.jar
[ERROR] urls[1] = file:/.m2/repository/org/sonatype/plexus/plexus-sec-dispatcher/1.4/plexus-sec-dispatcher-1.4.jar
[ERROR] urls[2] = file:/.m2/repository/org/codehaus/plexus/plexus-utils/1.5.5/plexus-utils-1.5.5.jar
[ERROR] urls[3] = file:/.m2/repository/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
[ERROR] urls[4] = file:/.m2/repository/org/sonarsource/scanner/api/sonar-scanner-api/2.16.3.1081/sonar-scanner-api-2.16.3.1081.jar
[ERROR] urls[5] = file:/.m2/repository/commons-lang/commons-lang/2.6/commons-lang-2.6.jar
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import  from realm ClassRealm[maven.api, parent: null]]
[ERROR]
[ERROR] -----------------------------------------------------
[ERROR] : org.sonar.plugins.java.api.CheckRegistrar

Looking into the SonarQube logs the following sonar-java plugin version was loaded:

sonarqube-1  | 2024.07.25 13:34:39 INFO  web[][o.s.s.p.ServerPluginManager] Deploy Java Advanced Code Quality Analyzer / 8.0.1.36337 / 06cf4ed6298da3ae634677c5eff8bba46f2498a5
sonarqube-1  | 2024.07.25 13:34:39 INFO  web[][o.s.s.p.ServerPluginManager] Deploy Java Code Quality and Security / 8.0.1.36337 / 06cf4ed6298da3ae634677c5eff8bba46f2498a5

So, I’m not sure if I should drop the dependency. At least they match in version :slight_smile:

I looked into the pom.xml for sonar-java version 8.0.1.36337 and they already support the 10.x api. Surprisingly, we can use the 8.0.1 version even if we run our plugin on SonarQube 9.x. Since that worked, we were not downgrading sonar-java on our site to support 9.x, since it works also with the latest version.

Best,
Nicklas

Hi Nicklas,

Do you see your plugin being loaded in web.log during startup? Since your rules show up in the UI, you presumably do, but it’s worth making sure and making sure there’s nothing else about your plugin in the log.

Could you maybe add some logging to your rules and check your analysis log for the output?

 
Thx,
Ann

Hi Ann,

yes, the plugin is being loaded. In the web.log I see,

sonarqube-1  | 2024.07.26 07:42:25 INFO  ce[][c.i.p.CryptographyPlugin] Sonar Cryptography initialized in context (SONARQUBE)

which is executed here in the code.

Also, when I scan a project with the Maven plugin, these logs appear, so it seems that the plugin is recognized.

I also added (for testing/debugging) a log line to the CheckRegistrar.register method (here), but this log message does not appear. So my assumption is that the plugin is recognized (at least the rule definition, that’s why I can see it in the UI), but my additional Java rules are not registered. I made sure, that I added my custom CheckRegistrar class as an extension to the plugin (see).

Best,
Nicklas

Hi Nicklas,

Thanks for jumping through my hoops. I’ve flagged this for people who use the API every day.

 
Ann

1 Like

Hello @nicklaskoertge,

I’m able to reproduce what you described, and I can see that the JavaInventoryRule is available while all the other rules, i.e. those in the detection package, are not loaded. Unfortunately, those rules are created via your framework and it’s out of my expertise to assist you with it.

Please try to check the documentation for the custom rules, specifically the section about registering the rule in the custom plugin. I would suggest to check that the metadata is correctly provided and look at the latest changes in the sonar-plugin-api, see also the documentation.

Cheers,
Angelo

1 Like

Hi Angelo,

thanks for your help! I understand that you don’t have the time to investigate any plugins :wink:

This is actually the correct behavior, only the JavaInventory rule should be visible in the user interface. The detection rules are “sub-rules” (no rules in the sonar context) and are used by the JavaInventory rule.

Just as a test, I replaced the JavaInventoryRule with a very simple rule based on the example from the “add custom rule documentation”: link

package com.ibm.plugin.rules;

import org.sonar.check.Rule;
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
import org.sonar.plugins.java.api.tree.Tree;

import java.util.Collections;
import java.util.List;

@Rule(key = "Inventory")
public class JavaInventoryRule extends IssuableSubscriptionVisitor {

    @Override
    public List<Tree.Kind> nodesToVisit() {
        System.out.println("rule nodes to visit check");
        // Register to the kind of nodes you want to be called upon visit.
        return Collections.singletonList(Tree.Kind.METHOD_INVOCATION);
    }

    @Override
    public void visitNode(Tree tree) {
        reportIssue(tree, "message");
    }
}

With this rule, there is no longer a dependency on a user-defined framework. During a test scan, neither the println statement is executed nor is a problem reported (I scanned this repository for testing).

Looking into the sonar-java code, I saw that there was a change in the registration of rules (see here). I don’t know if these changes have anything to do with it.

This issue (SONARJAVA-5026) seems related: Custom rules examples are not loaded by SonarQube when built with latest sonar-java

Best,
Nicklas

Hello @nicklaskoertge,

If you can see the rule in the UI, then I wonder if you activated it for the project you are trying to scan. In case you didn’t, add the rule to a quality profile and use that profile on your project.

I haven’t dug into SONARJAVA-5026, but the problem seems to be related to using an old version of the sonar-java-plugin in the custom plugin w.r.t. the java plugin provided in SQ; this shouldn’t be the case here.

Cheers,
Angelo

Hi Angelo

yes, I made sure that the rule is activated (the only rule in the crypto profile) and that the Quality Profile is activited for the repo, too. See screenshots.


Alright, I thought it has more todo with a mismatch of sonar-java versions between the one provided by SonarQube and the one referenced in the plugin/extension. I test my plugin using the following version settings, but same behaviour: no errors and no detections.

  • SonarQube 10.6.0.92116
  • SonarScanner for Maven 4.0
  • Dependencies in the plugin:
    • sonar-java 7.35.xxxx
    • sonar-plugin-api 10.10.0.2391

Best,
Nicklas

Hi All,

I investigated a little more and found a solution to the problem.

We set the pluginApiMinVersion to the sonar-api-verison we pin to build the plugin (see). Since this was always the newest version 10.10.0.2391 and SonarQube 10.4.0 only supports up to 10.6.0.2114 there was a version mismatch.

After setting the pluginApiMinVersion to 9.14.0.375, everything works as expected.

Best
Nicklas

2 Likes

Thank you, @nicklaskoertge, for looking into it more and finding a solution!

I will contact the team maintaining the sonar-packaging-maven-plugin to learn more about its interaction with the customs rules. Meanwhile, I found that the sonar-packaging-maven-plugin may be deprecated in the future: [PACKMP-21] - Jira.

Cheers,
Angelo

2 Likes

Hi Angelo, so we did some more testing using

  • SonarScanner for Maven 4.0
  • Dependencies in the plugin:
    • sonar-java 8.1.0.36477
    • sonar-plugin-api 10.10.0.2391
    • sonar-min-plugin-api 9.14.0.375

Everything works fine using the plugin in every SonarQube version up to 10.4.1.

It breaks using the version 10.5.0 or higher with the same plugin build (using the versions from above).

It seems to me, that there is a bug in SonarQube 10.5.0 and higher related to custom sonar-java rules.

Best,
Nicklas

Hi @nicklaskoertge,

Sorry if this has been alsready asked previously, but I am joining late on this thread, and I read quickly the context.

This is definitely the way to go. Your plugin should use sonar-java at compile time, and need it at runtime, but it should not package it.

Could it be because SonarJava is now lazy-loaded?

In the recent SonarQube versions, we have introduced a mechanism to skip downloading/loading language plugins if they are obviously useless.

  • The Scanner load first non-lazy plugins
  • The Scanner list the project files to analyze
  • The Scanner load lazy plugins, based on files present in the project

SonarJava is lazy, and is only loaded in the second phase if java and jsp files are there.

So a simple fix for you is to also make you plugin lazy, and ensure its loading condition is at least as restrictive as plugins it depends on.

But the problem here is your plugin depends on 2 lazy Sonar plugins, so this is not a situation we support anymore. You will have to split your plugin in 2 different plugins (one for Java, one for Python).

Add

<requiredForLanguages>java,jsp</requiredForLanguages>

(you can omit jsp if you don’t analyze JSP files)
to your Java custom plugin
Add

<requiredForLanguages>py,ipynb</requiredForLanguages>

(you can omit ipynb if you don’t analyze Jupyter Notebook files)
to your Python custom plugin.

3 Likes

Hi Julien,

thanks for your detailed response! Yes, I think that might be the reason, I need to find time to check and verify, but sounds like this will solve the problem.

Alright, we’ll split the plugin into multiple then, thanks!

Best,
Nicklas

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