Access denied ("java.lang.RuntimePermission" "getClassLoader") for Plugin in Computing Engine of SQ 8.0 and SQ 8.1

Hi,

the Sonargraph plugin (https://github.com/sonargraph/sonar-sonargraph-integration) runs fine on OpenJDK11 and SQ 7.9.1, but fails on the computing engine for SQ 8.0 and 8.1. I tweaked the logging and got the following error in the ce.log:
java.security.AccessControlException: access denied (“java.lang.RuntimePermission” “createClassLoader”)
at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.base/java.security.AccessController.checkPermission(AccessController.java:895)
at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:322)
at java.base/java.lang.SecurityManager.checkCreateClassLoader(SecurityManager.java:384)
at java.base/java.lang.ClassLoader.checkCreateClassLoader(ClassLoader.java:369)
at java.base/java.lang.ClassLoader.checkCreateClassLoader(ClassLoader.java:359)
at java.base/java.lang.ClassLoader.(ClassLoader.java:475)
at com.hello2morrow.sonargraph.integration.access.foundation.AggregatingClassLoader.(AggregatingClassLoader.java:33)
at com.hello2morrow.sonargraph.integration.access.persistence.JaxbAdapter.(JaxbAdapter.java:115)

I have already posted a question with the tag #plugins a month ago, but haven’t got any feedback so far, thus I try it here (java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createClassLoader") on SonarQube 8).

Is there any workaround for this? Where are these kind of security settings configured in SonarQube?

Thanks a lot for any help on this,

Ingmar

P.S.: Even if I don’t use the AggregatingClassLoader (we need it for OSGi environments), the processing of the XML fails for the same reason with a similar exception way down in the XML library:
javax.xml.bind.UnmarshalException: access denied (“java.lang.RuntimePermission” “getClassLoader”)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:744)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleError(UnmarshallingContext.java:771)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleError(UnmarshallingContext.java:767)
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$13.parse(RuntimeBuiltinLeafInfoImpl.java:599)
at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$13.parse(RuntimeBuiltinLeafInfoImpl.java:572)
at com.sun.xml.bind.v2.runtime.FilterTransducer.parse(FilterTransducer.java:78)
at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.parse(TransducedAccessor.java:239)
at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:212)
at com.sun.xml.bind.v2.runtime.unmarshaller.ProxyLoader.startElement(ProxyLoader.java:60)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$IntercepterLoader.startElement(ElementBeanInfoImpl.java:253)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:577)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:556)
at com.sun.xml.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:102)
at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:168)
at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:510)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3060)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:836)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:534)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:888)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:824)
at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1216)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:635)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:258)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:229)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:170)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:209)
at com.hello2morrow.sonargraph.integration.access.persistence.JaxbAdapter.load(JaxbAdapter.java:228)
at com.hello2morrow.sonargraph.integration.access.persistence.XmlExportMetaDataReader.readMetaDataFromStream(XmlExportMetaDataReader.java:102)
at com.hello2morrow.sonargraph.integration.access.controller.MetaDataControllerImpl.internLoadExportMetaData(MetaDataControllerImpl.java:86)
at com.hello2morrow.sonargraph.integration.access.controller.MetaDataControllerImpl.loadExportMetaData(MetaDataControllerImpl.java:73)
at com.hello2morrow.sonargraph.integration.sonarqube.SonargraphBase.readBuiltInMetaData(SonargraphBase.java:329)
at com.hello2morrow.sonargraph.integration.sonarqube.SonargraphMetrics.getMetrics(SonargraphMetrics.java:76)

Hi,
I confirm that it’s a new security restriction that we introduced in v8.0. Using the classloader allows plugins to have access to sensitive data and classes that should be out of scope for plugins.
I’m afraid the workaround will have to be done on your side by avoiding using classloaders.

Hi Duarte,

thanks fro the quick reply! I will have to refactor our code then…

Did I miss a note about this change in the security restrictions? I realize that the usage of XML somehow marks me an old guy ;-), but I could imagine that other plugins are affected as well by this change. Or is the usage of classloaders very uncommon? It would be nice as a plugin developer to know these kind of changes beforehand, so that users don’t get frustrated.
Btw, the error is not showing up prominentely anywhere in the SonarQube UI, you have to dig into the logs to find out, which plugin caused the analysis to fail.

You’re right in that we didn’t include this change in the release notes. We didn’t think it would have an impact in plugins that work properly with the API and this is also why there was no warning in advance (and also no deprecation period). I’m sorry that it broke your plugin.

We had other plugins affected with other security restrictions that were also introduced in v8.0 and that were fixed in v8.1. I’d say that in the context of SonarQube plugins, the use of classloaders is very uncommon and shouldn’t be necessary.

I understand that requirements for cloud-based services need to be more restrictive. And yes, I was hoping for this issue to get fixed in v8.1, too.
Apart from a warning note to plugin developers, it would be great if the security settings are configurable for those who manage their own SQ instance. Even if the plugin’s code itself does not need classloaders, libraries that are used by those plugins might require them (as in my case the XML lib). As a developer, you only see the tip of the iceberg, if you don’t use static code analysis on your external dependencies.
As I pointed out above, the analysis is marked as failed with no proper reason visible in the SQ UI. This puts the stability and reputation of the whole platform at risk, and that’s a shame.
Thanks again for your support!

I am running into this too while trying to load the Clojure runtime in my plugin. Clojure uses its own context classloader, so I have to get the current thread’s context classloader, change the current thread’s context classloader to the one my plugin class is using, and then change it back when I’m done. Is there a workaround for this so I can use Clojure in my plugin?