aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/java_tools/buildjar
diff options
context:
space:
mode:
authorGravatar tomlu <tomlu@google.com>2018-02-13 11:06:45 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-02-13 11:08:35 -0800
commitf365d3f3451c3aac00990d7c5c9a2610d96cc2cd (patch)
tree171cd5c28e280e2f805890d13064e6fa7d010352 /src/java_tools/buildjar
parent49ecd1f37ae2abcfe5a68951fe6b118345509907 (diff)
Accept --target_label, --injecting_rule_kind in JavaBuilder and Turbine.
The values (if present) are written into the manifest with this format: Target-Label: <label> Injecting-Rule-Kind: <kind> In the future, JavaBuilder will make sure of this instead of command line arguments to find owners for jars for its add_dep commands. PiperOrigin-RevId: 185557317
Diffstat (limited to 'src/java_tools/buildjar')
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/JavaLibraryBuildRequest.java14
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/OptionsParser.java12
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/SimpleJavaLibraryBuilder.java1
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarCreator.java15
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarHelper.java8
-rw-r--r--src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java46
-rw-r--r--src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java57
7 files changed, 131 insertions, 22 deletions
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/JavaLibraryBuildRequest.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/JavaLibraryBuildRequest.java
index 2f7a6045aa..01ba5f1cd9 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/JavaLibraryBuildRequest.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/JavaLibraryBuildRequest.java
@@ -62,6 +62,8 @@ public final class JavaLibraryBuildRequest {
private final Path outputJar;
private final Path nativeHeaderOutput;
+ @Nullable private final String targetLabel;
+ @Nullable private final String injectingRuleKind;
private final Path classDir;
private final Path tempDir;
@@ -183,6 +185,8 @@ public final class JavaLibraryBuildRequest {
this.sourceGenDir = asPath(optionsParser.getSourceGenDir());
this.generatedSourcesOutputJar = asPath(optionsParser.getGeneratedSourcesOutputJar());
this.generatedClassOutputJar = asPath(optionsParser.getManifestProtoPath());
+ this.targetLabel = optionsParser.getTargetLabel();
+ this.injectingRuleKind = optionsParser.getInjectingRuleKind();
}
private static ImmutableList<Path> asPaths(Collection<String> paths) {
@@ -288,6 +292,16 @@ public final class JavaLibraryBuildRequest {
return plugins;
}
+ @Nullable
+ public String getTargetLabel() {
+ return targetLabel;
+ }
+
+ @Nullable
+ public String getInjectingRuleKind() {
+ return injectingRuleKind;
+ }
+
public BlazeJavacArguments toBlazeJavacArguments(ImmutableList<Path> classPath) {
BlazeJavacArguments.Builder builder =
BlazeJavacArguments.builder()
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/OptionsParser.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/OptionsParser.java
index f2cdeea4ee..5413e5312d 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/OptionsParser.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/OptionsParser.java
@@ -83,7 +83,8 @@ public final class OptionsParser {
private String ruleKind;
private String targetLabel;
-
+ private String injectingRuleKind;
+
private boolean testOnly;
/**
@@ -219,6 +220,9 @@ public final class OptionsParser {
case "--target_label":
targetLabel = getArgument(argQueue, arg);
break;
+ case "--injecting_rule_kind":
+ injectingRuleKind = getArgument(argQueue, arg);
+ break;
case "--testonly":
testOnly = true;
break;
@@ -524,7 +528,11 @@ public final class OptionsParser {
public String getTargetLabel() {
return targetLabel;
}
-
+
+ public String getInjectingRuleKind() {
+ return injectingRuleKind;
+ }
+
public boolean testOnly() {
return testOnly;
}
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/SimpleJavaLibraryBuilder.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/SimpleJavaLibraryBuilder.java
index d5dd08688d..50c936ac43 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/SimpleJavaLibraryBuilder.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/SimpleJavaLibraryBuilder.java
@@ -152,6 +152,7 @@ public class SimpleJavaLibraryBuilder implements Closeable {
jar.setNormalize(true);
jar.setCompression(build.compressJar());
jar.addDirectory(build.getClassDir());
+ jar.setJarOwner(build.getTargetLabel(), build.getInjectingRuleKind());
JacocoInstrumentationProcessor processor = build.getJacocoInstrumentationProcessor();
if (processor != null) {
processor.processRequest(build, processor.isNewCoverageImplementation() ? jar : null);
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarCreator.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarCreator.java
index bb8be68004..b0bcb2bb48 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarCreator.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarCreator.java
@@ -45,6 +45,8 @@ public class JarCreator extends JarHelper {
private final TreeMap<String, Path> jarEntries = new TreeMap<>();
private String manifestFile;
private String mainClass;
+ private String targetLabel;
+ private String injectingRuleKind;
/** @deprecated use {@link JarCreator(Path)} instead */
@Deprecated
@@ -182,6 +184,11 @@ public class JarCreator extends JarHelper {
this.mainClass = mainClass;
}
+ public void setJarOwner(String targetLabel, String injectingRuleKind) {
+ this.targetLabel = targetLabel;
+ this.injectingRuleKind = injectingRuleKind;
+ }
+
/**
* Sets filename for the manifest content. If this is set the manifest will be read from this file
* otherwise the manifest content will get generated on the fly.
@@ -207,11 +214,17 @@ public class JarCreator extends JarHelper {
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
Attributes.Name createdBy = new Attributes.Name("Created-By");
if (attributes.getValue(createdBy) == null) {
- attributes.put(createdBy, "blaze");
+ attributes.put(createdBy, "bazel");
}
if (mainClass != null) {
attributes.put(Attributes.Name.MAIN_CLASS, mainClass);
}
+ if (targetLabel != null) {
+ attributes.put(JarHelper.TARGET_LABEL, targetLabel);
+ }
+ if (injectingRuleKind != null) {
+ attributes.put(JarHelper.INJECTING_RULE_KIND, injectingRuleKind);
+ }
ByteArrayOutputStream out = new ByteArrayOutputStream();
manifest.write(out);
return out.toByteArray();
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarHelper.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarHelper.java
index 719fcdbee5..2860fa4965 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarHelper.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/jarhelper/JarHelper.java
@@ -22,6 +22,7 @@ import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashSet;
import java.util.Set;
+import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@@ -46,6 +47,13 @@ public class JarHelper {
.atZone(ZoneId.systemDefault())
.toInstant()
.toEpochMilli();
+ // These attributes are used by JavaBuilder, Turbine, and ijar.
+ // They must all be kept in sync.
+ public static final Attributes.Name TARGET_LABEL = new Attributes.Name("Target-Label");
+ public static final Attributes.Name INJECTING_RULE_KIND =
+ new Attributes.Name("Injecting-Rule-Kind");
+
+ public static final long DOS_EPOCH_IN_JAVA_TIME = 315561600000L;
// ZIP timestamps have a resolution of 2 seconds.
// see http://www.info-zip.org/FAQ.html#limits
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java
index 876e9c0309..99c195d55b 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/JavacTurbine.java
@@ -32,6 +32,7 @@ import com.google.turbine.options.TurbineOptionsParser;
import com.sun.tools.javac.util.Context;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@@ -47,6 +48,9 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
import java.util.regex.Pattern;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassReader;
@@ -64,6 +68,13 @@ import org.objectweb.asm.Opcodes;
*/
public class JavacTurbine implements AutoCloseable {
+ // These attributes are used by JavaBuilder, Turbine, and ijar.
+ // They must all be kept in sync.
+ static final String MANIFEST_DIR = "META-INF/";
+ static final String MANIFEST_NAME = JarFile.MANIFEST_NAME;
+ static final Attributes.Name TARGET_LABEL = new Attributes.Name("Target-Label");
+ static final Attributes.Name INJECTING_RULE_KIND = new Attributes.Name("Injecting-Rule-Kind");
+
public static void main(String[] args) throws IOException {
System.exit(compile(TurbineOptionsParser.parse(Arrays.asList(args))).exitCode());
}
@@ -192,9 +203,7 @@ public class JavacTurbine implements AutoCloseable {
if (sources.isEmpty()) {
// accept compilations with an empty source list for compatibility with JavaBuilder
emitClassJar(
- Paths.get(turbineOptions.outputFile()),
- /* files= */ ImmutableMap.of(),
- /* transitive= */ ImmutableMap.of());
+ turbineOptions, /* files= */ ImmutableMap.of(), /* transitive= */ ImmutableMap.of());
dependencyModule.emitDependencyInformation(
/*classpath=*/ ImmutableList.of(), /*successful=*/ true);
return Result.OK_WITH_REDUCED_CLASSPATH;
@@ -238,9 +247,7 @@ public class JavacTurbine implements AutoCloseable {
if (result.ok()) {
emitClassJar(
- Paths.get(turbineOptions.outputFile()),
- compileResult.files(),
- transitive.collectTransitiveDependencies());
+ turbineOptions, compileResult.files(), transitive.collectTransitiveDependencies());
dependencyModule.emitDependencyInformation(actualClasspath, compileResult.success());
} else {
out.print(compileResult.output());
@@ -292,8 +299,9 @@ public class JavacTurbine implements AutoCloseable {
/** Write the class output from a successful compilation to the output jar. */
private static void emitClassJar(
- Path outputJar, Map<String, byte[]> files, Map<String, byte[]> transitive)
+ TurbineOptions turbineOptions, Map<String, byte[]> files, Map<String, byte[]> transitive)
throws IOException {
+ Path outputJar = Paths.get(turbineOptions.outputFile());
try (OutputStream fos = Files.newOutputStream(outputJar);
ZipOutputStream zipOut =
new ZipOutputStream(new BufferedOutputStream(fos, ZIPFILE_BUFFER_SIZE))) {
@@ -313,7 +321,31 @@ public class JavacTurbine implements AutoCloseable {
}
ZipUtil.storeEntry(name, bytes, zipOut);
}
+
+ if (turbineOptions.targetLabel().isPresent()) {
+ ZipUtil.storeEntry(MANIFEST_DIR, new byte[] {}, zipOut);
+ ZipUtil.storeEntry(MANIFEST_NAME, manifestContent(turbineOptions), zipOut);
+ }
+ }
+ }
+
+ private static byte[] manifestContent(TurbineOptions turbineOptions) throws IOException {
+ Manifest manifest = new Manifest();
+ Attributes attributes = manifest.getMainAttributes();
+ attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+ Attributes.Name createdBy = new Attributes.Name("Created-By");
+ if (attributes.getValue(createdBy) == null) {
+ attributes.put(createdBy, "bazel");
+ }
+ if (turbineOptions.targetLabel().isPresent()) {
+ attributes.put(TARGET_LABEL, turbineOptions.targetLabel().get());
+ }
+ if (turbineOptions.injectingRuleKind().isPresent()) {
+ attributes.put(INJECTING_RULE_KIND, turbineOptions.injectingRuleKind().get());
}
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ manifest.write(out);
+ return out.toByteArray();
}
/**
diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java
index 5849eb851e..d6159d96f5 100644
--- a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java
+++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.java.turbine.javac;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.stream.Collectors.toSet;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
@@ -53,6 +54,8 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
@@ -61,9 +64,11 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
@@ -105,7 +110,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).containsExactly("Hello.class");
+ assertThat(filterManifestEntries(outputs.keySet())).containsExactly("Hello.class");
String text = textify(outputs.get("Hello.class"));
String[] expected = {
@@ -136,7 +141,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).containsExactly("Hello.class");
+ assertThat(filterManifestEntries(outputs.keySet())).containsExactly("Hello.class");
String text = textify(outputs.get("Hello.class"));
String[] expected = {
@@ -228,7 +233,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
compile();
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet())
+ assertThat(filterManifestEntries(outputs.keySet()))
.containsExactly(
"Generated.class", "MyAnnotation.class", "Hello.class", "com/foo/hello.txt");
@@ -629,7 +634,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).containsExactly("Const.class");
+ assertThat(filterManifestEntries(outputs.keySet())).containsExactly("Const.class");
String text = textify(outputs.get("Const.class"));
String[] expected = {
@@ -678,7 +683,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
compile();
Map<String, byte[]> outputs = collectOutputs();
// just don't crash; enum constants need to be preserved
- assertThat(outputs.keySet()).containsExactly("TheEnum.class");
+ assertThat(filterManifestEntries(outputs.keySet())).containsExactly("TheEnum.class");
String text = textify(outputs.get("TheEnum.class"));
String[] expected = {
@@ -790,7 +795,8 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).containsExactly("Super.class", "Hello.class");
+ assertThat(filterManifestEntries(outputs.keySet()))
+ .containsExactly("Super.class", "Hello.class");
String text = textify(outputs.get("Hello.class"));
String[] expected = {
@@ -825,7 +831,8 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).containsExactly("Anno.class", "Hello.class");
+ assertThat(filterManifestEntries(outputs.keySet()))
+ .containsExactly("Anno.class", "Hello.class");
String text = textify(outputs.get("Hello.class"));
String[] expected = {
@@ -880,7 +887,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).containsExactly("Hello.class");
+ assertThat(filterManifestEntries(outputs.keySet())).containsExactly("Hello.class");
String text = textify(outputs.get("Hello.class"));
String[] expected = {
@@ -953,7 +960,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
// don't set up any source files
compile();
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).isEmpty();
+ assertThat(filterManifestEntries(outputs.keySet())).isEmpty();
}
/** An annotation processor that violates the contract. */
@@ -1067,7 +1074,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
compile();
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).containsExactly("Hello.class");
+ assertThat(filterManifestEntries(outputs.keySet())).containsExactly("Hello.class");
}
public static class Lib {}
@@ -1115,7 +1122,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).containsExactly("Hello.class");
+ assertThat(filterManifestEntries(outputs.keySet())).containsExactly("Hello.class");
String text = textify(outputs.get("Hello.class"));
String[] expected = {
@@ -1148,7 +1155,7 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
Map<String, byte[]> outputs = collectOutputs();
- assertThat(outputs.keySet()).containsExactly("Bridge.class");
+ assertThat(filterManifestEntries(outputs.keySet())).containsExactly("Bridge.class");
String text = textify(outputs.get("Bridge.class"));
String[] expected = {
@@ -1326,5 +1333,31 @@ public class JavacTurbineTest extends AbstractJavacTurbineCompilationTest {
assertThat(javacopts).contains("--release");
assertThat(javacopts).containsNoneOf("-source", "-target");
}
+
+ @Test
+ public void testManifestEntries() throws Exception {
+ optionsBuilder.setTargetLabel("//foo:foo");
+ optionsBuilder.setInjectingRuleKind("foo_library");
+ compile();
+ try (JarFile jarFile = new JarFile(output.toFile())) {
+ Manifest manifest = jarFile.getManifest();
+ Attributes attributes = manifest.getMainAttributes();
+ assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo");
+ assertThat(attributes.getValue("Injecting-Rule-Kind")).isEqualTo("foo_library");
+ assertThat(jarFile.getEntry(JarFile.MANIFEST_NAME).getLastModifiedTime().toInstant())
+ .isEqualTo(
+ LocalDateTime.of(2010, 1, 1, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant());
+ }
+ }
+
+ private static Set<String> filterManifestEntries(Set<String> entries) {
+ return entries
+ .stream()
+ .filter(
+ name ->
+ !(name.equals(JavacTurbine.MANIFEST_DIR)
+ || name.equals(JavacTurbine.MANIFEST_NAME)))
+ .collect(toSet());
+ }
}