Custom rules in SonarLint not executed

1,132 views
Skip to first unread message

Björn Kautler

unread,
Jan 18, 2018, 9:57:49 AM1/18/18
to SonarLint
Hi,

we currently have SQ 6.5.
I have the SL plugin 3.1.0.2244 installed in IntelliJ.
We have some custom SonarJava rules in effect on SQ.
Now if I analyze a file, it seems the custom rules are not being evaluated.
If I do a local analysis using the Gradle plugin with "sonar.analysis.mode" set to "issues" and "sonar.report.export.path" set, I see that the issue is found correctly.
The SL log tab shows that the correct configuration of the correct SQ instance is used for analysis.
Do you have any idea why this is not working correctly?
Does anything special has to be done to get this working?

Regards
Björn

Julien HENRY

unread,
Jan 19, 2018, 3:19:22 PM1/19/18
to Björn Kautler, SonarLint
Hi Björn,

Have you flagged your custom rule plugin as compatible with SonarLint?

++

Julien Henry | SonarSource

Developer

https://sonarsource.com


--
You received this message because you are subscribed to the Google Groups "SonarLint" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sonarlint+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sonarlint/3c56a416-2cf1-4d3e-a5af-802aa6755f69%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Björn Kautler

unread,
Jan 22, 2018, 5:43:47 AM1/22/18
to SonarLint
Hi Julien,

that is probably the case, thanks.
I didn't devlop the rules, but the one who did wondered that they are not shown too and just thought it is not supported yet documented.
Maybe the docu could be a bit more explicit. E. g. where it says "SonarLint supports the SonarSource code analyzers (SonarJava, SonarJS…) as well as custom rules that extend these code analyzers.", this for me means that all custom rules are supported. Maybe there at least a half-sentence like "if they declare SonarLint support" or something like that can be added to make it clear that not all custom rules are automatically supported.

One more question, can you tell me why "sonarLintSupported = true" is not the default behavior and when "true" should be preferred, when "false"?
The only thing I can come up right now is if an analyzer needs much time for its analysis and thus is not suited for an on-the-fly analysis.
But I'd expect that most rules are fast and thus "true" would be a more suitable default.

Regards
Björn


Am Freitag, 19. Januar 2018 21:19:22 UTC+1 schrieb Julien HENRY:
Hi Björn,

Have you flagged your custom rule plugin as compatible with SonarLint?

++

Julien Henry | SonarSource

Developer

https://sonarsource.com


2018-01-18 15:57 GMT+01:00 Björn Kautler <Bjo...@kautler.net>:
Hi,

we currently have SQ 6.5.
I have the SL plugin 3.1.0.2244 installed in IntelliJ.
We have some custom SonarJava rules in effect on SQ.
Now if I analyze a file, it seems the custom rules are not being evaluated.
If I do a local analysis using the Gradle plugin with "sonar.analysis.mode" set to "issues" and "sonar.report.export.path" set, I see that the issue is found correctly.
The SL log tab shows that the correct configuration of the correct SQ instance is used for analysis.
Do you have any idea why this is not working correctly?
Does anything special has to be done to get this working?

Regards
Björn

--
You received this message because you are subscribed to the Google Groups "SonarLint" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sonarlint+...@googlegroups.com.

Julien HENRY

unread,
Jan 22, 2018, 5:57:01 AM1/22/18
to Björn Kautler, SonarLint
We have no way to know what a SonarQube plugin is doing without first trying to load it. And loading it can make SonarLint crash / be very slow. That's why we took the conservative approach of not loading any plugin by default, and requesting people to explicitly flag their plugins as compatible with SonarLint when they are confident enough to do it.
In theory, custom rule plugins should be fine. But a given plugin can also be a mix of custom rules, custom Sensors, server side extensions, ... and so special care should be taken to ensure that only relevant code is loaded in SonarLint.

I agree that documentation could be improved, I will look into it.

++



Julien Henry | SonarSource

Developer

https://sonarsource.com


