Making FindBugs work with `downloadOnlyRequired`

Hello, as reported here the FindBugs plugin seems to be missing classes from the sonar-java built-in plugin when running on a non-java JVM project (such as Kotlin).

The plugin is packaged with: <requiredForLanguages>java,scala,jsp,clojure,kotlin</requiredForLanguages> but there does not seem to be a way to declare a dependency on another plugin.

Is there something I’m missing or the workaround is to disable the sonar.plugins.downloadOnlyRequired option?

I also see this error at the end of the scanner logs:

 Error: Exception in thread "Thread-1" java.lang.NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy
	at ch.qos.logback.classic.spi.LoggingEvent.<init>(LoggingEvent.java:145)
	at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:424)
	at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:386)
	at ch.qos.logback.classic.Logger.error(Logger.java:543)
	at org.eclipse.jgit.internal.util.ShutdownHook.cleanup(ShutdownHook.java:87)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.ClassNotFoundException: ch.qos.logback.classic.spi.ThrowableProxy
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
	at org.sonarsource.scanner.api.internal.IsolatedClassloader.loadClass(IsolatedClassloader.java:82)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
	... 6 more

Hello Guillaume,

Thanks for reporting this use case.

We will discuss it some more internally to see what solutions there could be for addressing this particular use case. In the meantime, here are two ideas:

  • If you analyze non-java code, you may not need to depend on the sonar-java plugin for projects that don’t contain Java code. So perhaps you can check if the sonar-java plugin is available / catch if it isn’t and only analyze non-Java code in that case. If I’m not mistaken, you don’t have a huge amount of dependencies on sonar-java anyway, so perhaps it is worth thinking about removing that dependency entirely and implementing the missing logic on the FindBugs side.
  • As already stated in the issue you linked to, as a workaround, users can disable the on-demand plugin downloading by setting sonar.plugins.downloadOnlyRequired to false.

I’ll provide an update if we come up with a better solution, in the meantime I hope these two options help!

Thanks Johann,
The plugin uses the JavaResourceLocator.classpath() which is useful for non Java projects too.
There’s also JavaResourceLocator.classFilesToAnalyze(), I think these are also populated for non Java projects.

Also the JavaResourceLocator is used via constructor injection, so the class currently needs to be available for the plugin to even start.
Is there a better way to test its availability and to retrieve it?

I seem to be running into the same problem with the error prone plugin: it also uses JavaResourceLocator.classpath() and is packaged with <requiredForLanguages>java</requiredForLanguages>.
Even for projects with some java files the JavaResourceLocator is missing:

Hello @jbeleites,
I understand why the issue happens for the Findbugs plugin and for non-java projects: there are no java files so the built-in Java plugin is not downloaded, and the JavaResourceLocator class is missing.
However for the errorprone plugin I have the issue for Java projects, so I would expect that the built-in Java plugin is downloaded, but it does not seem to happen.
Could it be because the plugins are executed in alphabetical order? Does it matter if the quality profile has rules from the built-in Java plugin?

I’ve tried adding <basePlugin>java</basePlugin> to the packaging and seemed to get a different error:

Caused by: java.io.IOException: Resource not found in the classpath: /org/sonar/l10n/java/rules/java/Sonar_way_profile.json
>       at org.sonarsource.analyzer.commons.Resources.toString(Resources.java:47)
>       at org.sonarsource.analyzer.commons.BuiltInQualityProfileJsonLoader.loadActiveKeysFromJsonProfile(BuiltInQualityProfileJsonLoader.java:73)