Skip to content

Commit b8c11c4

Browse files
Allow passing JVM args to javac in ScipBuildTool (#728)
A canonical usage for this is passing `--add-opens` flags to the _launcher_ of javac to make sure annotation processors work. To pass these arguments to the launcher, they have to be perfixed with -J – but arguments like this cannot be passed through the argfile that we use for javacOptions (see https://docs.oracle.com/en/java/javase/17/docs/specs/man/javac.html#command-line-argument-files) so we need to pass them to the command itself. For that purpose, we add a `jvmOptions` field to scip-java.json config – these options will have `-J` added to them and passed to the `javac` command. The test to verify this behaviour relies on an [old version of lombok that requires these options](projectlombok/lombok#2681 (comment)) Additionally, a hidden option `--strict-compilation` is added to the CLI, to prevent error recovery: sometimes scip-java can just ignore javac errors and produce semanticdb artifacts regardless. This complicates testing, so I need an escape hatch). ### Test plan - New test to ScipBuildToolSuite
1 parent 75b238b commit b8c11c4

File tree

4 files changed

+66
-3
lines changed

4 files changed

+66
-3
lines changed

scip-java/src/main/resources/scip-java/scip_java.bzl

+10-1
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,20 @@ def _scip_java(target, ctx):
7171
processorpath += [j.path for j in annotations.processor_classpath.to_list()]
7272
processors = annotations.processor_classnames
7373

74+
launcher_javac_flags = []
75+
compiler_javac_flags = []
76+
for value in compilation.javac_options:
77+
if value.startswith("-J"):
78+
launcher_javac_flags.append(value)
79+
else:
80+
compiler_javac_flags.append(value)
81+
7482
build_config = struct(**{
7583
"javaHome": ctx.var["java_home"],
7684
"classpath": classpath,
7785
"sourceFiles": source_files,
78-
"javacOptions": compilation.javac_options,
86+
"javacOptions": compiler_javac_flags,
87+
"jvmOptions": launcher_javac_flags,
7988
"processors": processors,
8089
"processorpath": processorpath,
8190
"bootclasspath": bootclasspath,

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

+8-2
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,9 @@ class ScipBuildTool(index: IndexCommand) extends BuildTool("SCIP", index) {
202202
}
203203
val isSemanticdbGenerated = Files
204204
.isDirectory(targetroot.resolve("META-INF"))
205-
if (errors.nonEmpty && !isSemanticdbGenerated) {
205+
if (
206+
errors.nonEmpty && (index.strictCompilation || !isSemanticdbGenerated)
207+
) {
206208
errors.foreach { error =>
207209
index.app.reporter.log(Diagnostic.exception(error))
208210
}
@@ -558,8 +560,11 @@ class ScipBuildTool(index: IndexCommand) extends BuildTool("SCIP", index) {
558560
BuildInfo.javacModuleOptions
559561
else
560562
Nil
563+
564+
val jvmOptions = config.jvmOptions.map("-J" + _)
565+
561566
val result = os
562-
.proc(javac.toString, s"@$argsfile", javacModuleOptions)
567+
.proc(javac.toString, s"@$argsfile", javacModuleOptions, jvmOptions)
563568
.call(
564569
stdout = pipe,
565570
stderr = pipe,
@@ -815,6 +820,7 @@ class ScipBuildTool(index: IndexCommand) extends BuildTool("SCIP", index) {
815820
processorpath: List[String] = Nil,
816821
processors: List[String] = Nil,
817822
javacOptions: List[String] = Nil,
823+
jvmOptions: List[String] = Nil,
818824
jvm: String = "17",
819825
kind: String = ""
820826
)

scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexCommand.scala

+5
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ case class IndexCommand(
8383
"Defaults to a build-specific command. For example, the default command for Maven command is 'clean verify -DskipTests'." +
8484
"To override the default, pass in the build command after a double dash: 'scip-java index -- compile test:compile'"
8585
)
86+
87+
@Hidden
88+
@Description(
89+
"Fail command invocation if compiler produces any errors"
90+
) strictCompilation: Boolean = false,
8691
@TrailingArguments() buildCommand: List[String] = Nil,
8792
@Hidden
8893
indexSemanticdb: IndexSemanticdbCommand = IndexSemanticdbCommand(),

tests/buildTools/src/test/scala/tests/ScipBuildToolSuite.scala

+43
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,49 @@ class ScipBuildToolSuite extends BaseBuildToolSuite {
110110
)
111111
)
112112

113+
checkBuild(
114+
"jvm-args", {
115+
// In this test we verify that JVM args and Javac options are passed
116+
// correctly.
117+
// Lombok modules need to be passed with -J prefix, and javacOptions should
118+
// be passed unchanged
119+
// For this test to work the lombok version HAS to be relatively old,
120+
// so that it requires all these opens.
121+
// The list is taken from here: https://github.com/projectlombok/lombok/issues/2681#issuecomment-748616687
122+
val lombokModules = """
123+
--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
124+
--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
125+
--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
126+
--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
127+
--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
128+
--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
129+
--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
130+
--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
131+
--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
132+
--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED
133+
""".trim.split("\n").map(_.trim).mkString("\"", "\", \"", "\"")
134+
135+
s"""|/lsif-java.json
136+
|{"jvmOptions": [$lombokModules], "javacOptions": ["--add-exports=java.base/sun.util=ALL-UNNAMED"], "dependencies": ["org.projectlombok:lombok:1.18.16"]}
137+
|/foo/Example.java
138+
|package foo;
139+
|import sun.util.BuddhistCalendar;
140+
|public class Example extends BuddhistCalendar {
141+
| public static void hello() {
142+
| BuddhistCalendar calendar = new BuddhistCalendar();
143+
| }
144+
|}
145+
|""".stripMargin
146+
},
147+
expectedSemanticdbFiles = 1,
148+
// somehow it seems the actual compilation error from javac
149+
// does not stop semanticdb-javac from producing the file.
150+
// we explicitly disable this lenient mode so that if there
151+
// are any compilation errors, it will be reflected in failed
152+
// CLI command.
153+
extraArguments = List("--strict-compilation")
154+
)
155+
113156
checkBuild(
114157
"basic",
115158
"""|/lsif-java.json

0 commit comments

Comments
 (0)