Is the maven scanner forking a new JVM?

Hello,
I am writing a plugin to report errorprone findings in SonarQube.
Since errorprone uses some internal JDK API (and since JEP-396) it needs the JVM to start with some options such as: --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED.

I have integration tests running the plugin an analysing a sample maven project, it is working as expected on SonarQube 10.4 however on 10.6 (or 10.7 or 24.12) I’m getting an error indicating that the JVM options were not enabled:

 [INFO] Sensor Errorprone sensor [errorawaysonar]
 [ERROR] [stderr] Exception in thread "main" java.util.ServiceConfigurationError: com.google.errorprone.bugpatterns.BugChecker: com.uber.nullaway.NullAway Unable to get public no-arg constructor
 [ERROR] [stderr] 	at java.base/java.util.ServiceLoader.fail(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.util.ServiceLoader.getConstructor(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.util.ServiceLoader$2.hasNext(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.util.ServiceLoader$3.hasNext(Unknown Source)
 [ERROR] [stderr] 	at com.github.erroraway.sonarqube.ErrorAwaySensor.execute(ErrorAwaySensor.java:86)
 [ERROR] [stderr] 	at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:64)
 [ERROR] [stderr] 	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:88)
 [ERROR] [stderr] 	at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:61)
 [ERROR] [stderr] 	at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:79)
 [ERROR] [stderr] 	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:61)
 [ERROR] [stderr] 	at org.sonar.scanner.scan.SpringModuleScanContainer.doAfterStart(SpringModuleScanContainer.java:82)
 [ERROR] [stderr] 	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:226)
 [ERROR] [stderr] 	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:205)
 [ERROR] [stderr] 	at org.sonar.scanner.scan.SpringProjectScanContainer.scan(SpringProjectScanContainer.java:204)
 [ERROR] [stderr] 	at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:200)
 [ERROR] [stderr] 	at org.sonar.scanner.scan.SpringProjectScanContainer.doAfterStart(SpringProjectScanContainer.java:173)
 [ERROR] [stderr] 	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:226)
 [ERROR] [stderr] 	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:205)
 [ERROR] [stderr] 	at org.sonar.scanner.bootstrap.SpringScannerContainer.doAfterStart(SpringScannerContainer.java:351)
 [ERROR] [stderr] 	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:226)
 [ERROR] [stderr] 	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:205)
 [ERROR] [stderr] 	at org.sonar.scanner.bootstrap.SpringGlobalContainer.doAfterStart(SpringGlobalContainer.java:144)
 [ERROR] [stderr] 	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:226)
 [ERROR] [stderr] 	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:205)
 [ERROR] [stderr] 	at org.sonar.scanner.bootstrap.ScannerMain.runScannerEngine(ScannerMain.java:149)
 [ERROR] [stderr] 	at org.sonar.scanner.bootstrap.ScannerMain.run(ScannerMain.java:66)
 [ERROR] [stderr] 	at org.sonar.scanner.bootstrap.ScannerMain.main(ScannerMain.java:52)
 [ERROR] [stderr] Caused by: java.lang.NoClassDefFoundError: com/sun/source/tree/Tree
 [ERROR] [stderr] 	at java.base/java.lang.Class.getDeclaredConstructors0(Native Method)
 [ERROR] [stderr] 	at java.base/java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.lang.Class.getConstructor0(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.lang.Class.getConstructor(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.util.ServiceLoader$1.run(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.util.ServiceLoader$1.run(Unknown Source)
 [ERROR] [stderr] 	at java.base/java.security.AccessController.doPrivileged(Unknown Source)
 [ERROR] [stderr] 	... 28 more
 [ERROR] [stderr] Caused by: java.lang.ClassNotFoundException: com.sun.source.tree.Tree
 [ERROR] [stderr] 	at org.sonar.classloader.ParentFirstStrategy.loadClass(ParentFirstStrategy.java:39)
 [ERROR] [stderr] 	at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:97)
 [ERROR] [stderr] 	at org.sonar.classloader.ClassRealm.loadClass(ClassRealm.java:86)
 [ERROR] [stderr] 	... 35 more

Indeed when comparing the logs I see that when running on SonarQube 10.7 the scanner seems to provision a JVM:

 [INFO] Java 17.0.13 Eclipse Adoptium (64-bit)
 [INFO] Linux 6.5.0-1025-azure (amd64)
 [INFO] MAVEN_OPTS=--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED  -Djava.awt.headless=true
 [INFO] User cache: /home/runner/.sonar/cache
 [INFO] JRE provisioning: os[linux], arch[x86_64]
 [INFO] Communicating with SonarQube Server 10.7.0.96327
 [INFO] Starting SonarScanner Engine...
 [INFO] Java 17.0.11 Eclipse Adoptium (64-bit)
 [INFO] Load global settings
 [INFO] Load global settings (done) | time=237ms
 [INFO] Server id: 59CB0369-AZOrU2kGu2wk1AyH6d7L
 [WARNING] sonar.plugins.downloadOnlyRequired is false, so ALL available plugins will be downloaded
 [INFO] Loading all plugins
 [INFO] Load plugins index

When running on 10.4 there’s no mention of provisioning a JRE:

 [INFO] Java 17.0.13 Eclipse Adoptium (64-bit)
 [INFO] Linux 6.5.0-1025-azure (amd64)
 [INFO] MAVEN_OPTS=--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED  -Djava.awt.headless=true
 [INFO] User cache: /home/runner/.sonar/cache
 > 2024.12.09 12:11:55 WARN  web[ab36584e-2c6a-48a1-86bb-cf9166839f70][o.s.w.s.PageNotFound] No mapping for GET /api/v2/analysis/version
 [INFO] Communicating with SonarQube Server 10.4.0.87286
 [INFO] Load global settings
 [INFO] Load global settings (done) | time=162ms
 [INFO] Server id: 8D08E935-AZOrU2bhNOMCuPjScYlG
 [INFO] User cache: /home/runner/.sonar/cache
 [WARNING] sonar.plugins.downloadOnlyRequired is false, so ALL available plugins will be downloaded
 [INFO] Loading all plugins
 [INFO] Load plugins index

Can you please advise if the scanner is indeed forking a new JVM on newer versions of SonarQube?
I suspect the issue might be that the JVM is a JRE (not a JDK), so it is missing the javac module.
Even it is a JDK, I think it would need the extra --add-exports options. Is there a way to start that JVM with plugin-supplied arguments?

Hey there.

  • Yes, starting in SonarQube v10.6 (and SonarScanner for Maven v5.0), by default a JVM is downloaded from the SonarQube server.
  • You should be able to pass additional options to this JVM by using sonar.scanner.javaOpts
1 Like

That was fast, thanks Colin!
Let me try that, thanks for the answer

In the end it seems that I needed to disable the JRE provisionning: I need the javac module therefore I need a JDK, not a JRE.
I used the sonar.scanner.skipJreProvisioning option to do that.

Thank you very much for giving me the hint @Colin !

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.