diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD index 211fa48dd9485c..e950a9408fbc1e 100644 --- a/src/main/java/com/google/devtools/build/lib/BUILD +++ b/src/main/java/com/google/devtools/build/lib/BUILD @@ -768,6 +768,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/java", "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/proto", "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi/python", + "//src/main/java/com/google/devtools/build/lib/shell", "//src/main/java/com/google/devtools/build/lib/vfs", "//src/main/java/com/google/devtools/build/skyframe", "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java index 399f7afb5c2a3e..d2cf3a15bbdd3a 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java @@ -66,6 +66,8 @@ import com.google.devtools.build.lib.rules.java.JavaToolchainProvider; import com.google.devtools.build.lib.rules.java.JavaUtil; import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider; +import com.google.devtools.build.lib.shell.ShellUtils; +import com.google.devtools.build.lib.shell.ShellUtils.TokenizationException; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.OS; @@ -407,13 +409,32 @@ public Artifact createStubAction( arguments.add(Substitution.ofSpaceSeparatedList("%jvm_flags%", jvmFlagsList)); if (OS.getCurrent() == OS.WINDOWS) { + boolean windowsEscapeJvmFlags = + ruleContext + .getConfiguration() + .getFragment(JavaConfiguration.class) + .windowsEscapeJvmFlags(); + + List jvmFlagsForLauncher = jvmFlagsList; + if (windowsEscapeJvmFlags) { + try { + jvmFlagsForLauncher = new ArrayList<>(jvmFlagsList.size()); + for (String f : jvmFlagsList) { + ShellUtils.tokenize(jvmFlagsForLauncher, f); + } + } catch (TokenizationException e) { + ruleContext.attributeError("jvm_flags", "could not Bash-tokenize flag: " + e); + } + } + return createWindowsExeLauncher( ruleContext, javaExecutable, classpath, javaStartClass, - jvmFlagsList, - executable); + jvmFlagsForLauncher, + executable, + windowsEscapeJvmFlags); } ruleContext.registerAction(new TemplateExpansionAction( @@ -426,9 +447,9 @@ private static Artifact createWindowsExeLauncher( String javaExecutable, NestedSet classpath, String javaStartClass, - ImmutableList jvmFlags, - Artifact javaLauncher) { - + List jvmFlags, + Artifact javaLauncher, + boolean windowsEscapeJvmFlags) { LaunchInfo launchInfo = LaunchInfo.builder() .addKeyValuePair("binary_type", "Java") @@ -448,6 +469,7 @@ private static Artifact createWindowsExeLauncher( "classpath", ";", Iterables.transform(classpath, Artifact.ROOT_RELATIVE_PATH_STRING)) + .addKeyValuePair("escape_jvmflags", windowsEscapeJvmFlags ? "1" : "0") // TODO(laszlocsomor): Change the Launcher to accept multiple jvm_flags entries. As of // 2019-02-13 the Launcher accepts just one jvm_flags entry, which contains all the // flags, joined by TAB characters. The Launcher splits up the string to get the diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java index 2f4e6172df366c..8b847e05f8796a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfiguration.java @@ -177,6 +177,7 @@ public boolean alwaysGenerateOutputMapping() { private final ImmutableList