To unsubscribe from this group and stop receiving emails from it, send an email to sonarlint+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sonarlint/e5637a20-1a93-4534-86de-0b2ec9abdeac%40googlegroups.com.

Björn Kautler

unread,
Jan 22, 2018, 7:04:25 AM1/22/18
to SonarLint
Ah, I see, thanks for the info.

Cheers
Björn

Björn Kautler

unread,
Jan 24, 2018, 7:57:08 AM1/24/18
to SonarLint
Hey Julien,

one more question, is this broken in Eclipse?
Our rule developer now added this SonarLint tagging and it works fine in IntelliJ.
But in Eclipse he gets the following on analyzing:

Error during execution of SonarLint analysis java.lang.IllegalStateException: Unable to load component class org.sonar.java.SonarComponents
 at org.sonarsource.sonarlint.core.container.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:59)
 at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:632)
 at org.picocontainer.parameters.BasicComponentParameter$1.resolveInstance(BasicComponentParameter.java:118)
 at org.picocontainer.parameters.ComponentParameter$1.resolveInstance(ComponentParameter.java:136)

Regards
Björn

Julien HENRY

unread,
Jan 24, 2018, 8:23:21 AM1/24/18
to Björn Kautler, SonarLint
Hi Björn,

It should work the same on Eclipse. Can you provide a full stacktrace (this one look truncated). Also please give me the version of SonarLint for Eclipse and SonarLint for IntelliJ.

++

Julien Henry | SonarSource

Developer

https://sonarsource.com


To unsubscribe from this group and stop receiving emails from it, send an email to sonarlint+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sonarlint/8bf9d710-bef8-4e01-b4f1-aa3949806360%40googlegroups.com.

Björn Kautler

unread,
Jan 24, 2018, 8:29:13 AM1/24/18
to SonarLint
Latest on both,
3.3.1.201712071600 on Eclipse,
3.1.0.2244 on IntelliJ.

Yes, the stack trace was truncated (didn't know).
Here the full stack trace:

SonarLint analysis of file ***.java...

Error during execution of SonarLint analysis

java.lang.IllegalStateException: Unable to load component class org.sonar.java.SonarComponents

                at org.sonarsource.sonarlint.core.container.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:59)

                at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:632)

                at org.picocontainer.parameters.BasicComponentParameter$1.resolveInstance(BasicComponentParameter.java:118)

                at org.picocontainer.parameters.ComponentParameter$1.resolveInstance(ComponentParameter.java:136)

                at org.picocontainer.injectors.SingleMemberInjector.getParameter(SingleMemberInjector.java:78)

                at org.picocontainer.injectors.ConstructorInjector$CtorAndAdapters.getParameterArguments(ConstructorInjector.java:309)

                at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:335)

                at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)

                at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)

                at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)

                at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)

                at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)

                at org.picocontainer.DefaultPicoContainer.getLocalInstance(DefaultPicoContainer.java:606)

                at org.picocontainer.DefaultPicoContainer.getComponents(DefaultPicoContainer.java:587)

                at org.sonarsource.sonarlint.core.container.ComponentContainer.getComponentsByType(ComponentContainer.java:266)

                at org.sonarsource.sonarlint.core.analyzer.sensor.ScannerExtensionDictionnary.completeBatchExtensions(ScannerExtensionDictionnary.java:105)

                at org.sonarsource.sonarlint.core.analyzer.sensor.ScannerExtensionDictionnary.getExtensions(ScannerExtensionDictionnary.java:99)

                at org.sonarsource.sonarlint.core.analyzer.sensor.ScannerExtensionDictionnary.getFilteredExtensions(ScannerExtensionDictionnary.java:87)

                at org.sonarsource.sonarlint.core.analyzer.sensor.ScannerExtensionDictionnary.select(ScannerExtensionDictionnary.java:54)

                at org.sonarsource.sonarlint.core.analyzer.sensor.AllSensorsExecutor.execute(AllSensorsExecutor.java:59)

                at org.sonarsource.sonarlint.core.analyzer.sensor.PhaseExecutor.execute(PhaseExecutor.java:36)

                at org.sonarsource.sonarlint.core.container.analysis.AnalysisContainer.doAfterStart(AnalysisContainer.java:142)

                at org.sonarsource.sonarlint.core.container.ComponentContainer.startComponents(ComponentContainer.java:125)

                at org.sonarsource.sonarlint.core.container.ComponentContainer.execute(ComponentContainer.java:110)

                at org.sonarsource.sonarlint.core.container.storage.StorageAnalyzer.analyze(StorageAnalyzer.java:74)

                at org.sonarsource.sonarlint.core.container.storage.StorageContainerHandler.analyze(StorageContainerHandler.java:69)

                at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.lambda$analyze$0(ConnectedSonarLintEngineImpl.java:154)

                at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.withReadLock(ConnectedSonarLintEngineImpl.java:338)

                at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.withReadLock(ConnectedSonarLintEngineImpl.java:328)

                at org.sonarsource.sonarlint.core.ConnectedSonarLintEngineImpl.analyze(ConnectedSonarLintEngineImpl.java:152)

                at org.sonarlint.eclipse.core.internal.server.Server.runAnalysis(Server.java:275)

                at org.sonarlint.eclipse.core.internal.jobs.AnalyzeProjectJob.run(AnalyzeProjectJob.java:426)

                at org.sonarlint.eclipse.core.internal.jobs.AnalyzeProjectJob.runAnalysisAndUpdateMarkers(AnalyzeProjectJob.java:182)

                at org.sonarlint.eclipse.core.internal.jobs.AnalyzeProjectJob.doRun(AnalyzeProjectJob.java:143)

                at org.sonarlint.eclipse.core.internal.jobs.AbstractSonarProjectJob.runInWorkspace(AbstractSonarProjectJob.java:43)

                at org.eclipse.core.internal.resources.InternalWorkspaceJob.run(InternalWorkspaceJob.java:39)

                at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56)

