diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/BUILD b/src/main/java/com/google/devtools/build/lib/rules/java/BUILD index d458a333e64969..6915118434a5e8 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/BUILD +++ b/src/main/java/com/google/devtools/build/lib/rules/java/BUILD @@ -152,6 +152,7 @@ java_library( "JavaStrictCompilationArgsProvider.java", "JavaTargetAttributes.java", "JavaToolchainProvider.java", + "JavaToolchainTool.java", "JavaUtil.java", "MessageBundleInfo.java", "NativeLibraryNestedSetBuilder.java", 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 41ca3e6e5afebe..ddca056d749dbc 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 @@ -61,7 +61,6 @@ public final class JavaCompilationHelper { private final JavaTargetAttributes.Builder attributes; private JavaTargetAttributes builtAttributes; private final ImmutableList customJavacOpts; - private final ImmutableList customJavacJvmOpts; private final List translations = new ArrayList<>(); private boolean translationsFrozen; private final JavaSemantics semantics; @@ -82,7 +81,6 @@ private JavaCompilationHelper( this.javaToolchain = Preconditions.checkNotNull(javaToolchainProvider); this.attributes = attributes; this.customJavacOpts = javacOpts; - this.customJavacJvmOpts = javaToolchain.getJavabuilderJvmOptions(); this.semantics = semantics; this.additionalInputsForDatabinding = additionalInputsForDatabinding; this.strictJavaDeps = @@ -301,7 +299,6 @@ public void createCompileAction(JavaCompileOutputs outputs) builder.setSourceFiles(sourceFiles); builder.setSourceJars(sourceJars); builder.setJavacOpts(customJavacOpts); - builder.setJavacJvmOpts(customJavacJvmOpts); builder.setJavacExecutionInfo(getExecutionInfo()); builder.setCompressJar(true); builder.setBuiltinProcessorNames(javaToolchain.getHeaderCompilerBuiltinProcessors()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java index 71b9675d5a5c2e..a5e84a12f0187e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileActionBuilder.java @@ -26,12 +26,11 @@ import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.ActionEnvironment; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.CommandLine; import com.google.devtools.build.lib.actions.EmptyRunfilesSupplier; import com.google.devtools.build.lib.actions.ExecutionRequirements; -import com.google.devtools.build.lib.actions.RunfilesSupplier; import com.google.devtools.build.lib.actions.extra.ExtraActionInfo; import com.google.devtools.build.lib.actions.extra.JavaCompileInfo; -import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.config.CoreOptionConverters.StrictDepsMode; @@ -143,13 +142,12 @@ public void extend(ExtraActionInfo.Builder builder, ImmutableList argume private NestedSet compileTimeDependencyArtifacts = NestedSetBuilder.emptySet(Order.STABLE_ORDER); private ImmutableList javacOpts = ImmutableList.of(); - private ImmutableList javacJvmOpts = ImmutableList.of(); private ImmutableMap executionInfo = ImmutableMap.of(); private boolean compressJar; private NestedSet classpathEntries = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); private BootClassPathInfo bootClassPath = BootClassPathInfo.empty(); private ImmutableList sourcePathEntries = ImmutableList.of(); - private FilesToRunProvider javaBuilder; + private JavaToolchainTool javaBuilder; private NestedSet toolsJars = NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER); private JavaPluginInfo plugins = JavaPluginInfo.empty(); private ImmutableSet builtinProcessorNames = ImmutableSet.of(); @@ -190,26 +188,10 @@ public JavaCompileAction build() { compileTimeDependencyArtifacts = NestedSetBuilder.emptySet(Order.STABLE_ORDER); } - CustomCommandLine.Builder executableLine = CustomCommandLine.builder(); NestedSetBuilder toolsBuilder = NestedSetBuilder.compileOrder(); - RunfilesSupplier runfilesSupplier = EmptyRunfilesSupplier.INSTANCE; - - // The actual params-file-based command line executed for a compile action. - Artifact javaBuilderJar = checkNotNull(javaBuilder.getExecutable()); - if (!javaBuilderJar.getExtension().equals("jar")) { - // JavaBuilder is a non-deploy.jar executable. - executableLine.addPath(javaBuilder.getExecutable().getExecPath()); - runfilesSupplier = javaBuilder.getRunfilesSupplier(); - toolsBuilder.addTransitive(javaBuilder.getFilesToRun()); - } else { - toolsBuilder.add(javaBuilderJar); - executableLine - .addPath(toolchain.getJavaRuntime().javaBinaryExecPathFragment()) - .addAll(javacJvmOpts) - .add("-jar") - .addPath(javaBuilderJar.getExecPath()); - } + CommandLine executableLine = javaBuilder.buildCommandLine(toolchain, toolsBuilder); + toolsBuilder.addTransitive(toolsJars); ActionEnvironment actionEnvironment = @@ -268,7 +250,7 @@ public JavaCompileAction build() { /* owner= */ ruleContext.getActionOwner(), /* env= */ actionEnvironment, /* tools= */ tools, - /* runfilesSupplier= */ runfilesSupplier, + /* runfilesSupplier= */ EmptyRunfilesSupplier.INSTANCE, /* progressMessage= */ new ProgressMessage( /* prefix= */ "Building", /* output= */ outputs.output(), @@ -281,7 +263,7 @@ public JavaCompileAction build() { /* outputs= */ allOutputs(), /* executionInfo= */ executionInfo, /* extraActionInfoSupplier= */ extraActionInfoSupplier, - /* executableLine= */ executableLine.build(), + /* executableLine= */ executableLine, /* flagLine= */ buildParamFileContents(internedJcopts), /* configuration= */ ruleContext.getConfiguration(), /* dependencyArtifacts= */ compileTimeDependencyArtifacts, @@ -403,11 +385,6 @@ public JavaCompileActionBuilder setJavacOpts(ImmutableList copts) { return this; } - public JavaCompileActionBuilder setJavacJvmOpts(ImmutableList opts) { - this.javacJvmOpts = opts; - return this; - } - public JavaCompileActionBuilder setJavacExecutionInfo( ImmutableMap executionInfo) { this.executionInfo = executionInfo; @@ -461,7 +438,7 @@ public JavaCompileActionBuilder setToolsJars(NestedSet toolsJars) { return this; } - public JavaCompileActionBuilder setJavaBuilder(FilesToRunProvider javaBuilder) { + public JavaCompileActionBuilder setJavaBuilder(JavaToolchainTool javaBuilder) { this.javaBuilder = javaBuilder; return this; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java index a5e336c98945c9..253ec2c4b83e52 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaHeaderCompileActionBuilder.java @@ -29,13 +29,12 @@ import com.google.devtools.build.lib.actions.ActionEnvironment; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.CommandLine; import com.google.devtools.build.lib.actions.CommandLines; -import com.google.devtools.build.lib.actions.CompositeRunfilesSupplier; +import com.google.devtools.build.lib.actions.EmptyRunfilesSupplier; import com.google.devtools.build.lib.actions.ExecutionRequirements; import com.google.devtools.build.lib.actions.ParamFileInfo; -import com.google.devtools.build.lib.actions.RunfilesSupplier; import com.google.devtools.build.lib.actions.SpawnResult; -import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.SpawnAction; @@ -318,32 +317,13 @@ public void build(JavaToolchainProvider javaToolchain) throws InterruptedExcepti .addAll(sourceFiles) .addTransitive(toolsJars); - ImmutableList runfilesSuppliers = ImmutableList.of(); - FilesToRunProvider headerCompiler = + JavaToolchainTool headerCompiler = useHeaderCompilerDirect ? javaToolchain.getHeaderCompilerDirect() : javaToolchain.getHeaderCompiler(); // The header compiler is either a jar file that needs to be executed using // `java -jar `, or an executable that can be run directly. - CustomCommandLine executableLine; - if (!headerCompiler.getExecutable().getExtension().equals("jar")) { - runfilesSuppliers = ImmutableList.of(headerCompiler.getRunfilesSupplier()); - mandatoryInputs.addTransitive(headerCompiler.getFilesToRun()); - executableLine = - CustomCommandLine.builder().addExecPath(headerCompiler.getExecutable()).build(); - } else { - mandatoryInputs - .addTransitive(javaToolchain.getJavaRuntime().javaBaseInputsMiddleman()) - .add(headerCompiler.getExecutable()); - executableLine = - CustomCommandLine.builder() - .addPath(javaToolchain.getJavaRuntime().javaBinaryExecPathFragment()) - .add("-Xverify:none") - .addAll(javaToolchain.getTurbineJvmOptions()) - .add("-jar") - .addExecPath(headerCompiler.getExecutable()) - .build(); - } + CommandLine executableLine = headerCompiler.buildCommandLine(javaToolchain, mandatoryInputs); CustomCommandLine.Builder commandLine = CustomCommandLine.builder() @@ -418,7 +398,7 @@ public void build(JavaToolchainProvider javaToolchain) throws InterruptedExcepti .getConfiguration() .modifiedExecutionInfo(executionInfo, "Turbine"), /* progressMessage= */ progressMessage, - /* runfilesSupplier= */ CompositeRunfilesSupplier.fromSuppliers(runfilesSuppliers), + /* runfilesSupplier= */ EmptyRunfilesSupplier.INSTANCE, /* mnemonic= */ "Turbine", /* executeUnconditionally= */ false, /* extraActionInfoSupplier= */ null, @@ -455,7 +435,7 @@ public void build(JavaToolchainProvider javaToolchain) throws InterruptedExcepti /* owner= */ ruleContext.getActionOwner(), /* env= */ actionEnvironment, /* tools= */ toolsJars, - /* runfilesSupplier= */ CompositeRunfilesSupplier.fromSuppliers(runfilesSuppliers), + /* runfilesSupplier= */ EmptyRunfilesSupplier.INSTANCE, /* progressMessage= */ progressMessage, /* mandatoryInputs= */ mandatoryInputs.build(), /* transitiveInputs= */ classpathEntries, 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 d5f4720054047d..5d43941930da47 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 @@ -57,10 +57,6 @@ public ConfiguredTarget create(RuleContext ruleContext) ruleContext.attributes().get("javac_supports_workers", Type.BOOLEAN); boolean javacSupportsMultiplexWorkers = ruleContext.attributes().get("javac_supports_multiplex_workers", Type.BOOLEAN); - FilesToRunProvider javabuilder = ruleContext.getExecutablePrerequisite("javabuilder"); - FilesToRunProvider headerCompiler = ruleContext.getExecutablePrerequisite("header_compiler"); - FilesToRunProvider headerCompilerDirect = - ruleContext.getExecutablePrerequisite("header_compiler_direct"); ImmutableSet headerCompilerBuiltinProcessors = ImmutableSet.copyOf( ruleContext.attributes().get("header_compiler_builtin_processors", Type.STRING_LIST)); @@ -85,17 +81,18 @@ public ConfiguredTarget create(RuleContext ruleContext) NestedSet tools = PrerequisiteArtifacts.nestedSet(ruleContext, "tools"); - ImmutableList jvmOpts = getJvmOpts(ruleContext, "jvm_opts"); - ImmutableList javabuilderJvmOpts = - ImmutableList.builder() - .addAll(jvmOpts) - .addAll(getJvmOpts(ruleContext, "javabuilder_jvm_opts")) - .build(); - ImmutableList turbineJvmOpts = - ImmutableList.builder() - .addAll(jvmOpts) - .addAll(getJvmOpts(ruleContext, "turbine_jvm_opts")) - .build(); + ImmutableList jvmOpts = + ruleContext.getExpander().withExecLocations(ImmutableMap.of()).list("jvm_opts"); + + JavaToolchainTool javabuilder = + JavaToolchainTool.fromRuleContext( + ruleContext, "javabuilder", "javabuilder_data", "javabuilder_jvm_opts"); + JavaToolchainTool headerCompiler = + JavaToolchainTool.fromRuleContext( + ruleContext, "header_compiler", "turbine_data", "turbine_jvm_opts"); + JavaToolchainTool headerCompilerDirect = + JavaToolchainTool.fromFilesToRunProvider( + ruleContext.getExecutablePrerequisite("header_compiler_direct")); ImmutableList packageConfiguration = ImmutableList.copyOf( @@ -113,8 +110,6 @@ public ConfiguredTarget create(RuleContext ruleContext) ruleContext.getLabel(), javacopts, jvmOpts, - javabuilderJvmOpts, - turbineJvmOpts, javacSupportsWorkers, javacSupportsMultiplexWorkers, bootclasspath, @@ -177,12 +172,6 @@ private static ImmutableListMultimap getCompatibleJavacOptions( return result.build(); } - private static ImmutableList getJvmOpts( - RuleContext ruleContext, - String attribute) { - return ruleContext.getExpander().withExecLocations(ImmutableMap.of()).list(attribute); - } - private static BootClassPathInfo getBootClassPathInfo(RuleContext ruleContext) { List bootClassPathInfos = ruleContext.getPrerequisites("bootclasspath", BootClassPathInfo.PROVIDER); 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 98d2814e858833..a0067df6eb1ba5 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 @@ -72,15 +72,13 @@ public static JavaToolchainProvider create( Label label, ImmutableList javacOptions, ImmutableList jvmOptions, - ImmutableList javabuilderJvmOptions, - ImmutableList turbineJvmOptions, boolean javacSupportsWorkers, boolean javacSupportsMultiplexWorkers, BootClassPathInfo bootclasspath, NestedSet tools, - FilesToRunProvider javaBuilder, - @Nullable FilesToRunProvider headerCompiler, - @Nullable FilesToRunProvider headerCompilerDirect, + JavaToolchainTool javaBuilder, + @Nullable JavaToolchainTool headerCompiler, + @Nullable JavaToolchainTool headerCompilerDirect, ImmutableSet headerCompilerBuiltinProcessors, ImmutableSet reducedClasspathIncompatibleProcessors, boolean forciblyDisableHeaderCompilation, @@ -117,8 +115,6 @@ public static JavaToolchainProvider create( compatibleJavacOptions, javacOptions, jvmOptions, - javabuilderJvmOptions, - turbineJvmOptions, javacSupportsWorkers, javacSupportsMultiplexWorkers, packageConfiguration, @@ -131,9 +127,9 @@ public static JavaToolchainProvider create( private final Label label; private final BootClassPathInfo bootclasspath; private final NestedSet tools; - private final FilesToRunProvider javaBuilder; - @Nullable private final FilesToRunProvider headerCompiler; - @Nullable private final FilesToRunProvider headerCompilerDirect; + private final JavaToolchainTool javaBuilder; + @Nullable private final JavaToolchainTool headerCompiler; + @Nullable private final JavaToolchainTool headerCompilerDirect; private final ImmutableSet headerCompilerBuiltinProcessors; private final ImmutableSet reducedClasspathIncompatibleProcessors; private final boolean forciblyDisableHeaderCompilation; @@ -147,8 +143,6 @@ public static JavaToolchainProvider create( private final ImmutableListMultimap compatibleJavacOptions; private final ImmutableList javacOptions; private final ImmutableList jvmOptions; - private final ImmutableList javabuilderJvmOptions; - private final ImmutableList turbineJvmOptions; private final boolean javacSupportsWorkers; private final boolean javacSupportsMultiplexWorkers; private final ImmutableList packageConfiguration; @@ -162,9 +156,9 @@ public static JavaToolchainProvider create( Label label, BootClassPathInfo bootclasspath, NestedSet tools, - FilesToRunProvider javaBuilder, - @Nullable FilesToRunProvider headerCompiler, - @Nullable FilesToRunProvider headerCompilerDirect, + JavaToolchainTool javaBuilder, + @Nullable JavaToolchainTool headerCompiler, + @Nullable JavaToolchainTool headerCompilerDirect, ImmutableSet headerCompilerBuiltinProcessors, ImmutableSet reducedClasspathIncompatibleProcessors, boolean forciblyDisableHeaderCompilation, @@ -178,8 +172,6 @@ public static JavaToolchainProvider create( ImmutableListMultimap compatibleJavacOptions, ImmutableList javacOptions, ImmutableList jvmOptions, - ImmutableList javabuilderJvmOptions, - ImmutableList turbineJvmOptions, boolean javacSupportsWorkers, boolean javacSupportsMultiplexWorkers, ImmutableList packageConfiguration, @@ -208,8 +200,6 @@ public static JavaToolchainProvider create( this.compatibleJavacOptions = compatibleJavacOptions; this.javacOptions = javacOptions; this.jvmOptions = jvmOptions; - this.javabuilderJvmOptions = javabuilderJvmOptions; - this.turbineJvmOptions = turbineJvmOptions; this.javacSupportsWorkers = javacSupportsWorkers; this.javacSupportsMultiplexWorkers = javacSupportsMultiplexWorkers; this.packageConfiguration = packageConfiguration; @@ -234,14 +224,14 @@ public NestedSet getTools() { return tools; } - /** Returns the {@link FilesToRunProvider} of JavaBuilder */ - public FilesToRunProvider getJavaBuilder() { + /** Returns the {@link JavaToolchainTool} for JavaBuilder */ + public JavaToolchainTool getJavaBuilder() { return javaBuilder; } - /** @return the {@link FilesToRunProvider} of the Header Compiler deploy jar */ + /** Returns the {@link JavaToolchainTool} for the header compiler */ @Nullable - public FilesToRunProvider getHeaderCompiler() { + public JavaToolchainTool getHeaderCompiler() { return headerCompiler; } @@ -250,7 +240,7 @@ public FilesToRunProvider getHeaderCompiler() { * non-annotation processing actions. */ @Nullable - public FilesToRunProvider getHeaderCompilerDirect() { + public JavaToolchainTool getHeaderCompilerDirect() { return headerCompilerDirect; } @@ -350,15 +340,6 @@ public ImmutableList getJvmOptions() { return jvmOptions; } - /** Returns the list of JVM options for running JavaBuilder. */ - public ImmutableList getJavabuilderJvmOptions() { - return javabuilderJvmOptions; - } - - public ImmutableList getTurbineJvmOptions() { - return turbineJvmOptions; - } - /** @return whether JavaBuilders supports running as a persistent worker or not */ public boolean getJavacSupportsWorkers() { return javacSupportsWorkers; 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 4e2f3d752898c5..06b1b9f218e328 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 @@ -98,10 +98,24 @@ The Java target version (e.g., '6' or '7'). It specifies for which Java runtime The list of arguments for the JVM when invoking JavaBuilder. */ .add(attr("javabuilder_jvm_opts", STRING_LIST).value(ImmutableList.of())) + /* + Labels of data available for label-expansion in javabuilder_jvm_opts. + */ + .add( + attr("javabuilder_data", LABEL_LIST) + .cfg(ExecutionTransitionFactory.create()) + .allowedFileTypes(FileTypeSet.ANY_FILE)) /* The list of arguments for the JVM when invoking turbine. */ .add(attr("turbine_jvm_opts", STRING_LIST).value(ImmutableList.of())) + /* + Labels of data available for label-expansion in turbine_jvm_opts. + */ + .add( + attr("turbine_data", LABEL_LIST) + .cfg(ExecutionTransitionFactory.create()) + .allowedFileTypes(FileTypeSet.ANY_FILE)) /* True if JavaBuilder supports running as a persistent worker, false if it doesn't. */ diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainTool.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainTool.java new file mode 100644 index 00000000000000..110a55b19ea46b --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainTool.java @@ -0,0 +1,117 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.rules.java; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.CommandLine; +import com.google.devtools.build.lib.analysis.AliasProvider; +import com.google.devtools.build.lib.analysis.FileProvider; +import com.google.devtools.build.lib.analysis.FilesToRunProvider; +import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import javax.annotation.Nullable; + +/** An executable tool that is part of {@code java_toolchain}. */ +@AutoValue +@AutoCodec +public abstract class JavaToolchainTool { + + /** The executable, possibly a {@code _deploy.jar}. */ + public abstract FilesToRunProvider tool(); + + /** Additional inputs required by the tool, e.g. a Class Data Sharing archive. */ + public abstract ImmutableList data(); + + /** + * JVM flags to invoke the tool with, or empty if it is not a {@code _deploy.jar}. Location + * expansion is performed on these flags using the inputs in {@link #data}. + */ + public abstract ImmutableList jvmOpts(); + + @Nullable + static JavaToolchainTool fromRuleContext( + RuleContext ruleContext, + String toolAttribute, + String dataAttribute, + String jvmOptsAttribute) { + FilesToRunProvider tool = ruleContext.getExecutablePrerequisite(toolAttribute); + if (tool == null) { + return null; + } + TransitiveInfoCollection data = ruleContext.getPrerequisite(dataAttribute); + ImmutableList dataArtifacts = + data == null + ? ImmutableList.of() + : data.getProvider(FileProvider.class).getFilesToBuild().toList(); + ImmutableMap> locations = + data == null + ? ImmutableMap.of() + : ImmutableMap.of(AliasProvider.getDependencyLabel(data), dataArtifacts); + ImmutableList jvmOpts = + ruleContext.getExpander().withExecLocations(locations).list(jvmOptsAttribute); + return create(tool, dataArtifacts, jvmOpts); + } + + @Nullable + static JavaToolchainTool fromFilesToRunProvider(@Nullable FilesToRunProvider executable) { + if (executable == null) { + return null; + } + return create(executable, ImmutableList.of(), ImmutableList.of()); + } + + @AutoCodec.Instantiator + static JavaToolchainTool create( + FilesToRunProvider tool, ImmutableList data, ImmutableList jvmOpts) { + return new AutoValue_JavaToolchainTool(tool, data, jvmOpts); + } + + /** + * Builds the executable command line for the toola nd adds its inputs to the given builder. + * + *

For a Java command, the executable command line will include {@code java -jar deploy.jar} as + * well as any JVM flags. + * + * @param toolchains {@code java_toolchain} for the action being constructed + * @param inputs for the action being constructed + * @returns the executable command line for the tool + */ + CommandLine buildCommandLine(JavaToolchainProvider toolchain, NestedSetBuilder inputs) { + CustomCommandLine.Builder command = CustomCommandLine.builder(); + inputs.addAll(data()); + Artifact executable = tool().getExecutable(); + if (!executable.getExtension().equals("jar")) { + command.addExecPath(executable); + inputs.addTransitive(tool().getFilesToRun()); + } else { + inputs.add(executable).addTransitive(toolchain.getJavaRuntime().javaBaseInputsMiddleman()); + command + .addPath(toolchain.getJavaRuntime().javaBinaryExecPathFragment()) + .addAll(toolchain.getJvmOptions()) + .addAll(jvmOpts()) + .add("-jar") + .addPath(executable.getExecPath()); + } + return command.build(); + } +}