diff --git a/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/GradleJavaCompiler.scala b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/GradleJavaCompiler.scala index 89dab4ef..5e1f5a8a 100644 --- a/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/GradleJavaCompiler.scala +++ b/lsif-java/src/main/scala/com/sourcegraph/lsif_java/buildtools/GradleJavaCompiler.scala @@ -2,6 +2,7 @@ package com.sourcegraph.lsif_java.buildtools import java.nio.charset.StandardCharsets import java.nio.file.Files +import java.nio.file.NoSuchFileException import java.nio.file.Path import java.nio.file.Paths import java.nio.file.StandardCopyOption @@ -70,9 +71,9 @@ case class GradleJavaCompiler(languageVersion: String, javacPath: Path) { val javaCommand = ListBuffer[String]( javaBinary.toString, s"-javaagent:$agent", - s"-Dsemanticdb.javacopts=${javacopts}", - s"-Dsemanticdb.pluginpath=${pluginPath}", - s"-Dsemanticdb.targetroot=${targetroot}", + s"-Dsemanticdb.javacopts=$javacopts", + s"-Dsemanticdb.pluginpath=$pluginPath", + s"-Dsemanticdb.targetroot=$targetroot", s"-Dsemanticdb.sourceroot=${index.workingDirectory}" ) if (index.verbose) { @@ -98,6 +99,39 @@ case class GradleJavaCompiler(languageVersion: String, javacPath: Path) { ) .toFile .setExecutable(true) + + val copyFiles = + (source: Path, destination: Path) => { + Files + .walk(source) + .forEach(t => { + val destPath = destination.resolve(source.relativize(t)) + try { + Files.copy(t, destPath) + } catch { + case _: NoSuchFileException => + return + } + }) + } + + // For compile{Test}Kotlin when using jvm toolchains, we need to have access + // to JDK internals found in /lib in JDK 9+, + // as well as /jre/lib in JDK <=8, else we get + // "no class roots are found in the JDK path" from the compile{Test}Kotlin tasks. + // https://docs.oracle.com/en/java/javase/12/migrate/index.html#JSMIG-GUID-A78CC891-701D-4549-AA4E-B8DD90228B4B + val javaHome = javacPath.getParent.getParent + val libPath = dir.resolve("lib") + val javacLibPath = javaHome.resolve("lib") + copyFiles(javacLibPath, libPath) + + if (languageVersion == "8") { + val jreLibPath = dir.resolve("jre").resolve("lib") + Files.createDirectories(jreLibPath.getParent) + val javacJreLibPath = javaHome.resolve("jre").resolve("lib") + + copyFiles(javacJreLibPath, jreLibPath) + } } } object GradleJavaCompiler { @@ -111,9 +145,9 @@ object GradleJavaCompiler { /** * Parses a single space-separated line into a GradleJavaCompiler instance. * - * Example input: "8 /path/javac" + * Example input: "8 /javacLibPath/javac" * - * Example output: `Some(GradleJavaCompiler("8", * /path/javac))` + * Example output: `Some(GradleJavaCompiler("8", * /javacLibPath/javac))` */ def fromLine(line: String): Option[GradleJavaCompiler] = line.split(' ') match { diff --git a/tests/buildTools/src/test/scala/tests/GradleBuildToolSuite.scala b/tests/buildTools/src/test/scala/tests/GradleBuildToolSuite.scala index fe4b8fc8..6e3c7b9c 100644 --- a/tests/buildTools/src/test/scala/tests/GradleBuildToolSuite.scala +++ b/tests/buildTools/src/test/scala/tests/GradleBuildToolSuite.scala @@ -287,6 +287,28 @@ class GradleBuildToolSuite extends BaseBuildToolSuite { 4 ) + List("8", "11").foreach { version => + checkBuild( + s"kotlin-jvm-toolchains-jdk-$version", + s"""|/build.gradle + |plugins { + | id 'java' + | id 'org.jetbrains.kotlin.jvm' version '1.5.31' + |} + |java { + | toolchain { + | languageVersion = JavaLanguageVersion.of($version) + | } + |} + |repositories { mavenCentral() } + |/src/main/kotlin/foo/Example.kt + |package foo + |object Example {} + |""".stripMargin, + 1 + ) + } + List("jvm()" -> 2, "jvm { withJava() }" -> 4).foreach { case (jvmSettings, expectedSemanticdbFiles) => checkBuild( @@ -326,5 +348,4 @@ class GradleBuildToolSuite extends BaseBuildToolSuite { expectedSemanticdbFiles ) } - }