Include module-info.class files in interface jars

instead of removing them, since builds that use modules need them to be
visible across compilation boundaries. Note that the module-infos don't
contain any implementation that needs to be removed, so ijar just copies
the entire file through.

PiperOrigin-RevId: 184562080
diff --git a/third_party/ijar/ijar.cc b/third_party/ijar/ijar.cc
index df97969..144120e 100644
--- a/third_party/ijar/ijar.cc
+++ b/third_party/ijar/ijar.cc
@@ -68,17 +68,17 @@
              CLASS_EXTENSION) != 0) {
     return false;
   }
-  // skip module-info.class files, which don't need stripping
+  return true;
+}
+
+static bool IsModuleInfo(const char* filename) {
   const char* slash = strrchr(filename, '/');
   if (slash == NULL) {
     slash = filename;
   } else {
     slash++;
   }
-  if (strcmp(slash, "module-info.class") == 0) {
-    return false;
-  }
-  return true;
+  return strcmp(slash, "module-info.class") == 0;
 }
 
 void JarStripperProcessor::Process(const char* filename, const u4 attr,
@@ -86,17 +86,23 @@
   if (verbose) {
     fprintf(stderr, "INFO: StripClass: %s\n", filename);
   }
-  u1* buf = reinterpret_cast<u1*>(malloc(size));
-  u1* classdata_out = buf;
-  if (!StripClass(buf, data, size)) {
+  if (IsModuleInfo(filename)) {
+    u1* q = builder->NewFile(filename, 0);
+    memcpy(q, data, size);
+    builder->FinishFile(size, false, true);
+  } else {
+    u1* buf = reinterpret_cast<u1*>(malloc(size));
+    u1* classdata_out = buf;
+    if (!StripClass(buf, data, size)) {
+      free(classdata_out);
+      return;
+    }
+    u1* q = builder->NewFile(filename, 0);
+    size_t out_length = buf - classdata_out;
+    memcpy(q, classdata_out, out_length);
+    builder->FinishFile(out_length, false, true);
     free(classdata_out);
-    return;
   }
-  u1* q = builder->NewFile(filename, 0);
-  size_t out_length = buf - classdata_out;
-  memcpy(q, classdata_out, out_length);
-  builder->FinishFile(out_length, false, true);
-  free(classdata_out);
 }
 
 // Opens "file_in" (a .jar file) for reading, and writes an interface
diff --git a/third_party/ijar/test/IjarTests.java b/third_party/ijar/test/IjarTests.java
index d9a3897..4e0fb5d 100644
--- a/third_party/ijar/test/IjarTests.java
+++ b/third_party/ijar/test/IjarTests.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 import static com.google.common.truth.Truth.assertThat;
+import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.fail;
@@ -20,14 +21,6 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.io.ByteStreams;
 import com.google.devtools.build.java.bazel.BazelJavaCompiler;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Opcodes;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
@@ -41,7 +34,6 @@
 import java.util.jar.JarFile;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
-
 import javax.annotation.processing.AbstractProcessor;
 import javax.annotation.processing.RoundEnvironment;
 import javax.lang.model.element.TypeElement;
@@ -51,6 +43,12 @@
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
 import javax.tools.StandardLocation;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
 
 /**
  * JUnit tests for ijar tool.
@@ -270,6 +268,10 @@
   @Test
   public void moduleInfo() throws Exception {
     Map<String, byte[]> lib = readJar("third_party/ijar/test/module_info-interface.jar");
-    assertThat(lib.keySet()).containsExactly("java/lang/String.class");
+    assertThat(lib.keySet())
+        .containsExactly("java/lang/String.class", "module-info.class", "foo/module-info.class");
+    // ijar passes module-infos through unmodified, so it doesn't care that these ones are bogus
+    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");
   }
 }