aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/actions/LazyWritePathsFileAction.java91
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java86
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ApkProvider.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java25
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java23
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java32
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationHelper.java80
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java31
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java44
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java14
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java4
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/java/proto/SkylarkJavaLiteProtoLibraryTest.java1
-rwxr-xr-xsrc/test/shell/bazel/bazel_coverage_test.sh95
21 files changed, 317 insertions, 290 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/LazyWritePathsFileAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/LazyWritePathsFileAction.java
new file mode 100644
index 0000000000..d349c6c02e
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/LazyWritePathsFileAction.java
@@ -0,0 +1,91 @@
+// Copyright 2017 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.analysis.actions;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.lib.actions.ActionExecutionContext;
+import com.google.devtools.build.lib.actions.ActionOwner;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.util.Fingerprint;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Lazily writes the exec path of the given files separated by newline into a specified output file.
+ */
+public final class LazyWritePathsFileAction extends AbstractFileWriteAction {
+ private static final String GUID = "6be94d90-96f3-4bec-8104-1fb08abc2546";
+
+ private final NestedSet<Artifact> files;
+ private final boolean includeOnlyIfSource;
+
+ public LazyWritePathsFileAction(
+ ActionOwner owner, Artifact output, NestedSet<Artifact> files, boolean includeOnlyIfSource) {
+ super(owner, Artifact.NO_ARTIFACTS, output, false);
+ this.files = NestedSetBuilder.fromNestedSet(files).build();
+ this.includeOnlyIfSource = includeOnlyIfSource;
+ }
+
+ public LazyWritePathsFileAction(
+ ActionOwner owner, Artifact output,
+ ImmutableSet<Artifact> files,
+ boolean includeOnlyIfSource) {
+ super(owner, Artifact.NO_ARTIFACTS, output, false);
+ this.files = NestedSetBuilder.<Artifact>stableOrder().addAll(files).build();
+ this.includeOnlyIfSource = includeOnlyIfSource;
+ }
+
+ @Override
+ public DeterministicWriter newDeterministicWriter(ActionExecutionContext ctx) {
+ return new DeterministicWriter() {
+ @Override
+ public void writeOutputFile(OutputStream out) throws IOException {
+ out.write(getContents().toString().getBytes(UTF_8));
+ }
+ };
+ }
+
+ /**
+ * Computes the Action key for this action by computing the fingerprint for the file contents.
+ */
+ @Override
+ protected String computeKey() {
+ Fingerprint f = new Fingerprint();
+ f.addString(GUID);
+ f.addBoolean(includeOnlyIfSource);
+ f.addString(getContents());
+ return f.hexDigestAndReset();
+ }
+
+ private String getContents() {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (Artifact file : files) {
+ if (includeOnlyIfSource) {
+ if (file.isSourceArtifact()) {
+ stringBuilder.append(file.getRootRelativePathString());
+ stringBuilder.append("\n");
+ }
+ } else {
+ stringBuilder.append(file.getRootRelativePathString());
+ stringBuilder.append("\n");
+ }
+ }
+ return stringBuilder.toString();
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java b/src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java
index f7d2fc184e..8b42e96721 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java
@@ -461,8 +461,8 @@ public class TestRunnerAction extends AbstractAction implements NotifyOnActionCa
env.put("COVERAGE_MANIFEST", getCoverageManifest().getExecPathString());
env.put("COVERAGE_DIR", getCoverageDirectory().getPathString());
env.put("COVERAGE_OUTPUT_FILE", getCoverageData().getExecPathString());
- // TODO(elenairina): Remove this after the next blaze release (after 2017.07.30).
- env.put("NEW_JAVA_COVERAGE_IMPL", "True");
+ // TODO(elenairina): Remove this after it reaches a blaze release.
+ env.put("NEW_JAVA_COVERAGE_IMPL", "released");
}
}
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 65956414df..ccfe515141 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
@@ -29,6 +29,7 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
+import com.google.devtools.build.lib.analysis.actions.LazyWritePathsFileAction;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.ComputedSubstitution;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
@@ -261,6 +262,8 @@ public class BazelJavaSemantics implements JavaSemantics {
List<String> jvmFlags,
Artifact executable,
String javaStartClass,
+ String coverageStartClass,
+ NestedSetBuilder<Artifact> filesBuilder,
String javaExecutable) {
Preconditions.checkState(ruleContext.getConfiguration().hasFragment(Jvm.class));
@@ -314,22 +317,35 @@ public class BazelJavaSemantics implements JavaSemantics {
}
arguments.add(new ComputedClasspathSubstitution(classpath, workspacePrefix, isRunfilesEnabled));
- JavaCompilationArtifacts javaArtifacts = javaCommon.getJavaCompilationArtifacts();
- String path =
- javaArtifacts.getInstrumentedJar() != null
- ? "${JAVA_RUNFILES}/"
- + workspacePrefix
- + javaArtifacts.getInstrumentedJar().getRootRelativePath().getPathString()
- : "";
- arguments.add(
- Substitution.of(
- "%set_jacoco_metadata%",
- ruleContext.getConfiguration().isCodeCoverageEnabled()
- ? "export JACOCO_METADATA_JAR=" + path
- : ""));
+ if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
+ Artifact runtimeClassPathArtifact = ruleContext.getUniqueDirectoryArtifact(
+ "coverage_runtime_classpath",
+ "runtime-classpath.txt",
+ ruleContext.getBinOrGenfilesDirectory());
+ ruleContext.registerAction(new LazyWritePathsFileAction(
+ ruleContext.getActionOwner(),
+ runtimeClassPathArtifact,
+ javaCommon.getRuntimeClasspath(),
+ false));
+ filesBuilder.add(runtimeClassPathArtifact);
+ arguments.add(Substitution.of(
+ JACOCO_METADATA_PLACEHOLDER,
+ "export JACOCO_METADATA_JAR=${JAVA_RUNFILES}/" + workspacePrefix + "/"
+ + runtimeClassPathArtifact.getRootRelativePathString()
+ ));
+ arguments.add(Substitution.of(
+ JACOCO_MAIN_CLASS_PLACEHOLDER, "export JACOCO_MAIN_CLASS=" + coverageStartClass));
+ arguments.add(Substitution.of(
+ JACOCO_JAVA_RUNFILES_ROOT_PLACEHOLDER,
+ "export JACOCO_JAVA_RUNFILES_ROOT=${JAVA_RUNFILES}/" + workspacePrefix)
+ );
+ } else {
+ arguments.add(Substitution.of(JavaSemantics.JACOCO_METADATA_PLACEHOLDER, ""));
+ arguments.add(Substitution.of(JavaSemantics.JACOCO_MAIN_CLASS_PLACEHOLDER, ""));
+ arguments.add(Substitution.of(JavaSemantics.JACOCO_JAVA_RUNFILES_ROOT_PLACEHOLDER, ""));
+ }
- arguments.add(Substitution.of("%java_start_class%",
- ShellEscaper.escapeString(javaStartClass)));
+ arguments.add(Substitution.of("%java_start_class%", ShellEscaper.escapeString(javaStartClass)));
ImmutableList<String> jvmFlagsList = ImmutableList.copyOf(jvmFlags);
arguments.add(Substitution.ofSpaceSeparatedList("%jvm_flags%", jvmFlagsList));
@@ -658,49 +674,11 @@ public class BazelJavaSemantics implements JavaSemantics {
return jvmFlags.build();
}
- /**
- * Returns whether coverage has instrumented artifacts.
- */
- public static boolean hasInstrumentationMetadata(JavaTargetAttributes.Builder attributes) {
- return !attributes.getInstrumentationMetadata().isEmpty();
- }
-
- // TODO(yueg): refactor this (only mainClass different for now)
@Override
- public String addCoverageSupport(
- JavaCompilationHelper helper,
- JavaTargetAttributes.Builder attributes,
- Artifact executable,
- Artifact instrumentationMetadata,
- JavaCompilationArtifacts.Builder javaArtifactsBuilder,
- String mainClass)
+ public String addCoverageSupport(JavaCompilationHelper helper, Artifact executable)
throws InterruptedException {
// This method can be called only for *_binary/*_test targets.
Preconditions.checkNotNull(executable);
- // Add our own metadata artifact (if any).
- if (instrumentationMetadata != null) {
- attributes.addInstrumentationMetadataEntries(ImmutableList.of(instrumentationMetadata));
- }
-
- if (!hasInstrumentationMetadata(attributes)) {
- return mainClass;
- }
-
- Artifact instrumentedJar =
- helper
- .getRuleContext()
- .getBinArtifact(helper.getRuleContext().getLabel().getName() + "_instrumented.jar");
-
- // Create an instrumented Jar. This will be referenced on the runtime classpath prior
- // to all other Jars.
- JavaCommon.createInstrumentedJarAction(
- helper.getRuleContext(),
- this,
- attributes.getInstrumentationMetadata(),
- instrumentedJar,
- mainClass);
- javaArtifactsBuilder.setInstrumentedJar(instrumentedJar);
-
// Add the coverage runner to the list of dependencies when compiling in coverage mode.
TransitiveInfoCollection runnerTarget =
helper.getRuleContext().getPrerequisite("$jacocorunner", Mode.TARGET);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt
index d5495c00b6..f1c5c84ba2 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt
@@ -245,6 +245,8 @@ export CLASSLOADER_PREFIX_PATH="${RUNPATH}"
# We need to make the metadata jar with uninstrumented classes available for generating
# the lcov-compatible coverage report, and we don't want it on the classpath.
%set_jacoco_metadata%
+%set_jacoco_main_class%
+%set_jacoco_java_runfiles_root%
if [[ -n "$JVM_DEBUG_PORT" ]]; then
JVM_DEBUG_SUSPEND=${DEFAULT_JVM_DEBUG_SUSPEND:-"y"}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index f6ce6b444d..9b7d5e1801 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -865,7 +865,6 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
ApkProvider.create(
zipAlignedApk,
unsignedApk,
- androidCommon.getInstrumentedJar(),
applicationManifest.getManifest(),
debugKeystore))
.addProvider(AndroidPreDexJarProvider.class, AndroidPreDexJarProvider.create(jarToDex))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
index 3b296a4856..17686ee83a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java
@@ -447,12 +447,11 @@ public class AndroidCommon {
} else {
Artifact outputDepsProto =
javacHelper.createOutputDepsProtoArtifact(resourceClassJar, javaArtifactsBuilder);
- javacHelper.createCompileActionWithInstrumentation(
+ javacHelper.createCompileAction(
resourceClassJar,
null /* manifestProtoOutput */,
null /* genSourceJar */,
- outputDepsProto,
- javaArtifactsBuilder);
+ outputDepsProto);
}
} else {
// Otherwise, it should have been the AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR.
@@ -697,8 +696,7 @@ public class AndroidCommon {
helper.createSourceJarAction(srcJar, genSourceJar);
outputDepsProto = helper.createOutputDepsProtoArtifact(classJar, javaArtifactsBuilder);
- helper.createCompileActionWithInstrumentation(classJar, manifestProtoOutput, genSourceJar,
- outputDepsProto, javaArtifactsBuilder);
+ helper.createCompileAction(classJar, manifestProtoOutput, genSourceJar, outputDepsProto);
if (isBinary) {
generatedExtensionRegistryProvider =
@@ -879,6 +877,10 @@ public class AndroidCommon {
return javaCommon.getJavacOpts();
}
+ public Artifact getClassJar() {
+ return classJar;
+ }
+
public Artifact getGenClassJar() {
return genClassJar;
}
@@ -904,10 +906,6 @@ public class AndroidCommon {
return jarsProducedForRuntime;
}
- public Artifact getInstrumentedJar() {
- return javaCommon.getJavaCompilationArtifacts().getInstrumentedJar();
- }
-
public NestedSet<Artifact> getTransitiveNeverLinkLibraries() {
return transitiveNeverlinkLibraries;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
index 01c4e6b89b..48d8bb115e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
@@ -126,8 +126,6 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
JavaCompilationHelper helper =
getJavaCompilationHelperWithDependencies(ruleContext, javaSemantics, javaCommon,
attributesBuilder);
- Artifact instrumentationMetadata =
- helper.createInstrumentationMetadata(classJar, javaArtifactsBuilder);
Artifact executable; // the artifact for the rule itself
if (OS.getCurrent() == OS.WINDOWS
&& ruleContext.getConfiguration().enableWindowsExeLauncher()) {
@@ -154,7 +152,7 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
javaSemantics,
helper,
executable,
- instrumentationMetadata,
+ null,
javaArtifactsBuilder,
attributesBuilder);
@@ -178,11 +176,7 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
helper.createOutputDepsProtoArtifact(classJar, javaArtifactsBuilder);
javaRuleOutputJarsProviderBuilder.setJdeps(outputDepsProtoArtifact);
helper.createCompileAction(
- classJar,
- manifestProtoOutput,
- genSourceJar,
- outputDepsProtoArtifact,
- instrumentationMetadata);
+ classJar, manifestProtoOutput, genSourceJar, outputDepsProtoArtifact);
helper.createSourceJarAction(srcJar, genSourceJar);
setUpJavaCommon(javaCommon, helper, javaArtifactsBuilder.build());
@@ -202,6 +196,8 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
getJvmFlags(ruleContext, testClass),
executable,
mainClass,
+ "com.google.testing.junit.runner.GoogleTestRunner",
+ filesToBuildBuilder,
javaExecutable);
Artifact deployJar =
@@ -428,13 +424,6 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
builder.addTargets(depsForRunfiles, RunfilesProvider.DEFAULT_RUNFILES);
builder.addTransitiveArtifacts(transitiveAarArtifacts);
- if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
- Artifact instrumentedJar = javaCommon.getJavaCompilationArtifacts().getInstrumentedJar();
- if (instrumentedJar != null) {
- builder.addArtifact(instrumentedJar);
- }
- }
-
builder.addArtifacts(javaCommon.getRuntimeClasspath());
// Add the JDK files if it comes from P4 (see java_stub_template.txt).
@@ -469,3 +458,4 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
return testClass;
}
}
+
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApkProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApkProvider.java
index d265fd3160..70676b701d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ApkProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApkProvider.java
@@ -17,7 +17,6 @@ import com.google.auto.value.AutoValue;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import javax.annotation.Nullable;
/** A provider for targets that produce an apk file. */
@AutoValue
@@ -27,10 +26,9 @@ public abstract class ApkProvider implements TransitiveInfoProvider {
public static ApkProvider create(
Artifact apk,
Artifact unsignedApk,
- @Nullable Artifact coverageMetdata,
Artifact mergedManifest,
Artifact keystore) {
- return new AutoValue_ApkProvider(apk, unsignedApk, coverageMetdata, mergedManifest, keystore);
+ return new AutoValue_ApkProvider(apk, unsignedApk, mergedManifest, keystore);
}
/** Returns the APK file built in the transitive closure. */
@@ -39,10 +37,6 @@ public abstract class ApkProvider implements TransitiveInfoProvider {
/** Returns the unsigned APK file built in the transitive closure. */
public abstract Artifact getUnsignedApk();
- /** Returns the coverage metadata artifacts generated in the transitive closure. */
- @Nullable
- public abstract Artifact getCoverageMetadata();
-
/** Returns the merged manifest. */
public abstract Artifact getMergedManifest();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
index 0672fe4942..c98d231f52 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
@@ -79,7 +79,6 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
JavaTargetAttributes.Builder attributesBuilder = common.initCommon();
attributesBuilder.addClassPathResources(
ruleContext.getPrerequisiteArtifacts("classpath_resources", Mode.TARGET).list());
-
// Add Java8 timezone resource data
addTimezoneResourceForJavaBinaries(ruleContext, attributesBuilder);
@@ -148,8 +147,6 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
}
JavaCompilationArtifacts.Builder javaArtifactsBuilder = new JavaCompilationArtifacts.Builder();
- Artifact instrumentationMetadata =
- helper.createInstrumentationMetadata(classJar, javaArtifactsBuilder);
NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.stableOrder();
Artifact executableForRunfiles = null;
@@ -166,14 +163,7 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
filesBuilder.add(classJar).add(executableForRunfiles);
if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
- mainClass =
- semantics.addCoverageSupport(
- helper,
- attributesBuilder,
- executableForRunfiles,
- instrumentationMetadata,
- javaArtifactsBuilder,
- mainClass);
+ mainClass = semantics.addCoverageSupport(helper, executableForRunfiles);
}
} else {
filesBuilder.add(classJar);
@@ -224,8 +214,7 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
helper.createGenJarAction(classJar, manifestProtoOutput, genClassJar);
}
- helper.createCompileAction(
- classJar, manifestProtoOutput, genSourceJar, outputDepsProto, instrumentationMetadata);
+ helper.createCompileAction(classJar, manifestProtoOutput, genSourceJar, outputDepsProto);
helper.createSourceJarAction(srcJar, genSourceJar);
common.setClassPathFragment(
@@ -260,6 +249,8 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
jvmFlags,
executableForRunfiles,
mainClass,
+ originalMainClass,
+ filesBuilder,
javaExecutable);
if (!executableToRun.equals(executableForRunfiles)) {
filesBuilder.add(executableToRun);
@@ -505,13 +496,6 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
builder.addTargets(runtimeDeps, RunfilesProvider.DEFAULT_RUNFILES);
semantics.addDependenciesForRunfiles(ruleContext, builder);
- if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
- Artifact instrumentedJar = javaArtifacts.getInstrumentedJar();
- if (instrumentedJar != null) {
- builder.addArtifact(instrumentedJar);
- }
- }
-
builder.addArtifacts((Iterable<Artifact>) common.getRuntimeClasspath());
// Add the JDK files if it comes from the source repository (see java_stub_template.txt).
@@ -594,3 +578,4 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
}
}
}
+
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
index 8e7fdf2395..fd3258d566 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCommon.java
@@ -173,28 +173,6 @@ public class JavaCommon {
}
}
- /**
- * Creates an action to aggregate all metadata artifacts into a single
- * &lt;target_name&gt;_instrumented.jar file.
- */
- public static void createInstrumentedJarAction(
- RuleContext ruleContext,
- JavaSemantics semantics,
- List<Artifact> metadataArtifacts,
- Artifact instrumentedJar,
- String mainClass)
- throws InterruptedException {
- // In Jacoco's setup, metadata artifacts are real jars.
- new DeployArchiveBuilder(semantics, ruleContext)
- .setOutputJar(instrumentedJar)
- // We need to save the original mainClass because we're going to run inside CoverageRunner
- .setJavaStartClass(mainClass)
- .setAttributes(new JavaTargetAttributes.Builder(semantics).build())
- .addRuntimeJars(ImmutableList.copyOf(metadataArtifacts))
- .setCompression(DeployArchiveBuilder.Compression.UNCOMPRESSED)
- .build();
- }
-
public static ImmutableList<String> getConstraints(RuleContext ruleContext) {
return ruleContext.getRule().isAttrDefined("constraints", Type.STRING_LIST)
? ImmutableList.copyOf(ruleContext.attributes().get("constraints", Type.STRING_LIST))
@@ -756,7 +734,6 @@ public class JavaCommon {
.addTransitiveTargets(runtimeDepInfo, true, ClasspathType.RUNTIME_ONLY)
.build();
attributes.addRuntimeClassPathEntries(args.getRuntimeJars());
- attributes.addInstrumentationMetadataEntries(args.getInstrumentationMetadata());
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java
index f30705bba4..65896c4fd3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArgs.java
@@ -22,7 +22,6 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.util.FileType;
-import java.util.Collection;
/** A container of Java compilation artifacts. */
@AutoValue
@@ -42,14 +41,11 @@ public abstract class JavaCompilationArgs {
public static final JavaCompilationArgs EMPTY_ARGS =
JavaCompilationArgs.create(
NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER),
- NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER),
NestedSetBuilder.<Artifact>create(Order.NAIVE_LINK_ORDER));
private static JavaCompilationArgs create(
- NestedSet<Artifact> runtimeJars,
- NestedSet<Artifact> compileTimeJars,
- NestedSet<Artifact> instrumentationMetadata) {
- return new AutoValue_JavaCompilationArgs(runtimeJars, compileTimeJars, instrumentationMetadata);
+ NestedSet<Artifact> runtimeJars, NestedSet<Artifact> compileTimeJars) {
+ return new AutoValue_JavaCompilationArgs(runtimeJars, compileTimeJars);
}
/** Returns transitive runtime jars. */
@@ -58,9 +54,6 @@ public abstract class JavaCompilationArgs {
/** Returns transitive compile-time jars. */
public abstract NestedSet<Artifact> getCompileTimeJars();
- /** Returns transitive instrumentation metadata jars. */
- public abstract NestedSet<Artifact> getInstrumentationMetadata();
-
/**
* Returns a new builder instance.
*/
@@ -76,8 +69,6 @@ public abstract class JavaCompilationArgs {
NestedSetBuilder.naiveLinkOrder();
private final NestedSetBuilder<Artifact> compileTimeJarsBuilder =
NestedSetBuilder.naiveLinkOrder();
- private final NestedSetBuilder<Artifact> instrumentationMetadataBuilder =
- NestedSetBuilder.naiveLinkOrder();
/**
* Use {@code TransitiveJavaCompilationArgs#builder()} to instantiate the builder.
@@ -95,7 +86,6 @@ public abstract class JavaCompilationArgs {
addRuntimeJars(other.getRuntimeJars());
}
addCompileTimeJars(other.getCompileTimeJars());
- addInstrumentationMetadata(other.getInstrumentationMetadata());
return this;
}
@@ -137,16 +127,6 @@ public abstract class JavaCompilationArgs {
return this;
}
- public Builder addInstrumentationMetadata(Artifact instrumentationMetadata) {
- this.instrumentationMetadataBuilder.add(instrumentationMetadata);
- return this;
- }
-
- public Builder addInstrumentationMetadata(Collection<Artifact> instrumentationMetadata) {
- this.instrumentationMetadataBuilder.addAll(instrumentationMetadata);
- return this;
- }
-
public Builder addTransitiveCompilationArgs(
JavaCompilationArgsProvider dep, boolean recursive, ClasspathType type) {
JavaCompilationArgs args = recursive
@@ -239,8 +219,6 @@ public abstract class JavaCompilationArgs {
if (!ClasspathType.COMPILE_ONLY.equals(type)) {
runtimeJarsBuilder.addTransitive(args.getRuntimeJars());
}
- instrumentationMetadataBuilder.addTransitive(
- args.getInstrumentationMetadata());
return this;
}
@@ -248,10 +226,7 @@ public abstract class JavaCompilationArgs {
* Builds a {@link JavaCompilationArgs} object.
*/
public JavaCompilationArgs build() {
- return JavaCompilationArgs.create(
- runtimeJarsBuilder.build(),
- compileTimeJarsBuilder.build(),
- instrumentationMetadataBuilder.build());
+ return JavaCompilationArgs.create(runtimeJarsBuilder.build(), compileTimeJarsBuilder.build());
}
}
@@ -271,3 +246,4 @@ public abstract class JavaCompilationArgs {
JavaCompilationArgs() {}
}
+
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java
index e18ded353a..bd34392f35 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompilationArtifacts.java
@@ -19,10 +19,8 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-
import java.util.LinkedHashSet;
import java.util.Set;
-
import javax.annotation.Nullable;
/**
@@ -47,9 +45,7 @@ public abstract class JavaCompilationArtifacts {
public abstract ImmutableList<Artifact> getRuntimeJars();
public abstract ImmutableList<Artifact> getCompileTimeJars();
- public abstract ImmutableList<Artifact> getInstrumentationMetadata();
@Nullable public abstract Artifact getCompileTimeDependencyArtifact();
- @Nullable public abstract Artifact getInstrumentedJar();
/** Returns a builder for a {@link JavaCompilationArtifacts}. */
public static Builder builder() {
@@ -62,17 +58,13 @@ public abstract class JavaCompilationArtifacts {
public static final class Builder {
private final Set<Artifact> runtimeJars = new LinkedHashSet<>();
private final Set<Artifact> compileTimeJars = new LinkedHashSet<>();
- private final Set<Artifact> instrumentationMetadata = new LinkedHashSet<>();
private Artifact compileTimeDependencies;
- private Artifact instrumentedJar;
public JavaCompilationArtifacts build() {
return new AutoValue_JavaCompilationArtifacts(
ImmutableList.copyOf(runtimeJars),
ImmutableList.copyOf(compileTimeJars),
- ImmutableList.copyOf(instrumentationMetadata),
- compileTimeDependencies,
- instrumentedJar);
+ compileTimeDependencies);
}
public Builder addRuntimeJar(Artifact jar) {
@@ -95,19 +87,9 @@ public abstract class JavaCompilationArtifacts {
return this;
}
- public Builder addInstrumentationMetadata(Artifact instrumentationMetadata) {
- this.instrumentationMetadata.add(instrumentationMetadata);
- return this;
- }
-
public Builder setCompileTimeDependencies(@Nullable Artifact compileTimeDependencies) {
this.compileTimeDependencies = compileTimeDependencies;
return this;
}
-
- public Builder setInstrumentedJar(@Nullable Artifact instrumentedJar) {
- this.instrumentedJar = instrumentedJar;
- return this;
- }
}
}
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 aa2fc6a104..ac07ba6832 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
@@ -167,18 +167,16 @@ public final class JavaCompilationHelper {
*
* @param outputJar the class jar Artifact to create with the Action
* @param manifestProtoOutput the output artifact for the manifest proto emitted from JavaBuilder
- * @param gensrcOutputJar the generated sources jar Artifact to create with the Action
- * (null if no sources will be generated).
- * @param outputDepsProto the compiler-generated jdeps file to create with the Action
- * (null if not requested)
- * @param outputMetadata metadata file (null if no instrumentation is needed).
+ * @param gensrcOutputJar the generated sources jar Artifact to create with the Action (null if no
+ * sources will be generated).
+ * @param outputDepsProto the compiler-generated jdeps file to create with the Action (null if not
+ * requested)
*/
public void createCompileAction(
Artifact outputJar,
Artifact manifestProtoOutput,
@Nullable Artifact gensrcOutputJar,
- @Nullable Artifact outputDepsProto,
- @Nullable Artifact outputMetadata) {
+ @Nullable Artifact outputDepsProto) {
JavaTargetAttributes attributes = getAttributes();
@@ -211,7 +209,7 @@ public final class JavaCompilationHelper {
builder.setGensrcOutputJar(gensrcOutputJar);
builder.setOutputDepsProto(outputDepsProto);
builder.setAdditionalOutputs(attributes.getAdditionalOutputs());
- builder.setMetadata(outputMetadata);
+ builder.setFileWithPathsForCoverage(maybeCreateFileWithPathsForCoverage(outputJar));
builder.setInstrumentationJars(jacocoInstrumentation);
builder.setSourceFiles(attributes.getSourceFiles());
builder.addSourceJars(attributes.getSourceJars());
@@ -256,65 +254,15 @@ public final class JavaCompilationHelper {
}
}
- /**
- * Returns the instrumentation metadata files to be generated for a given output jar.
- *
- * <p>Only called if the output jar actually needs to be instrumented.
- */
- @Nullable
- private static Artifact createInstrumentationMetadataArtifact(
- RuleContext ruleContext, Artifact outputJar) {
- PathFragment packageRelativePath = outputJar.getRootRelativePath().relativeTo(
- ruleContext.getPackageDirectory());
- return ruleContext.getPackageRelativeArtifact(
- FileSystemUtils.replaceExtension(packageRelativePath, ".em"), outputJar.getRoot());
- }
-
- /**
- * Creates the Action that compiles Java source files and optionally instruments them for
- * coverage.
- *
- * @param outputJar the class jar Artifact to create with the Action
- * @param manifestProtoOutput the output artifact for the manifest proto emitted from JavaBuilder
- * @param gensrcJar the generated sources jar Artifact to create with the Action
- * @param outputDepsProto the compiler-generated jdeps file to create with the Action
- * @param javaArtifactsBuilder the build to store the instrumentation metadata in
- */
- public void createCompileActionWithInstrumentation(
- Artifact outputJar,
- Artifact manifestProtoOutput,
- @Nullable Artifact gensrcJar,
- @Nullable Artifact outputDepsProto,
- JavaCompilationArtifacts.Builder javaArtifactsBuilder) {
- createCompileAction(
- outputJar,
- manifestProtoOutput,
- gensrcJar,
- outputDepsProto,
- createInstrumentationMetadata(outputJar, javaArtifactsBuilder));
- }
-
- /**
- * Creates the instrumentation metadata artifact if needed.
- *
- * @return the instrumentation metadata artifact or null if instrumentation is
- * disabled
- */
- @Nullable
- public Artifact createInstrumentationMetadata(Artifact outputJar,
- JavaCompilationArtifacts.Builder javaArtifactsBuilder) {
- // If we need to instrument the jar, add additional output (the coverage metadata file) to the
- // JavaCompileAction.
- Artifact instrumentationMetadata = null;
- if (shouldInstrumentJar()) {
- instrumentationMetadata = createInstrumentationMetadataArtifact(
- getRuleContext(), outputJar);
-
- if (instrumentationMetadata != null) {
- javaArtifactsBuilder.addInstrumentationMetadata(instrumentationMetadata);
- }
+ private Artifact maybeCreateFileWithPathsForCoverage(Artifact outputJar) {
+ if (!shouldInstrumentJar()) {
+ return null;
}
- return instrumentationMetadata;
+ PathFragment packageRelativePath =
+ outputJar.getRootRelativePath().relativeTo(ruleContext.getPackageDirectory());
+ PathFragment path =
+ FileSystemUtils.replaceExtension(packageRelativePath, "-paths-for-coverage.txt");
+ return ruleContext.getPackageRelativeArtifact(path, outputJar.getRoot());
}
private boolean shouldInstrumentJar() {
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 c0c8ae4e80..6fe89c86fe 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
@@ -44,6 +44,7 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.CommandLine;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.CustomMultiArgv;
+import com.google.devtools.build.lib.analysis.actions.LazyWritePathsFileAction;
import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
@@ -498,7 +499,7 @@ public final class JavaCompileAction extends SpawnAction {
private Artifact outputDepsProto;
private Collection<Artifact> additionalOutputs;
private Artifact paramFile;
- private Artifact metadata;
+ private Artifact fileWithPathsForCoverage;
private ImmutableSet<Artifact> sourceFiles = ImmutableSet.of();
private final Collection<Artifact> sourceJars = new ArrayList<>();
private BuildConfiguration.StrictDepsMode strictJavaDeps =
@@ -592,7 +593,6 @@ public final class JavaCompileAction extends SpawnAction {
.addAll(
new ArrayList<>(Collections2.filter(Arrays.asList(
outputJar,
- metadata,
gensrcOutputJar,
manifestProtoOutput,
outputDepsProto), Predicates.notNull())));
@@ -615,6 +615,11 @@ public final class JavaCompileAction extends SpawnAction {
semantics.getJavaBuilderMainClass(),
pathSeparator);
+ if (fileWithPathsForCoverage != null) {
+ analysisEnvironment.registerAction(new LazyWritePathsFileAction(
+ owner, fileWithPathsForCoverage, sourceFiles, true));
+ }
+
// The actual params-file-based command line executed for a compile action.
CommandLine javaBuilderCommandLine =
CustomCommandLine.builder()
@@ -630,7 +635,7 @@ public final class JavaCompileAction extends SpawnAction {
.addAll(instrumentationJars)
.build();
- NestedSet<Artifact> inputs =
+ NestedSetBuilder<Artifact> inputsBuilder =
NestedSetBuilder.<Artifact>stableOrder()
.addTransitive(classpathEntries)
.addTransitive(compileTimeDependencyArtifacts)
@@ -642,8 +647,12 @@ public final class JavaCompileAction extends SpawnAction {
.addAll(sourcePathEntries)
.addAll(extdirInputs)
.add(paramFile)
- .addTransitive(tools)
- .build();
+ .addTransitive(tools);
+ if (fileWithPathsForCoverage != null) {
+ inputsBuilder.add(fileWithPathsForCoverage);
+ }
+
+ NestedSet<Artifact> inputs = inputsBuilder.build();
return new JavaCompileAction(
owner,
@@ -760,9 +769,9 @@ public final class JavaCompileAction extends SpawnAction {
}
}
}
- if (metadata != null) {
+ if (fileWithPathsForCoverage != null) {
result.add("--post_processor");
- result.addExecPath(JACOCO_INSTRUMENTATION_PROCESSOR, metadata);
+ result.addExecPath(JACOCO_INSTRUMENTATION_PROCESSOR, fileWithPathsForCoverage);
result.addPath(
configuration
.getCoverageMetadataDirectory(targetLabel.getPackageIdentifier().getRepository())
@@ -872,8 +881,8 @@ public final class JavaCompileAction extends SpawnAction {
return this;
}
- public Builder setMetadata(Artifact metadata) {
- this.metadata = metadata;
+ public Builder setFileWithPathsForCoverage(Artifact fileWithExecPathsForCoverage) {
+ this.fileWithPathsForCoverage = fileWithExecPathsForCoverage;
return this;
}
@@ -1019,3 +1028,7 @@ public final class JavaCompileAction extends SpawnAction {
}
}
}
+
+
+
+
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java
index 5932b19526..9326f735aa 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibrary.java
@@ -126,8 +126,7 @@ public class JavaLibrary implements RuleConfiguredTargetFactory {
Artifact outputDepsProto = helper.createOutputDepsProtoArtifact(classJar, javaArtifactsBuilder);
- helper.createCompileActionWithInstrumentation(classJar, manifestProtoOutput, genSourceJar,
- outputDepsProto, javaArtifactsBuilder);
+ helper.createCompileAction(classJar, manifestProtoOutput, genSourceJar, outputDepsProto);
helper.createSourceJarAction(srcJar, genSourceJar);
Artifact iJar = null;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
index 1be54d5358..8b43e9491c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaLibraryHelper.java
@@ -188,11 +188,7 @@ public final class JavaLibraryHelper {
jacocoInstrumental);
Artifact outputDepsProto = helper.createOutputDepsProtoArtifact(output, artifactsBuilder);
helper.createCompileAction(
- output,
- null /* manifestProtoOutput */,
- null /* gensrcOutputJar */,
- outputDepsProto,
- null /* outputMetadata */);
+ output, null /* manifestProtoOutput */, null /* gensrcOutputJar */, outputDepsProto);
helper.createCompileTimeJarAction(output, artifactsBuilder);
artifactsBuilder.addRuntimeJar(output);
@@ -244,7 +240,6 @@ public final class JavaLibraryHelper {
.build();
attributes.addCompileTimeClassPathEntries(args.getCompileTimeJars());
attributes.addRuntimeClassPathEntries(args.getRuntimeJars());
- attributes.addInstrumentationMetadataEntries(args.getInstrumentationMetadata());
}
private NestedSet<Artifact> getNonRecursiveCompileTimeJarsFromDeps() {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
index 9e2e719532..02e4149def 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
@@ -21,6 +21,7 @@ import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fro
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Streams;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.LanguageDependentFragment.LibraryLanguage;
import com.google.devtools.build.lib.analysis.OutputGroupProvider;
@@ -31,8 +32,10 @@ import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.Runfiles.Builder;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
+import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.ComputedSubstitution;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel;
import com.google.devtools.build.lib.packages.Attribute.LateBoundLabelList;
@@ -46,8 +49,10 @@ import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistry
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.vfs.PathFragment;
+import java.io.File;
import java.util.Collection;
import java.util.List;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
@@ -240,7 +245,34 @@ public interface JavaSemantics {
}
};
- String IJAR_LABEL = "//tools/defaults:ijar";
+ String JACOCO_METADATA_PLACEHOLDER = "%set_jacoco_metadata%";
+ String JACOCO_MAIN_CLASS_PLACEHOLDER = "%set_jacoco_main_class%";
+ String JACOCO_JAVA_RUNFILES_ROOT_PLACEHOLDER = "%set_jacoco_java_runfiles_root%";
+
+ /**
+ * Substitution for exporting the jars needed for jacoco coverage.
+ */
+ class ComputedJacocoSubstitution extends ComputedSubstitution {
+ private final NestedSet<Artifact> jars;
+ private final String pathPrefix;
+
+ public ComputedJacocoSubstitution(NestedSet<Artifact> jars, String workspacePrefix) {
+ super(JACOCO_METADATA_PLACEHOLDER);
+ this.jars = jars;
+ this.pathPrefix = "${JAVA_RUNFILES}/" + workspacePrefix;
+ }
+
+ /**
+ * Concatenating the root relative paths of the artifacts. Each relative path entry is prepended
+ * with "${JAVA_RUNFILES}" and the workspace prefix.
+ */
+ @Override
+ public String getValue() {
+ return Streams.stream(jars)
+ .map(artifact -> pathPrefix + "/" + artifact.getRootRelativePathString())
+ .collect(Collectors.joining(File.pathSeparator, "export JACOCO_METADATA_JARS=", ""));
+ }
+ }
/**
* Verifies if the rule contains any errors.
@@ -311,6 +343,8 @@ public interface JavaSemantics {
List<String> jvmFlags,
Artifact executable,
String javaStartClass,
+ String coverageStartClass,
+ NestedSetBuilder<Artifact> filesBuilder,
String javaExecutable);
/**
@@ -356,13 +390,7 @@ public interface JavaSemantics {
*
* @return new main class
*/
- String addCoverageSupport(
- JavaCompilationHelper helper,
- JavaTargetAttributes.Builder attributes,
- Artifact executable,
- Artifact instrumentationMetadata,
- JavaCompilationArtifacts.Builder javaArtifactsBuilder,
- String mainClass)
+ String addCoverageSupport(JavaCompilationHelper helper, Artifact executable)
throws InterruptedException;
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java
index 0f2ec192cd..5c9d2ca666 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaTargetAttributes.java
@@ -82,7 +82,6 @@ public class JavaTargetAttributes {
private final Map<PathFragment, Artifact> resources = new LinkedHashMap<>();
private final NestedSetBuilder<Artifact> resourceJars = NestedSetBuilder.stableOrder();
private final List<Artifact> messages = new ArrayList<>();
- private final List<Artifact> instrumentationMetadata = new ArrayList<>();
private final List<Artifact> sourceJars = new ArrayList<>();
private final List<Artifact> classPathResources = new ArrayList<>();
@@ -142,7 +141,6 @@ public class JavaTargetAttributes {
Preconditions.checkArgument(!built);
addCompileTimeClassPathEntries(context.getCompileTimeJars());
addRuntimeClassPathEntries(context.getRuntimeJars());
- addInstrumentationMetadataEntries(context.getInstrumentationMetadata());
return this;
}
@@ -256,12 +254,6 @@ public class JavaTargetAttributes {
return this;
}
- public Builder addInstrumentationMetadataEntries(Iterable<Artifact> metadataEntries) {
- Preconditions.checkArgument(!built);
- Iterables.addAll(instrumentationMetadata, metadataEntries);
- return this;
- }
-
public Builder addNativeLibrary(Artifact nativeLibrary) {
Preconditions.checkArgument(!built);
String name = nativeLibrary.getFilename();
@@ -408,12 +400,6 @@ public class JavaTargetAttributes {
return !sourceFiles.isEmpty();
}
- /** @deprecated prefer {@link JavaTargetAttributes#getInstrumentationMetadata} */
- @Deprecated
- public List<Artifact> getInstrumentationMetadata() {
- return instrumentationMetadata;
- }
-
/** @deprecated prefer {@link JavaTargetAttributes#hasSourceJars} */
@Deprecated
public boolean hasSourceJars() {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
index 1164d0316a..3cbc80c6ab 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
@@ -837,10 +837,6 @@ public class JavaSkylarkApiTest extends BuildViewTestCase {
args.getCompileTimeJars(), otherArgs.getCompileTimeJars())) {
return false;
}
- if (!nestedSetsOfArtifactHaveTheSameParent(
- args.getInstrumentationMetadata(), otherArgs.getInstrumentationMetadata())) {
- return false;
- }
if (!nestedSetsOfArtifactHaveTheSameParent(args.getRuntimeJars(), otherArgs.getRuntimeJars())) {
return false;
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/proto/SkylarkJavaLiteProtoLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/proto/SkylarkJavaLiteProtoLibraryTest.java
index 0622eebc05..ead884af2a 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/java/proto/SkylarkJavaLiteProtoLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/java/proto/SkylarkJavaLiteProtoLibraryTest.java
@@ -297,7 +297,6 @@ public class SkylarkJavaLiteProtoLibraryTest extends BuildViewTestCase {
" srcs = ['input1.proto', 'input2.proto'])");
JavaCompilationArgs compilationArgs =
getProvider(JavaCompilationArgsProvider.class, rule).getJavaCompilationArgs();
- assertThat(compilationArgs.getInstrumentationMetadata()).isEmpty();
JavaSourceJarsProvider sourceJarsProvider = getProvider(JavaSourceJarsProvider.class, rule);
assertThat(sourceJarsProvider).isNotNull();
diff --git a/src/test/shell/bazel/bazel_coverage_test.sh b/src/test/shell/bazel/bazel_coverage_test.sh
index c651f50580..41c996c625 100755
--- a/src/test/shell/bazel/bazel_coverage_test.sh
+++ b/src/test/shell/bazel/bazel_coverage_test.sh
@@ -144,7 +144,98 @@ EOF
[ -e $coverage_file_path ] || fail "Coverage output file does not exist!"
cat <<EOF > result.dat
-SF:com/example/Collatz.java
+SF:src/main/com/example/Collatz.java
+FN:3,com/example/Collatz::<init> ()V
+FNDA:0,com/example/Collatz::<init> ()V
+FN:6,com/example/Collatz::getCollatzFinal (I)I
+FNDA:1,com/example/Collatz::getCollatzFinal (I)I
+BA:6,2
+BA:6,2
+BA:9,2
+BA:9,2
+DA:3,0
+DA:6,3
+DA:7,2
+DA:9,4
+DA:10,5
+DA:12,7
+end_of_record
+EOF
+ if ! cmp result.dat $coverage_file_path; then
+ fail "Coverage output file is different than the expected file"
+ fi
+}
+
+function test_java_test_java_import_coverage() {
+
+ cat <<EOF > BUILD
+java_test(
+ name = "test",
+ srcs = glob(["src/test/**/*.java"]),
+ test_class = "com.example.TestCollatz",
+ deps = [":collatz-import"],
+)
+
+java_import(
+ name = "collatz-import",
+ jars = [":libcollatz-lib.jar"],
+)
+
+java_library(
+ name = "collatz-lib",
+ srcs = glob(["src/main/**/*.java"]),
+)
+EOF
+
+ mkdir -p src/main/com/example
+ cat <<EOF > src/main/com/example/Collatz.java
+package com.example;
+
+public class Collatz {
+
+ public static int getCollatzFinal(int n) {
+ if (n == 1) {
+ return 1;
+ }
+ if (n % 2 == 0) {
+ return getCollatzFinal(n / 2);
+ } else {
+ return getCollatzFinal(n * 3 + 1);
+ }
+ }
+
+}
+EOF
+
+ mkdir -p src/test/com/example
+ cat <<EOF > src/test/com/example/TestCollatz.java
+package com.example;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class TestCollatz {
+
+ @Test
+ public void testGetCollatzFinal() {
+ assertEquals(Collatz.getCollatzFinal(1), 1);
+ assertEquals(Collatz.getCollatzFinal(5), 1);
+ assertEquals(Collatz.getCollatzFinal(10), 1);
+ assertEquals(Collatz.getCollatzFinal(21), 1);
+ }
+
+}
+EOF
+
+ bazel coverage //:test &>$TEST_log || fail "Coverage for //:test failed"
+ cat $TEST_log
+ ending_part=$(sed -n -e '/PASSED/,$p' $TEST_log)
+
+ coverage_file_path=$(grep -Eo "/[/a-zA-Z0-9\.\_\-]+\.dat$" <<< "$ending_part")
+ [ -e $coverage_file_path ] || fail "Coverage output file not exists!"
+
+ cat <<EOF > result.dat
+SF:src/main/com/example/Collatz.java
FN:3,com/example/Collatz::<init> ()V
FNDA:0,com/example/Collatz::<init> ()V
FN:6,com/example/Collatz::getCollatzFinal (I)I
@@ -163,7 +254,7 @@ end_of_record
EOF
if ! cmp result.dat $coverage_file_path; then
- fail "Coverage output file is different with expected"
+ fail "Coverage output file is different than the expected file"
fi
}