Locating compiled .class files

The FindBugs plugin works by analyzing the compiled .class files, and then reports the findings on the corresponding source files.
Currently the .class files are located using the built-in java plugin through the DefaultJavaResourceLocator class.

  • The DefaultJavaResourceLocator.classpath() method works but for Gradle multi module projects it also returns the .class files from the dependent projects, so the analysis takes longer
  • The DefaultJavaResourceLocator.classFilesToAnalyze() seems to returns a set of classes built as a side effect of the java analysis. I have bug reports that this seems to return no classes for PR analysis and also seems to have side effect with the ThymeLeaf sensor. Unfortunately cannot reproduce these issues with the community edition

Basically I would like to get the content of sonar.java.binaries but this is not trivial (for instance I’d need to match paths such as /target/**/*-classes/**/*.class)
This is already implemented by the java plugin but it does not seem to be exposed through the API, would it be possible to expose it? Or is there a way to get it already?
Ideally I would also like to get the compiled test classes (so ClasspathForTest)

Hello Guillaume,

Recent versions of the analyzer actually don’t always analyze all files in PR analyses anymore (to save runtime, while maintaining the same quality of reporting). We only do a partial analysis if we are able to leverage cached data. This could be the cause for the bug reports that some classes are not returned for PR analyses. In a custom rule, you can influence this behavior by:

  • either using the cache as well
  • or forcing the analyzer to re-analyze all files, regardless of what data is cached. This will likely result in a performance hit for PR analyses.

You can find more information on this feature here.

Can you tell me which API endpoint exactly you would like to be able to use?

Thanks a lot for the reply @jbeleites

Would you know if there’s a way for the plugins to know if they are running as part of a cache enabled analysis?

Regarding the query to expose sonar.java.binaries I figured it would be clearer if I submitted a PR, so there it is: expose ClasspathForMain.getBinaryDirs() via JavaResourceLocator API by gtoison · Pull Request #4175 · SonarSource/sonar-java · GitHub

Thank you!

Yes, there is! If you are trying to find out within a SonarJava custom rule, you can use the corresponding API in SonarJava. This is available in all ModuleScannerContext, InputFileScannerContext, and JavaFileScannerContext objects. With the CacheContext you can check if caching is enabled.

If you are writing an entire custom plugin, you can find the same information in the SensorContext.

Note that these APIs are relatively new. So if you want to stay backwards-compatible with older versions, you may need to check whether these API endpoints are available to avoid crashing the analysis.

Thanks for the PR, that makes it very clear! I think we should be able to add this functionality into the next SonarJava release.

Thanks for the answers, much appreciated, that’s great!

Another part of the query is that the test binaries are not exposed and it is blocking this issue (you might know the author of the issue!): Apply fb-contrib rules to Unit Tests · Issue #18 · spotbugs/sonar-findbugs · GitHub

Do you think it would be possible to also expose the binary files from ClasspathForTest? This could be added to the JavaResourceLocator, or maybe to a separate new component?
If that helps maybe I can add a proposal as a separate PR?