SonarQube doesn't properly set the thread context class loader when invoking plugins that use the child-first loading strategy

When invoking the usage of a plugin that requests a child-first class loading strategy via setting useChildFirstClassLoader in its Maven configuration, SonarQube does not set the thread’s context class loader to that of the child. This results in the plugin receiving the class loader of the parent (SonarQube), which will throw a ClassCastException if there are any conflicting jars used between the plugin the parent.

This was experienced with the Fortify plugin and SonarQube 7.7 Enterprise Edition because SonarQube Developer Edition and Enterprise Edition both ship with /lib/common/javax.ws.rs-api-2.1.jar, while the Fortify plugin ships with jakarta.ws.rs-api-2.1.5.jar. It appears that SonarQube Community Edition does not ship with the JAX-RS jar and thus does not exhibit the issue (in this case), but the problem would still arise if there were to be a jar conflict.

We resolved this in the Fortify plugin by temporarily setting the class loader of the thread whenever the plugin was invoked, but all plugins should not have to do this; SonarQube should be setting the class loader for the executing thread properly and then resetting it if needed after the plugin has finished executing.

More details are available here, where the issue in the Fortify plugin was discussed and resolved:

Hi Michael,

Thanks for this nice investigation.
Changing the thread context when executing plugins code is possible only for a few extension points like Sensor. That could not be applied to many other extensions. As I’m not in favor of having different behaviors between extensions, I suggest to not change the classloader mechanism and to keep the trick in your plugin.

Please note also that the recommended way to import issues from 3rd-party analyzers is to use intermediary JSON files in this format: https://docs.sonarqube.org/latest/analysis/generic-issue/. That implies to extract the Fortify importer out of the SonarQube scanner.

Regards

Thanks Simon.

If this issue will not be addressed in SonarQube, I would suggest that the requirement to safeguard one’s plugin via the approach taken for Fortify be documented on the Build Plugin page here:

https://docs.sonarqube.org/display/DEV/Build+Plugin

Other developers may run into this issue and they should be advised of how to work around it.