Add jvm_opts attribute to the java_toolchain rule
This allows to override the JVM options given to the Java compiler
invocations.
Fixes #56
--
MOS_MIGRATED_REVID=93981759
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
index a1e41f7..004606c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java
@@ -48,6 +48,7 @@
private JavaTargetAttributes.Builder attributes;
private JavaTargetAttributes builtAttributes;
private final ImmutableList<String> customJavacOpts;
+ private final ImmutableList<String> customJavacJvmOpts;
private final List<Artifact> translations = new ArrayList<>();
private boolean translationsFrozen = false;
private final JavaSemantics semantics;
@@ -57,6 +58,8 @@
super(ruleContext);
this.attributes = attributes;
this.customJavacOpts = javacOpts;
+ this.customJavacJvmOpts =
+ ImmutableList.copyOf(JavaToolchainProvider.getDefaultJavacJvmOptions(ruleContext));
this.semantics = semantics;
}
@@ -85,7 +88,6 @@
public void createCompileAction(Artifact outputJar, @Nullable Artifact gensrcOutputJar,
@Nullable Artifact outputDepsProto, @Nullable Artifact outputMetadata) {
JavaTargetAttributes attributes = getAttributes();
- List<String> javacOpts = getJavacOpts();
JavaCompileAction.Builder builder = createJavaCompileActionBuilder(semantics);
builder.setClasspathEntries(attributes.getCompileTimeClassPath());
builder.addResources(attributes.getResources());
@@ -106,7 +108,8 @@
builder.setInstrumentationJars(getInstrumentationJars(semantics));
builder.addSourceFiles(attributes.getSourceFiles());
builder.addSourceJars(attributes.getSourceJars());
- builder.setJavacOpts(javacOpts);
+ builder.setJavacOpts(customJavacOpts);
+ builder.setJavacJvmOpts(customJavacJvmOpts);
builder.setCompressJar(true);
builder.setClassDirectory(outputDir(outputJar));
builder.setSourceGenDirectory(sourceGenDir(outputJar));
@@ -243,6 +246,11 @@
builder.setClassDirectory(outputDir(resourceJar));
builder.setTempDirectory(tempDir(resourceJar));
builder.setJavaBuilderJar(getJavaBuilderJar());
+ builder.setJavacOpts(getDefaultJavacOptsFromRule(getRuleContext()));
+ builder.setJavacJvmOpts(
+ ImmutableList.copyOf(JavaToolchainProvider.getDefaultJavacOptions(getRuleContext())));
+ builder.setJavacJvmOpts(
+ ImmutableList.copyOf(JavaToolchainProvider.getDefaultJavacJvmOptions(getRuleContext())));
getAnalysisEnvironment().registerAction(builder.build());
return resourceJar;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java
index 572fcc1..85d4647 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java
@@ -723,6 +723,7 @@
private final Collection<Artifact> directJars = new ArrayList<>();
private final Collection<Artifact> compileTimeDependencyArtifacts = new ArrayList<>();
private List<String> javacOpts = new ArrayList<>();
+ private ImmutableList<String> javacJvmOpts = ImmutableList.of();
private boolean compressJar;
private NestedSet<Artifact> classpathEntries =
NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER);
@@ -856,7 +857,7 @@
langtoolsJar,
instrumentationJars,
paramFile,
- javaConfiguration.getDefaultJavaBuilderJvmFlags(),
+ javacJvmOpts,
semantics.getJavaBuilderMainClass(),
configuration.getHostPathSeparator());
@@ -978,6 +979,11 @@
return this;
}
+ public Builder setJavacJvmOpts(ImmutableList<String> opts) {
+ this.javacJvmOpts = opts;
+ return this;
+ }
+
public Builder setCompressJar(boolean compressJar) {
this.compressJar = compressJar;
return this;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfigurationLoader.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfigurationLoader.java
index 53fdfdf..b1aa262 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfigurationLoader.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaConfigurationLoader.java
@@ -55,22 +55,10 @@
boolean generateJavaDeps = javaOptions.javaDeps ||
javaOptions.experimentalJavaClasspath != JavaClasspathMode.OFF;
- ImmutableList<String> defaultJavaBuilderJvmOpts = ImmutableList.<String>builder()
- .addAll(getJavacJvmOptions())
- .addAll(JavaHelper.tokenizeJavaOptions(javaOptions.javaBuilderJvmOpts))
- .build();
+ ImmutableList<String> defaultJavaBuilderJvmOpts =
+ ImmutableList.copyOf(JavaHelper.tokenizeJavaOptions(javaOptions.javaBuilderJvmOpts));
return new JavaConfiguration(generateJavaDeps, javaOptions.jvmOpts, javaOptions,
javaToolchain, javaCpu, defaultJavaBuilderJvmOpts);
}
-
- /**
- * This method returns the list of JVM options when invoking the java compiler.
- *
- * <p>TODO(bazel-team): Maybe we should put those options in the java_toolchain rule.
- */
- protected ImmutableList<String> getJavacJvmOptions() {
- return ImmutableList.of("-client");
- }
-
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
index 65ed97a..aac1742 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.java;
-import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
@@ -39,10 +38,12 @@
final String encoding = ruleContext.attributes().get("encoding", Type.STRING);
final List<String> xlint = ruleContext.attributes().get("xlint", Type.STRING_LIST);
final List<String> misc = ruleContext.attributes().get("misc", Type.STRING_LIST);
+ final List<String> jvmOpts = ruleContext.attributes().get("jvm_opts", Type.STRING_LIST);
+ final JavaToolchainData toolchainData =
+ new JavaToolchainData(source, target, encoding, xlint, misc, jvmOpts);
final JavaConfiguration configuration = ruleContext.getFragment(JavaConfiguration.class);
- JavaToolchainProvider provider = new JavaToolchainProvider(source, target, encoding,
- ImmutableList.copyOf(xlint), ImmutableList.copyOf(misc),
- configuration.getDefaultJavacFlags());
+ JavaToolchainProvider provider = new JavaToolchainProvider(toolchainData,
+ configuration.getDefaultJavacFlags(), configuration.getDefaultJavaBuilderJvmFlags());
RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext)
.add(JavaToolchainProvider.class, provider)
.setFilesToBuild(new NestedSetBuilder<Artifact>(Order.STABLE_ORDER).build())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainData.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainData.java
index 0338fb8..f3c94f4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainData.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainData.java
@@ -18,6 +18,8 @@
import com.google.common.collect.ImmutableList.Builder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import java.util.List;
+
/**
* Information about the JDK used by the <code>java_*</code> rules.
*
@@ -27,9 +29,11 @@
@Immutable
public class JavaToolchainData {
private final ImmutableList<String> options;
+ private final ImmutableList<String> jvmOpts;
public JavaToolchainData(String source, String target, String encoding,
- ImmutableList<String> xlint, ImmutableList<String> misc) {
+ List<String> xlint, List<String> misc, List<String> jvmOpts) {
+ this.jvmOpts = ImmutableList.copyOf(jvmOpts);
Builder<String> builder = ImmutableList.<String>builder();
if (!source.isEmpty()) {
builder.add("-source", source);
@@ -52,4 +56,11 @@
public ImmutableList<String> getJavacOptions() {
return options;
}
+
+ /**
+ * @return the list of options to be given to the JVM when invoking the java compiler.
+ */
+ public ImmutableList<String> getJavacJvmOptions() {
+ return jvmOpts;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainDataParser.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainDataParser.java
index 64e1eb3..688e02a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainDataParser.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainDataParser.java
@@ -75,6 +75,7 @@
String encoding = "";
ImmutableList<String> xlint = ImmutableList.of();
ImmutableList<String> misc = ImmutableList.of();
+ ImmutableList<String> jvmOpts = ImmutableList.of();
for (Build.Attribute attribute : rule.getAttributeList()) {
switch (attribute.getName()) {
case "source_version":
@@ -92,8 +93,11 @@
case "misc":
misc = ImmutableList.copyOf(attribute.getStringListValueList());
break;
+ case "jvm_opts":
+ jvmOpts = ImmutableList.copyOf(attribute.getStringListValueList());
+ break;
}
}
- return new JavaToolchainData(source, target, encoding, xlint, misc);
+ return new JavaToolchainData(source, target, encoding, xlint, misc, jvmOpts);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java
index 3e210d8..3c2c4f3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainProvider.java
@@ -18,6 +18,7 @@
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.Type;
import java.util.List;
@@ -28,17 +29,23 @@
public final class JavaToolchainProvider implements TransitiveInfoProvider {
private final ImmutableList<String> javacOptions;
+ private final ImmutableList<String> javacJvmOptions;
- public JavaToolchainProvider(String source, String target, String encoding,
- ImmutableList<String> xlint, ImmutableList<String> misc, List<String> defaultJavacFlags) {
+ public JavaToolchainProvider(JavaToolchainData data, List<String> defaultJavacFlags,
+ List<String> defaultJavacJvmOpts) {
super();
// merges the defaultJavacFlags from
// {@link JavaConfiguration} with the flags from the {@code java_toolchain} rule.
- JavaToolchainData data = new JavaToolchainData(source, target, encoding, xlint, misc);
this.javacOptions = ImmutableList.<String>builder()
.addAll(data.getJavacOptions())
.addAll(defaultJavacFlags)
.build();
+ // merges the defaultJavaBuilderJvmFlags from
+ // {@link JavaConfiguration} with the flags from the {@code java_toolchain} rule.
+ this.javacJvmOptions = ImmutableList.<String>builder()
+ .addAll(data.getJavacJvmOptions())
+ .addAll(defaultJavacJvmOpts)
+ .build();
}
/**
@@ -49,6 +56,13 @@
}
/**
+ * @return the list of default options for the JVM running the java compiler
+ */
+ public ImmutableList<String> getJavacJvmOptions() {
+ return javacJvmOptions;
+ }
+
+ /**
* An helper method to construct the list of javac options.
*
* @param ruleContext The rule context of the current rule.
@@ -59,10 +73,31 @@
JavaToolchainProvider javaToolchain =
ruleContext.getPrerequisite(":java_toolchain", Mode.TARGET, JavaToolchainProvider.class);
if (javaToolchain == null) {
- ruleContext.ruleError("No java_toolchain implicit dependency found. This is probably because"
- + " your java configuration is not up-to-date.");
+ ruleContext.ruleError("The --java_toolchain option does not point to a java_toolchain rule.");
return ImmutableList.of();
}
return javaToolchain.getJavacOptions();
}
+
+ /**
+ * An helper method to construct the list of options to pass to the JVM running the java compiler.
+ *
+ * @param ruleContext The rule context of the current rule.
+ * @return the list of flags provided by the {@code java_toolchain} rule merged with the one
+ * provided by the {@link JavaConfiguration} fragment.
+ */
+ public static List<String> getDefaultJavacJvmOptions(RuleContext ruleContext) {
+ if (!ruleContext.getRule().isAttrDefined(":java_toolchain", Type.LABEL)) {
+ // As some rules might not have java_toolchain dependency (e.g., java_import), we silently
+ // ignore it. The rules needing it will error in #getDefaultJavacOptions(RuleContext) anyway.
+ return ImmutableList.of();
+ }
+ JavaToolchainProvider javaToolchain =
+ ruleContext.getPrerequisite(":java_toolchain", Mode.TARGET, JavaToolchainProvider.class);
+ if (javaToolchain == null) {
+ ruleContext.ruleError("The --java_toolchain option does not point to a java_toolchain rule.");
+ return ImmutableList.of();
+ }
+ return javaToolchain.getJavacJvmOptions();
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java
index 5da931d..4a45461 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java
@@ -28,6 +28,20 @@
* Rule definition for {@code java_toolchain}
*/
public final class JavaToolchainRule implements RuleDefinition {
+ // TODO(dmarting): remove this and make -client the default once the jvm_opts field is released.
+ private final ImmutableList<String> defaultJavacJvmOpts;
+
+ public JavaToolchainRule() {
+ defaultJavacJvmOpts = ImmutableList.<String>of("-client");
+ }
+
+ /**
+ * Construct a {@link JavaToolchainRule} with a different set of default JVM options for Javac.
+ */
+ public JavaToolchainRule(ImmutableList<String> defaultJavacJvmOpts) {
+ this.defaultJavacJvmOpts = defaultJavacJvmOpts;
+ }
+
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
return builder.setUndocumented()
@@ -50,11 +64,16 @@
removes it. Please see the Javac documentation on the -Xlint options for more information.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(attr("xlint", STRING_LIST).value(ImmutableList.<String>of()))
- /* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(xlint) -->
+ /* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(misc) -->
The list of extra arguments for the Java compiler. Please refer to the Java compiler
documentation for the extensive list of possible Java compiler flags.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(attr("misc", STRING_LIST).value(ImmutableList.<String>of()))
+ /* <!-- #BLAZE_RULE(java_toolchain).ATTRIBUTE(jvm_opts) -->
+ The list of arguments for the JVM when invoking the Java compiler. Please refer to the Java
+ virtual machine documentation for the extensive list of possible flags for this option.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(attr("jvm_opts", STRING_LIST).value(defaultJavacJvmOpts))
.build();
}