Use the correct JVM for LcovMerger instead of whatever "java" gets us.

Fixes #2904.

RELNOTES: None.
PiperOrigin-RevId: 158516169
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaTestRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaTestRule.java
index 3696b28..e309112 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaTestRule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaTestRule.java
@@ -63,7 +63,7 @@
         // Input files for test actions collecting code coverage
         .add(
             attr("$lcov_merger", LABEL)
-                .value(env.getLabel("@bazel_tools//tools/test:LcovMerger_deploy.jar")))
+                .value(env.getLabel("@bazel_tools//tools/test:LcovMerger")))
         .add(
             attr("$jacocorunner", LABEL)
                 .value(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestActionBuilder.java
index 9deb11f..6de3553 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/test/TestActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/test/TestActionBuilder.java
@@ -17,15 +17,18 @@
 import static com.google.devtools.build.lib.packages.BuildType.LABEL;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
+import com.google.devtools.build.lib.analysis.FileProvider;
 import com.google.devtools.build.lib.analysis.FilesToRunProvider;
 import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts;
 import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
 import com.google.devtools.build.lib.analysis.RuleContext;
 import com.google.devtools.build.lib.analysis.RunfilesSupport;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.collect.nestedset.NestedSet;
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -211,12 +214,24 @@
           ruleContext, "$coverage_support", Mode.DONT_CHECK));
       // We don't add this attribute to non-supported test target
       if (ruleContext.isAttrDefined("$lcov_merger", LABEL)) {
-        Artifact lcovMerger = ruleContext.getPrerequisiteArtifact("$lcov_merger", Mode.TARGET);
-        if (lcovMerger != null) {
-          inputsBuilder.addTransitive(
-              PrerequisiteArtifacts.nestedSet(ruleContext, "$lcov_merger", Mode.TARGET));
-          // Pass this LcovMerger_deploy.jar path to collect_coverage.sh
-          extraTestEnv.put("LCOV_MERGER", lcovMerger.getExecPathString());
+        TransitiveInfoCollection lcovMerger =
+            ruleContext.getPrerequisite("$lcov_merger", Mode.TARGET);
+        FilesToRunProvider lcovFilesToRun = lcovMerger.getProvider(FilesToRunProvider.class);
+        if (lcovFilesToRun != null) {
+          extraTestEnv.put("LCOV_MERGER", lcovFilesToRun.getExecutable().getExecPathString());
+          inputsBuilder.addTransitive(lcovFilesToRun.getFilesToRun());
+        } else {
+          NestedSet<Artifact> filesToBuild =
+              lcovMerger.getProvider(FileProvider.class).getFilesToBuild();
+
+          if (Iterables.size(filesToBuild) == 1) {
+            Artifact lcovMergerArtifact = Iterables.getOnlyElement(filesToBuild);
+            extraTestEnv.put("LCOV_MERGER", lcovMergerArtifact.getExecPathString());
+            inputsBuilder.add(lcovMergerArtifact);
+          } else {
+            ruleContext.attributeError("$lcov_merger",
+                "the LCOV merger should be either an executable or a single artifact");
+          }
         }
       }
 
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
index 60794b2..1c8b7fc 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java
@@ -139,7 +139,7 @@
 
     config.create("/bazel_tools_workspace/tools/test/BUILD",
         "filegroup(name = 'runtime', srcs = ['test-setup.sh'],)",
-        "filegroup(name='coverage_support', srcs=['collect_coverage.sh',':LcovMerger_deploy.jar'])",
+        "filegroup(name='coverage_support', srcs=['collect_coverage.sh','LcovMerger'])",
         "filegroup(name = 'coverage_report_generator', srcs = ['coverage_report_generator.sh'])");
 
     config.create(
diff --git a/tools/test/collect_coverage.sh b/tools/test/collect_coverage.sh
index b8e1dc7..559c60d 100755
--- a/tools/test/collect_coverage.sh
+++ b/tools/test/collect_coverage.sh
@@ -136,7 +136,7 @@
   exit $TEST_STATUS
 fi
 
-export LCOV_MERGER_CMD="java -jar ${LCOV_MERGER} --coverage_dir=${COVERAGE_DIR} \
+export LCOV_MERGER_CMD="${LCOV_MERGER} --coverage_dir=${COVERAGE_DIR} \
 --output_file=${COVERAGE_OUTPUT_FILE}"
 
 
@@ -146,4 +146,7 @@
   echo "-----------------"
 fi
 
-exec $LCOV_MERGER_CMD
+# JAVA_RUNFILES is set to the runfiles of the test, which does not necessarily
+# contain a JVM (it does only if the test has a Java binary somewhere). So let
+# the LCOV merger discover where its own runfiles tree is.
+JAVA_RUNFILES= exec $LCOV_MERGER_CMD