aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/ijar
diff options
context:
space:
mode:
authorGravatar tomlu <tomlu@google.com>2018-02-09 10:32:40 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-02-09 10:34:20 -0800
commit8a56b164facce7844718a0c80554f6c11ba155f2 (patch)
tree0c977e9834d2d67f257dc8db4600ada757bd285f /third_party/ijar
parentad32f62952e2b6f8293a26ea5fd677e61975c9ff (diff)
Accept --target_label, --injecting_rule_kind in ijar.
This is a rollforward with fixes. 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: 185159950
Diffstat (limited to 'third_party/ijar')
-rw-r--r--third_party/ijar/ijar.cc62
-rw-r--r--third_party/ijar/test/BUILD8
-rw-r--r--third_party/ijar/test/IjarTests.java18
3 files changed, 84 insertions, 4 deletions
diff --git a/third_party/ijar/ijar.cc b/third_party/ijar/ijar.cc
index 144120ebf3..d7742ee1ac 100644
--- a/third_party/ijar/ijar.cc
+++ b/third_party/ijar/ijar.cc
@@ -36,6 +36,14 @@ bool StripClass(u1*& classdata_out, const u1* classdata_in, size_t in_length);
const char* CLASS_EXTENSION = ".class";
const size_t CLASS_EXTENSION_LENGTH = strlen(CLASS_EXTENSION);
+const char *MANIFEST_HEADER =
+ "Manifest-Version: 1.0\n"
+ "Created-By: bazel\n";
+// These attributes are used by JavaBuilder, Turbine, and ijar.
+// They must all be kept in sync.
+const char *TARGET_LABEL_KEY = "Target-Label: ";
+const char *INJECTING_RULE_KIND_KEY = "Injecting-Rule-Kind: ";
+
// ZipExtractorProcessor that select only .class file and use
// StripClass to generate an interface class, storing as a new file
// in the specified ZipBuilder.
@@ -105,9 +113,39 @@ void JarStripperProcessor::Process(const char* filename, const u4 attr,
}
}
+// Copies the string into the buffer without the null terminator, returns length
+static size_t WriteStr(u1 *buf, const char *str) {
+ size_t len = strlen(str);
+ memcpy(buf, str, len);
+ return len;
+}
+
+static void WriteManifest(ZipBuilder *out, const char *target_label,
+ const char *injecting_rule_kind) {
+ if (target_label == NULL) {
+ return;
+ }
+ out->WriteEmptyFile("META-INF/");
+ u1 *start = out->NewFile("META-INF/MANIFEST.MF", 0);
+ u1 *buf = start;
+ buf += WriteStr(buf, MANIFEST_HEADER);
+ buf += WriteStr(buf, TARGET_LABEL_KEY);
+ buf += WriteStr(buf, target_label);
+ *buf++ = '\n';
+ if (injecting_rule_kind) {
+ buf += WriteStr(buf, INJECTING_RULE_KIND_KEY);
+ buf += WriteStr(buf, injecting_rule_kind);
+ *buf++ = '\n';
+ }
+ size_t total_len = buf - start;
+ out->FinishFile(total_len);
+}
+
// Opens "file_in" (a .jar file) for reading, and writes an interface
// .jar to "file_out".
-void OpenFilesAndProcessJar(const char *file_out, const char *file_in) {
+static void OpenFilesAndProcessJar(const char *file_out, const char *file_in,
+ const char *target_label,
+ const char *injecting_rule_kind) {
JarStripperProcessor processor;
std::unique_ptr<ZipExtractor> in(ZipExtractor::Create(file_in, &processor));
if (in.get() == NULL) {
@@ -129,6 +167,7 @@ void OpenFilesAndProcessJar(const char *file_out, const char *file_in) {
fprintf(stderr, "%s\n", in->GetError());
abort();
}
+ WriteManifest(out.get(), target_label, injecting_rule_kind);
// Add dummy file, since javac doesn't like truly empty jars.
if (out->GetNumberFiles() == 0) {
@@ -148,25 +187,39 @@ void OpenFilesAndProcessJar(const char *file_out, const char *file_in) {
static_cast<int>(100.0 * out_length / in_length));
}
}
-
} // namespace devtools_ijar
//
// main method
//
static void usage() {
- fprintf(stderr, "Usage: ijar [-v] x.jar [x_interface.jar>]\n");
+ fprintf(stderr,
+ "Usage: ijar "
+ "[-v] [--target label label] [--injecting_rule_kind kind] "
+ "x.jar [x_interface.jar>]\n");
fprintf(stderr, "Creates an interface jar from the specified jar file.\n");
exit(1);
}
int main(int argc, char **argv) {
+ const char *target_label = NULL;
+ const char *injecting_rule_kind = NULL;
const char *filename_in = NULL;
const char *filename_out = NULL;
for (int ii = 1; ii < argc; ++ii) {
if (strcmp(argv[ii], "-v") == 0) {
devtools_ijar::verbose = true;
+ } else if (strcmp(argv[ii], "--target_label") == 0) {
+ if (++ii >= argc) {
+ usage();
+ }
+ target_label = argv[ii];
+ } else if (strcmp(argv[ii], "--injecting_rule_kind") == 0) {
+ if (++ii >= argc) {
+ usage();
+ }
+ injecting_rule_kind = argv[ii];
} else if (filename_in == NULL) {
filename_in = argv[ii];
} else if (filename_out == NULL) {
@@ -199,6 +252,7 @@ int main(int argc, char **argv) {
fprintf(stderr, "INFO: writing to '%s'.\n", filename_out);
}
- devtools_ijar::OpenFilesAndProcessJar(filename_out, filename_in);
+ devtools_ijar::OpenFilesAndProcessJar(filename_out, filename_in, target_label,
+ injecting_rule_kind);
return 0;
}
diff --git a/third_party/ijar/test/BUILD b/third_party/ijar/test/BUILD
index 455ab29608..6b4eeb908e 100644
--- a/third_party/ijar/test/BUILD
+++ b/third_party/ijar/test/BUILD
@@ -101,6 +101,14 @@ genrule(
tools = ["//third_party/ijar"],
)
+genrule(
+ name = "interface_ijar_testlib_with_target_label",
+ srcs = [":ijar_testlib"],
+ outs = ["interface_ijar_testlib_with_target_label.jar"],
+ cmd = "$(location //third_party/ijar) --target_label //foo:foo --injecting_rule_kind foo_library $< $@",
+ tools = ["//third_party/ijar"],
+)
+
java_library(
name = "typeannotations2",
srcs = glob(["typeannotations2/**/*.java"]),
diff --git a/third_party/ijar/test/IjarTests.java b/third_party/ijar/test/IjarTests.java
index 4e0fb5d839..467680552b 100644
--- a/third_party/ijar/test/IjarTests.java
+++ b/third_party/ijar/test/IjarTests.java
@@ -23,15 +23,19 @@ import com.google.common.io.ByteStreams;
import com.google.devtools.build.java.bazel.BazelJavaCompiler;
import java.io.File;
import java.io.IOException;
+import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
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.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.annotation.processing.AbstractProcessor;
@@ -274,4 +278,18 @@ public class IjarTests {
assertThat(new String(lib.get("module-info.class"), UTF_8)).isEqualTo("hello");
assertThat(new String(lib.get("foo/module-info.class"), UTF_8)).isEqualTo("goodbye");
}
+
+ @Test
+ public void testTargetLabel() throws Exception {
+ try (JarFile jf =
+ new JarFile("third_party/ijar/test/interface_ijar_testlib_with_target_label.jar")) {
+ Manifest manifest = jf.getManifest();
+ Attributes attributes = manifest.getMainAttributes();
+ assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo");
+ assertThat(attributes.getValue("Injecting-Rule-Kind")).isEqualTo("foo_library");
+ assertThat(jf.getEntry(JarFile.MANIFEST_NAME).getLastModifiedTime().toInstant())
+ .isEqualTo(
+ Instant.ofEpochMilli(new GregorianCalendar(1980, 0, 1, 0, 0, 0).getTimeInMillis()));
+ }
+ }
}