Caused by: java.lang.NoClassDefFoundError: Could not initialize class de.empic.sonar.rule.CheckSerializableInRemoteInterfaces

                at sun.reflect.GeneratedConstructorAccessor294.newInstance(Unknown Source)

                at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

                at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

                at java.lang.Class.newInstance(Class.java:442)

                at org.sonar.api.batch.rule.Checks.instantiate(Checks.java:160)

                at org.sonar.api.batch.rule.Checks.addAnnotatedChecks(Checks.java:136)

                at org.sonar.java.SonarComponents.registerCheckClasses(SonarComponents.java:149)

                at org.sonar.java.SonarComponents.<init>(SonarComponents.java:98)

                at sun.reflect.GeneratedConstructorAccessor291.newInstance(Unknown Source)

                at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

                at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

                at org.picocontainer.injectors.AbstractInjector.newInstance(AbstractInjector.java:145)

                at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:342)

                at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)

                at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)

                at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)

                at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)

                at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)

                at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)

                at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)

                at org.sonarsource.sonarlint.core.container.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:57)

                ... 36 more

Julien HENRY

unread,
Jan 24, 2018, 8:45:15 AM1/24/18
to Björn Kautler, SonarLint
Do you have the same issue on all Eclipse instances, or only on a particular one? The only idea I have would be that your custom rule plugin is somehow corrupted in SonarLint local storage.

To investigate, please follow those steps:
  1) open <your SQ server>/api/plugins/installed
  2) look for the md5 checksum of your custom plugin
{"key": "yourcustompluginkey","sonarLintSupported": true,
"hash": "thehash",

  3) find the folder where plugin is locally stored by SonarLint. By default it is ~/.sonarlint/plugins/<thehash>

In this folder you should find a copy of the plugin jar 
  -> compute its md5 checksum to verify it is not corrupted
  -> ensure that class de.empic.sonar.rule.CheckSerializableInRemoteInterfaces is inside the JAR

