Skip to content

Commit c3b8f4b

Browse files
committed
Make buildTools/test work on Java 17
Previously, we only tested `sbt test` on Java 8 and we had a lot of failing tests if sbt was started with Java 17. This commit makes the tests in the `buildTools` project pass on Java 17.
1 parent 452884d commit c3b8f4b

File tree

8 files changed

+145
-27
lines changed

8 files changed

+145
-27
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ on:
66
pull_request:
77
jobs:
88
test:
9-
runs-on: ${{ matrix.os }}
9+
runs-on: ${{ matrix.os }}
1010
strategy:
1111
matrix:
1212
# NOTE(olafurpg) Windows is not enabled because it times out due to reasons I don't understand.
1313
# os: [windows-latest, ubuntu-latest]
1414
os: [ubuntu-latest]
15+
java: [8, 17]
1516
steps:
1617
- uses: actions/checkout@v2
1718
- uses: actions/setup-java@v1
1819
with:
19-
java-version: 8
20+
java-version: ${{ matrix.java }}
2021
- uses: actions/setup-go@v2
2122
with:
2223
go-version: "^1.13.1"

scip-java/src/main/scala/com/sourcegraph/scip_java/Embedded.scala

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import java.nio.file.Files
55
import java.nio.file.Path
66
import java.nio.file.StandardCopyOption
77

8+
import com.sourcegraph.scip_java.BuildInfo
89
import moped.reporters.Reporter
910
import os.CommandResult
1011

