Error when reporting issues with SonarLint (java) plugin

  • Operating system: mac OS Ventura 13.4
  • SonarLint plugin version: 3.18
  • Programming language you’re coding in: Java
  • Is connected mode used: yes
    • Connected to SonarQube (and which version): 10.0-community

And a thorough description of the problem / question:

Hi,

I have a strange error from time to time when I use my custom sonarlint/qube plugin.

The plugin is based on sonar-java, just adds new rules.

At first the issues (rule violations) are successfully detected and reported using sonar-java’s built-in “reportIssue” function. After switching to another file (.java) and reopening the previous file, I get the following error:

Error - 13:49:57.293] java.lang.UnsupportedOperationException
	at java.base/java.util.ImmutableCollections.uoe(Unknown Source)
	at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(Unknown Source)
	at org.sonarsource.sonarlint.ls.AnalysisTaskExecutor.lambda$analyzeConnected$28(AnalysisTaskExecutor.java:508)
	at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.streamIssue(ConnectedSonarLintEngineImpl.java:223)
	at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.lambda$analyze$1(ConnectedSonarLintEngineImpl.java:216)
	at org.sonarsource.sonarlint.core.analysis.container.analysis.IssueListenerHolder.handle(IssueListenerHolder.java:37)
	at org.sonarsource.sonarlint.core.analysis.container.analysis.sensor.SonarLintSensorStorage.store(SonarLintSensorStorage.java:92)
	at org.sonarsource.sonarlint.core.analysis.sonarapi.DefaultSonarLintIssue.doSave(DefaultSonarLintIssue.java:172)
	at org.sonarsource.sonarlint.core.analysis.sonarapi.DefaultStorable.save(DefaultStorable.java:42)
	at org.sonar.java.reporting.JavaIssue.save(JavaIssue.java:103)
	at org.sonar.java.SonarComponents.reportIssue(SonarComponents.java:314)
	at org.sonar.java.SonarComponents.lambda$reportIssue$3(SonarComponents.java:293)
	at java.base/java.util.Optional.ifPresent(Unknown Source)
	at org.sonar.java.SonarComponents.reportIssue(SonarComponents.java:287)
	at org.sonar.java.model.DefaultModuleScannerContext.reportIssue(DefaultModuleScannerContext.java:76)
	at org.sonar.java.model.DefaultJavaFileScannerContext.reportIssueWithFlow(DefaultJavaFileScannerContext.java:152)
	at org.sonar.java.model.DefaultJavaFileScannerContext.reportIssue(DefaultJavaFileScannerContext.java:145)
	at org.sonar.java.model.DefaultJavaFileScannerContext.reportIssue(DefaultJavaFileScannerContext.java:100)
	at org.sonar.plugins.java.api.IssuableSubscriptionVisitor.reportIssue(IssuableSubscriptionVisitor.java:62)

I looked a little bit into the code and in org/sonarsource/sonarlint/ls/AnalysisTaskExecutor.java I might found the relevant code:

IssueListener accumulatorIssueListener = i -> {
    var inputFile = i.getInputFile();
    // FIXME SLVSCODE-255 support project level issues
    if (inputFile != null) {
      issuesPerFiles.computeIfAbsent(inputFile.getClientObject(), uri -> new ArrayList<>()).add(i);
    }
  };

This function is called. Since I am reporting multiple issues for one file, it could be that the input file (key) is already in the hashmap, so it tries to append the new issue to the list. The list should be mutable (because of new ArrayList<>()), but it seems that it is not.

I don’t think there’s a bug in my code, because I’m just calling the reportIssue function, but I’m also not sure where the bug is then.

Hope you can help here, many thanks!

Hello, welcome to the community! And thanks for reporting this behavior.

I haven’t been able to reproduce this exact behavior. However, I noticed the following code a few lines below in that same AnalysisTaskExecutor class:

var issues = issuesPerFiles.computeIfAbsent(fileUri, uri -> List.of());

… which could be the cause for immutable lists being present in the map, although it should not be the case yet when the use of reportIssue leads to add being called: the lazy initialization with List.of() is in a “post analysis” task that is supposed to run after the rest of the analysis, and I’m not sure how it could end up being called before a plugin tries to report issues.

(On a side note, I believe that the mentioned line should not modify the Map at this stage and use getOrDefault instead of computeIfAbsent).

Would it be possible for you to (privately) share the code for your plugin, maybe with some source code on which the analysis triggers the issue?

1 Like

Hi Jean-Baptiste, thanks for your help!

Interesting, yes I can share my code and examples with you to find the problem. Do you have a preferred method for me to send you the code?

I use an Observable pattern to have “sub”-BaseTreeVisitors of a current rule report findings to the “main” rule (IssuableSubscriptionVisitor), which then handles the issue report in the rule context. I think this is the main architectural difference between my rule extension and the tutorial rule extension for sonar-java.

Maybe this is could cause the problem.

Hello, we just released SonarLint for VSCode 3.19.2 with a change that should fix this issue.

If it does not, then we’ll find a way :slight_smile: e.g. I can create a private GitHub repository for you to share the code.

2 Likes

Hello Jean-Baptiste, thank you very much! Tested it, everything works fine now.

1 Like

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