Sonar plugin for Gradle doesn't work when run inside OpenJDK 11/12 docker container

Hi

We have a Java project on Gradle and use Docker for builds (we build project inside docker container). Recently we’ve updated Java from 8 to 12 and got the exception from “sonarqube” Gradle task.

The most interesting part of the exception:

Exception
Caused by: java.lang.IllegalStateException: Fail to create temp file in ?/.sonar/cache/_tmp

at org.sonarsource.scanner.api.internal.cache.FileCache.newTempFile(FileCache.java:138)

at org.sonarsource.scanner.api.internal.cache.FileCache.get(FileCache.java:83)

at org.sonarsource.scanner.api.internal.JarDownloader.lambda$getScannerEngineFiles$0(JarDownloader.java:60)

at org.sonarsource.scanner.api.internal.JarDownloader.getScannerEngineFiles(JarDownloader.java:61)

at org.sonarsource.scanner.api.internal.JarDownloader.download(JarDownloader.java:53)

at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.lambda$createLauncher$0(IsolatedLauncherFactory.java:76)

... 186 more

Caused by: java.nio.file.NoSuchFileException: ?/.sonar/cache/_tmp/fileCache5903868184697272935.tmp

at org.sonarsource.scanner.api.internal.cache.FileCache.newTempFile(FileCache.java:136)

... 191 more

I’ve created an example project with the reproduce where I use exactly the same versions of Gradle, sonar plugin and java as we use in our project.

Steps to reproduce:

  1. Clone example project https://github.com/yevheniisemenov/sonar-gradle-in-docker-issue
  2. cd to project root directory
  3. in the project root directory run docker run -u $(id -u ${USER}):$(id -g ${USER}) -ti -v $PWD:$PWD -w $PWD openjdk:12.0.1-jdk bash
  4. inside docker container run ./gradlew sonarqube -Dsonar.login=(paste your token here) -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=(paste your org name) -x test --stacktrace

If you do the same with “openjdk:8u181-jdk-slim” image everything works fine.

I’m not sure this is Sonar issue, but anyway I would be grateful for any help.

2 Likes

After a few hours of investigation and debug found the cause of the issue in “scanner-api”. I suppose it happens because of this line of code where path - is a relative path which is not recommended by Gradle guideline.

On “openjdk:8u181-jdk-slim” it works correctly and absolute path resolved as “/Users/yevheniisemenov/Documents/sonar-java12/?/.sonar” path.

But on “openjdk:12.0.1-jdk” absolute path resolved as “/Users/yevheniisemenov/Documents/sonar-java12/.gradle/daemon/5.4/?/.sonar”.

I will try to contribute a fix and submit a pull request later.

For now, as a workaround, SONAR_USER_HOME env. variable is being helped to fix the issue.

Thanks for the feedback @ysemenov!

Hi @ysemenov

I wasn’t able to reproduce the problem with openjdk:12.0.1-jdk.
The piece of code you linked is just getting user home path with the property user.home, which didn’t change with any version of Java as far as I know. Also, this path should be absolute.

Did you check if you ran gradle in docker with a correctly configured user?

I had a second look, this time with your specific example and was able to reproduce.

The problem is that the user with which you’re running docker doesn’t exist in the container. The user id doesn’t map to any entry in passwd.
It looks like java relies on passwd to find user home rather than looking at the environment variable HOME.
Code that is possibly relevant: https://hg.openjdk.java.net/jdk-updates/jdk12u/file/e831fc6bca9e/src/java.base/unix/native/libjava/java_props_md.c#l520

I don’t think sonar-api is doing wrong by relying on the user.home system property. In any case I don’t see a good alternative to that (maybe using tmp?)

1 Like