If it appear that JAR is corrupted, it might come from an I/O error or an antivirus altering the file. To fix the problem, simply delete the folder ~/.sonarlint/plugins/<thehash> and update binding in SonarLint.


Julien Henry | SonarSource

Developer

https://sonarsource.com


To unsubscribe from this group and stop receiving emails from it, send an email to sonarlint+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sonarlint/1ba7b8e6-9b48-46d3-9dce-15f53469a41f%40googlegroups.com.

Björn Kautler

unread,
Jan 24, 2018, 10:42:31 AM1/24/18
to SonarLint
Ah, I had a look at the stack trace myself and tried it in Eclipse too.
As almost always with NoClassDefFoundError, these are consecutive faults.
On first try after Eclipse restart the stack trace is


java.lang.IllegalStateException: Unable to load component class org.sonar.java.SonarComponents
...
Caused by: java.lang.NoClassDefFoundError: org/apache/log4j/Logger
 at de.empic.sonar.rule.CheckSerializableInRemoteInterfaces.<clinit>(CheckSerializableInRemoteInterfaces.java:34)
...
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
...

The dev used log4j as provided lib in the custom rules and it seems when running in Gradle and IntelliJ, log4j is present, when running in Eclipse it is not and thus it fails.

Sorry for wasting your time. :-)

Cheers
Björn

Thomas Schindler

unread,
Jan 25, 2018, 3:42:20 AM1/25/18
to SonarLint
Hi Julien, Hi Björn,

first of all thank you for your investigation in this case. As I'm the main developer for this SonarQube plugin, I'd like to jump into the discussion. 

I checked the maven configuration of the POM and found out, that the log4j is a provided dependency. I tried to change this to "compile", but it turns out that this is not possible as the sonar packaging plugin for maven expects it to be provided:

[INFO] --- sonar-packaging-maven-plugin:1.18.0.372:check (default-check) @ eap-sonar-rules ---
[DEBUG] Configuring mojo org.sonarsource.sonar-packaging-maven-plugin:sonar-packaging-maven-plugin:1.18.0.372:check from plugin realm ClassRealm[extension>org.sonarsource.sonar-packaging-maven-plugin:sonar-packaging-maven-plugin:1.18.0.372, parent: java.net.URLClassLoader@3f99bd52]
[DEBUG] Configuring mojo 'org.sonarsource.sonar-packaging-maven-plugin:sonar-packaging-maven-plugin:1.18.0.372:check' with basic configurator -->
[DEBUG]   (f) addMavenDescriptor = true
[DEBUG]   (f) appDirectory = D:\workspaces\java-custom-rules\EapSonarRules\target\eap-sonar-rules-3.1.2
[DEBUG]   (f) classesDirectory = D:\workspaces\java-custom-rules\EapSonarRules\target\classes
[DEBUG]   (f) finalName = eap-sonar-rules-3.1.2
[DEBUG]   (f) outputDirectory = D:\workspaces\java-custom-rules\EapSonarRules\target
[DEBUG]   (f) pluginClass = de.empic.sonar.plugin.EapJavaExtensionPlugin
[DEBUG]   (f) pluginDescription = Custom Sonar rules for validation of EAP source code
[DEBUG]   (f) pluginIssueTrackerUrl = https://gitlab.empic.de/developers/empic_sonar_rules/issues
[DEBUG]   (f) pluginKey = eap-sonar-rules
[DEBUG]   (f) pluginName = EAP Sonar Rules
[DEBUG]   (f) pluginOrganizationName = EMPIC GmbH
[DEBUG]   (f) pluginOrganizationUrl = http://www.empic.aero
[DEBUG]   (f) project = MavenProject: de.empic:eap-sonar-rules:3.1.2 @ D:\workspaces\java-custom-rules\EapSonarRules\pom.xml
[DEBUG]   (f) session = org.apache.maven.execution.MavenSession@606fc505
[DEBUG]   (f) skipDependenciesPackaging = false
[DEBUG]   (f) sonarLintSupported = true
[DEBUG]   (f) sonarQubeMinVersion = 6.5
[DEBUG]   (f) useChildFirstClassLoader = false
[DEBUG] -- end configuration --
[ERROR] This dependency must be declared with scope <provided>: log4j:log4j:jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

