Unable to resolve dependency when scanning in java11 on a build that is running in java8

We are in the process of setting up java11 on our jenkins machines to run sonar scanner. We are following the instructions provided in https://sonarcloud.io/documentation/user-guide/move-analysis-java-11/ as our build runs on java8.

We have hard-coded system path that points to jdk1.8 in one of our internal pom parents and the scanning fails with below error when we run mvn sonar:sonar

$ mvn verify …

$ export JAVA_HOME=/path/to/java11

$ mvn sonar:sonar …

Failed to execute goal on project xxxxxxx_service: Could not resolve dependencies for project com.xyz:xxxxxx:pom:1.0-SNAPSHOT: Could not find artifact jdk.tools:jdk.tools:jar:1.8 at specified path /usr/lib/jvm/java-11-openjdk-amd64/…/lib/tools.jar

I tried adding -Dsonar.java.binaries=**/build/classes but that didnt help.

Is there any other way to run sonar analysis in java11 for builds running in java8?

Hi Aswathy,

Could you share here how are you setting in your POM.xml the target JDK version 8?
It looks like the build is looking for the JDK version 8 under a JDK 11 path.

In addition, please could you share the full logs in debug mode, as we may be missing important information here?

The idea here is that your JAVA_HOME should be pointing to JDK8 when running mvn verify, and then override JAVA_HOME (as you are doing) to point to JDK11 before mvn sonar:sonar. Hardcoding the JDK8 dependency in the POM.xml file may imply that the scanner will be told to use and find the JDK8 as indicated in the POM.xml under the JAVA_HOME path you specified, which at the time you execute mvn sonar:sonar it is the JDK11 path.

I am not sure what is requiring you to hardcode the JDK version in the POM.xml? Do you think you can try the above approach without hardcoding anything in the POM.xml, and just by switching the value of JAVA_HOME?

Below is the dependency we have added in our POM parent.

<dependency>
  <groupId>jdk.tools</groupId>
  <artifactId>jdk.tools</artifactId>
  <scope>system</scope>
  <version>1.8</version>
  <systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>

This is an internal java base POM parent that is being used by all the downstream projects. I am not sure about the impact if we remove it. I will confirm with the maintainers of this POM.

In the meantime, I would like to know if there are any workarounds to run static code analysis against the binaries generated by jdk8 without rebuilding the code again in jdk11.

Complete log for your reference:

sonar_analysis_jdk11.txt (24.3 KB)

Hi Aswathy,

The problem is that in this parent pom.xml, the path to the dependency is relative to java.home environment variable. As soon as you change java.home in order to set version 11 so that you can run the SonarScanner, this parent dependency (jdk8) won’t be found.

I would suggest to replace the value in systemPath by the expected path to JDK8 in the parent pom, removing the reference to java.home from it or using an alternative environment variable. You may also try overriding this dependency on the child pom, using the dependencyManagement section.

Hi Daniel,

We require this parent dependency to build the projects that are still in jdk8 and we are not planning to migrate to jdk11 in the near future.

We cannot replace java.home with full path as these java projects are built in various jenkins agent and developer machines where the paths might vary.

Is there a way to run static code analysis against the existing binaries without rebuilding the code?

Hi Aswathy,

I understand the situation and limitations. Here, in order to make things work, there is no straightforward solution I am afraid. This means any workaround will imply some non-negligible effort. Due to using ${java.home} reference in the parent pom, you are completely tied up: you cannot pass a different JDK version to the Scanner. We need to break this limitation, and this falls greatly on the Maven scope and not SonarCloud’s.

Without being a Maven expert, an alternative I can propose is to look into Maven Profiles, so that you activate this dependency conditionally and on the right path.

You can use profiles to set a new variable, i.e. “tools.jar”, conditionally to the right path. In the profile’s condition, if tools.jar is not found where you expect it, it would mean you changed JAVA_HOME and that you are on the scanner process. In such case you could have prepared a new JAVA8_HOME environment variable before overwriting it, and your profile could define tools.jar path using this new variable.

There are several resources on the Internet that explain this. Also have a look at this approach which is very similar to what I just explained in the above paragraph.

Hope this helps, best regards,
Daniel

Thanks Daniel. Maven profiles seems to be a good solution. Let me give it a try.

Hi Daniel,

Using profiles to set the variable conditionally worked for maven builds. Thanks for your help.

We have few gradle monorepo projects that are failing to compile when we run mvn sonarqube in jdk11 after building the code in jdk8. Have attached the debug logs for your reference. Could you take a look at it and provide a solution?

sonar_analysis_jdk11_gradle.txt (33.0 KB)