@@ -22,7 +23,12 @@ object Embedded {
2223

2324
private def javacErrorpath(tmp: Path) = tmp.resolve("errorpath.txt")
2425

25-
def customJavac(sourceroot: Path, targetroot: Path, tmp: Path): Path = {
26+
def customJavac(
27+
sourceroot: Path,
28+
targetroot: Path,
29+
tmp: Path,
30+
javaAtLeast17: Boolean
31+
): Path = {
2632
val bin = tmp.resolve("bin")
2733
val javac = bin.resolve("javac")
2834
val java = bin.resolve("java")
@@ -38,6 +44,11 @@ object Embedded {
3844
|""".stripMargin.getBytes(StandardCharsets.UTF_8)
3945
)
4046
val newJavacopts = tmp.resolve("javac_newarguments")
47+
val javacModuleOptions =
48+
if (javaAtLeast17)
49+
BuildInfo.javacModuleOptions.mkString(" ")
50+
else
51+
""
4152
val injectSemanticdbArguments = List[String](
4253
"java",
4354
s"-Dsemanticdb.errorpath=$errorpath",
@@ -62,9 +73,9 @@ object Embedded {
6273
|done
6374
|$injectSemanticdbArguments
6475
|if [ $${#LAUNCHER_ARGS[@]} -eq 0 ]; then
65-
| javac "@$$NEW_JAVAC_OPTS"
76+
| javac $javacModuleOptions "@$$NEW_JAVAC_OPTS"
6677
|else
67-
| javac "@$$NEW_JAVAC_OPTS" "$${LAUNCHER_ARGS[@]}"
78+
| javac $javacModuleOptions "@$$NEW_JAVAC_OPTS" "$${LAUNCHER_ARGS[@]}"
6879
|fi
6980
|""".stripMargin
7081
Files.write(javac, script.getBytes(StandardCharsets.UTF_8))

scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleBuildTool.scala

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,9 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) {
126126
}
127127

128128
private def initScript(toolchains: GradleJavaToolchains, tmp: Path): Path = {
129+
val executableJavacPath = toolchains.executableJavacPath()
129130
val executable =
130-
toolchains.executableJavacPath() match {
131+
executableJavacPath match {
131132
case Some(path) =>
132133
s"options.forkOptions.executable = '$path'"
133134
case None =>
@@ -144,17 +145,6 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) {
144145
val dependenciesPath = targetroot.resolve("dependencies.txt")
145146
val kotlinSemanticdbVersion = BuildInfo.semanticdbKotlincVersion
146147
Files.deleteIfExists(dependenciesPath)
147-
val javaModuleOptions =
148-
if (Properties.isJavaAtLeast(9)) {
149-
// Include --add-exports flags for Java 9+
150-
BuildInfo
151-
.javacModuleOptions
152-
.map(option => s""""$option"""")
153-
.mkString(",")
154-
} else {
155-
// No --add-exports flags for Java 8
156-
""
157-
}
158148
val script =
159149
s"""|allprojects {
160150
| gradle.projectsEvaluated {
@@ -171,7 +161,7 @@ class GradleBuildTool(index: IndexCommand) extends BuildTool("Gradle", index) {
171161
| tasks.withType(JavaCompile) {
172162
| options.fork = true
173163
| options.incremental = false
174-
| options.forkOptions.jvmArgs.addAll([$javaModuleOptions])
164+
| System.out.println("JAVA VERSION " + System.getProperty("java.version"))
175165
| $executable
176166
| }
177167
| }

scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleJavaCompiler.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ case class GradleJavaCompiler(languageVersion: String, javacPath: Path) {
2727
pluginPath: Path
2828
): Path = {
2929
val home = tmp.resolve(s"1.$languageVersion")
30-
val javac = Embedded.customJavac(index.workingDirectory, targetroot, tmp)
30+
val javac = Embedded.customJavac(
31+
index.workingDirectory,
32+
targetroot,
33+
tmp,
34+
GradleJavaToolchains.isJavaAtLeast(languageVersion, "17")
35+
)
3136
val agent = Embedded.agentJar(tmp)
3237
val debugPath = GradleJavaCompiler.debugPath(tmp)
3338
val javacopts = targetroot.resolve("javacopts.txt")

scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/GradleJavaToolchains.scala

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import java.nio.charset.StandardCharsets
44
import java.nio.file.Files
55
import java.nio.file.Path
66

7+
import scala.annotation.tailrec
78
import scala.jdk.CollectionConverters._
89

910
import com.sourcegraph.scip_java.Embedded
@@ -14,6 +15,7 @@ case class GradleJavaToolchains(
1415
tool: GradleBuildTool,
1516
index: IndexCommand,
1617
gradleVersion: Option[String],
18+
javaVersion: Option[String],
1719
isJavaEnabled: Boolean,
1820
isScalaEnabled: Boolean,
1921
isKotlinEnabled: Boolean,
@@ -24,9 +26,22 @@ case class GradleJavaToolchains(
2426

2527
def isEmpty: Boolean = toolchains.isEmpty
2628

29+
def isJavaAtLeast(version: Int): Boolean = {
30+
val actualVersion = javaVersion.getOrElse(sys.props("java.version"))
31+
GradleJavaToolchains
32+
.isJavaAtLeast(actualVersion, math.max(version, 0).toString())
33+
}
34+
2735
def executableJavacPath(): Option[Path] = {
2836
if (toolchains.isEmpty) {
29-
Some(Embedded.customJavac(index.workingDirectory, tool.targetroot, tmp))
37+
Some(
38+
Embedded.customJavac(
39+
index.workingDirectory,
40+
tool.targetroot,
41+
tmp,
42+
isJavaAtLeast(17)
43+
)
44+
)
3045
} else {
3146
None
3247
}
@@ -62,6 +77,7 @@ object GradleJavaToolchains {
6277
val javaEnabledPath = tmp.resolve("java-enabled.txt")
6378
val scalaEnabledPath = tmp.resolve("scala-enabled.txt")
6479
val kotlinEnabledPath = tmp.resolve("kotlin-enabled.txt")
80+
val javaVersionPath = tmp.resolve("java-version.txt")
6581
val kotlinMultiplatformEnabledPath = tmp
6682
.resolve("kotlin-multiplatform-enabled.txt")
6783
val gradleVersionPath = tmp.resolve("gradle-version.txt")
@@ -75,6 +91,12 @@ object GradleJavaToolchains {
7591
| [gradle.gradleVersion],
7692
| java.nio.file.StandardOpenOption.TRUNCATE_EXISTING,
7793
| java.nio.file.StandardOpenOption.CREATE)
94+
| java.nio.file.Files.write(
95+
| java.nio.file.Paths.get(
96+
| java.net.URI.create('${javaVersionPath.toUri}')),
97+
| [System.getProperty("java.version")],
98+
| java.nio.file.StandardOpenOption.TRUNCATE_EXISTING,
99+
| java.nio.file.StandardOpenOption.CREATE)
78100
|} catch (Exception e) {
79101
| // Ignore errors.
80102
|}
@@ -146,11 +168,19 @@ object GradleJavaToolchains {
146168
None
147169
}
148170

171+
val javaVersion =
172+
if (Files.isRegularFile(javaVersionPath)) {
173+
Some(new String(Files.readAllBytes(javaVersionPath)).trim)
174+
} else {
175+
None
176+
}
177+
149178
GradleJavaToolchains(
150179
toolchains,
151180
tool,
152181
index,
153182
gradleVersion = gradleVersion,
183+
javaVersion = javaVersion,
154184
isJavaEnabled = Files.isRegularFile(javaEnabledPath),
155185
isScalaEnabled = Files.isRegularFile(scalaEnabledPath),
156186
isKotlinEnabled = Files.isRegularFile(kotlinEnabledPath),
@@ -160,4 +190,68 @@ object GradleJavaToolchains {
160190
tmp = tmp
161191
)
162192
}
193+
194+
// Copy-pasted from scala.util.Properties.isJavaAtLeast but makes the actual
195+
// version a parameterizeable instead of being hard-coded to
196+
// `Properties.javaVersionSpec`.
197+
def isJavaAtLeast(
198+
actualVersion: String,
199+
comparisonVersion: String
200+
): Boolean = {
201+
def versionOf(s: String, depth: Int): (Int, String) =
202+
s.indexOf('.') match {
203+
case 0 =>
204+
(-2, s.substring(1))
205+
case 1 if depth == 0 && s.charAt(0) == '1' =>
206+
val r0 = s.substring(2)
207+
val (v, r) = versionOf(r0, 1)
208+
val n =
209+
if (v > 8 || r0.isEmpty)
210+
-2
211+
else
212+
v // accept 1.8, not 1.9 or 1.
213+
(n, r)
214+
case -1 =>
215+
val n =
216+
if (!s.isEmpty)
217+
s.toInt
218+
else if (depth == 0)
219+
-2
220+
else
221+
0
222+
(n, "")
223+
case i =>
224+
val r = s.substring(i + 1)
225+
val n =
226+
if (depth < 2 && r.isEmpty)
227+
-2
228+
else
229+
s.substring(0, i).toInt
230+
(n, r)
231+
}
232+
@tailrec
233+
def compareVersions(s: String, v: String, depth: Int): Int = {
234+
if (depth >= 3)
235+
0
236+
else {
237+
val (sn, srest) = versionOf(s, depth)
238+
val (vn, vrest) = versionOf(v, depth)
239+
if (vn < 0)
240+
-2
241+
else if (sn < vn)
242+
-1
243+
else if (sn > vn)
244+
1
245+
else
246+
compareVersions(srest, vrest, depth + 1)
247+
}
248+
}
249+
250+
compareVersions(actualVersion, comparisonVersion, 0) match {
251+
case -2 =>
252+
throw new NumberFormatException(s"Not a version: $comparisonVersion")
253+
case i =>
254+
i >= 0
255+
}
256+
}
163257
}

scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/MavenBuildTool.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import java.nio.file.Path
55
import java.nio.file.Paths
66

77
import scala.collection.mutable.ListBuffer
8+
import scala.util.Properties
89

910
import com.sourcegraph.scip_java.Embedded
1011
import com.sourcegraph.scip_java.commands.IndexCommand
@@ -39,7 +40,10 @@ class MavenBuildTool(index: IndexCommand) extends BuildTool("Maven", index) {
3940
val executable = Embedded.customJavac(
4041
index.workingDirectory,
4142
index.finalTargetroot(defaultTargetroot),
42-
tmp
43+
tmp,
44+
// TODO: infer Java version from `java -version` because it may not
45+
// match the Java version that's used by the current process.
46+
Properties.isJavaAtLeast(11)
4347
)
4448
buildCommand ++=
4549
List(

tests/buildTools/src/test/scala/tests/BaseBuildToolSuite.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import munit.Tag
1818
import munit.TestOptions
1919
import os.Shellable
2020

21+
object Java8Only extends munit.Tag("Java8Only")
22+
2123
abstract class BaseBuildToolSuite extends MopedSuite(ScipJava.app) {
2224
override def environmentVariables: Map[String, String] = sys.env
2325

@@ -26,6 +28,14 @@ abstract class BaseBuildToolSuite extends MopedSuite(ScipJava.app) {
2628
override def munitTestTransforms: List[TestTransform] =
2729
super.munitTestTransforms ++
2830
List(
31+
new TestTransform(
32+
"Java8Only",
33+
t =>
34+
if (Properties.isJavaAtLeast(9) && t.tags(Java8Only))
35+
t.tag(munit.Ignore)
36+
else
37+
t
38+
),
2939
new TestTransform(
3040
"SkipWindows",
3141
t =>

tests/buildTools/src/test/scala/tests/GradleBuildToolSuite.scala

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ class GradleBuildToolSuite extends BaseBuildToolSuite {
2727
List("latest" -> "implementation", "4.0" -> "compile").foreach {
2828
case (version, config) =>
2929
checkBuild(
30-
s"basic-$version",
30+
if (version == "latest")
31+
"basic-latest"
32+
else
33+
s"basic-$version".tag(Java8Only),
3134
s"""|/build.gradle
3235
|apply plugin: 'java'
3336
|repositories {
@@ -55,7 +58,7 @@ class GradleBuildToolSuite extends BaseBuildToolSuite {
5558

5659
List("3.3", "2.2.1").foreach { version =>
5760
checkBuild(
58-
s"legacy-$version",
61+
s"legacy-$version".tag(Java8Only),
5962
s"""|/build.gradle
6063
|apply plugin: 'java'
6164
|/src/main/java/Example.java
@@ -90,7 +93,7 @@ class GradleBuildToolSuite extends BaseBuildToolSuite {
9093
)
9194

9295
checkBuild(
93-
"toolchains-6.7",
96+
"toolchains-6.7".tag(Java8Only),
9497
"""|/build.gradle
9598
|apply plugin: 'java'
9699
|java {
@@ -114,7 +117,7 @@ class GradleBuildToolSuite extends BaseBuildToolSuite {
114117
)
115118

116119
checkBuild(
117-
"toolchains-6.8",
120+
"toolchains-6.8".tag(Java8Only),
118121
"""|/build.gradle
119122
|apply plugin: 'java'
120123
|java {
@@ -158,7 +161,7 @@ class GradleBuildToolSuite extends BaseBuildToolSuite {
158161
)
159162

160163
checkBuild(
161-
"playframework",
164+
"playframework".tag(Java8Only),
162165
"""|/build.gradle
163166
|plugins {
164167
| id 'org.gradle.playframework' version '0.11'
@@ -209,7 +212,7 @@ class GradleBuildToolSuite extends BaseBuildToolSuite {
209212
)
210213

211214
checkBuild(
212-
"checkerframework",
215+
"checkerframework".tag(Java8Only),
213216
"""|/build.gradle
214217
|plugins {
215218
| id 'java'

0 commit comments

Comments
 (0)