I don't know why log4j cannot be packaged with a SonarQube plugin, but that given, I investigated further, why it is not available in Eclipse whe the analysis is started. I turned on the verbose output in the SonarLint Console:

Starting SonarLint for Eclipse 3.3.1.201712071600
Trigger: STARTUP
SonarLint analysis of file /eap-webclient/mod-med src web java/de/empic/web/med/model/CommentMedicalQuestion.java...
Connected mode (using configuration of 'de.empic.eap:EAP:eap-webclient' in server 'metrics.empic.de')
Starting analysis with configuration:
[
  moduleKey: de.empic.eap:EAP:eap-webclient
  baseDir: D:\workspace\empic_trunk\eap-webclient
  workDir: D:\workspaces\HEAD\.metadata\.plugins\org.eclipse.core.resources\.projects\eap-webclient\org.sonarlint.eclipse.core
  extraProperties: {sonar.java.source=1.8, sonar.java.target=1.8, sonar.libraries=C:\Program Files\Java\jdk1.8.0_151\jre\lib\resources.jar, ... , D:\empic-libs\ivy\log4j\log4j\1.2.17\log4j-1.2.17.jar, ..., D:/workspace/empic_trunk/v-nox/build/classes/eclipse,   sonar.binaries=D:/workspace/empic_trunk/eap-webclient/build/classes/eclipse, sonar.java.binaries=D:/workspace/empic_trunk/eap-webclient/build/classes/eclipse, sonar.java.test.binaries=D:/workspace/empic_trunk/eap-webclient/build/classes/eclipse}
  inputFiles: [
    D:\workspace\empic_trunk\med\src\web\java\de\empic\web\med\model\CommentMedicalQuestion.java (UTF-8)
  ]
]
.
.
.

I attached the complete logfile with stacktrace.

As you can see, the path to the log4j library is contained in the sonar.libraries property. Therefore I don't understand why there is a "java.lang.ClassNotFoundException: org.apache.log4j.Logger" when loading the plugins classes. 

Could there be some problem with the sonar classloader?

Best regards
Thomas
sonarLint2.log

Julien HENRY

unread,
Jan 25, 2018, 4:10:27 AM1/25/18
to Thomas Schindler, SonarLint
Hi Thomas,

TL;DR Don't use log4j, but instead slf4j, or better: use the org.sonar.api.utils.log.Logger facade.

Logging is a very complex topic. We don't want each plugin to embed its own logging deps, because we want to centralize the ability to configure log level, and we also need to redirect logs to the appropriate output on scanner side, without messing up the client logging configuration. On scanner side, we are providing slf4j + all possible bridges (like log4j over slf4j) for historical reasons, and because some plugins used to embed third party analyzers (like PMD, Findbugs) where you can't easily decide to change the logging facade.

Since SonarLint was a new product, we decided to only support slf4j and org.sonar.api.utils.log.Logger facade. The fact it is working in IntelliJ is likely an unexpected leak of the log4j JAR available in IDE classloader. I created a ticket to fix that:

++



Julien Henry | SonarSource

Developer

https://sonarsource.com


--
You received this message because you are subscribed to the Google Groups "SonarLint" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sonarlint+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sonarlint/667359ec-9094-47ca-866b-5385fd294d4b%40googlegroups.com.

Thomas Schindler

unread,
Jan 25, 2018, 5:07:11 AM1/25/18
to SonarLint
Hi Julien,

thank's a lot for the help. Using the org.sonar.api.utils.log.Logger facade fixed the issue.

Regards
Thomas

Am Donnerstag, 18. Januar 2018 15:57:49 UTC+1 schrieb Björn Kautler:
Reply all
Reply to author
Forward
0 new messages