Allow some duplicates in merged jars

Only take the first MANIFEST.MF or module-info.class file.

Test: m -j checkbuild
Change-Id: Ifbf9fe272437ef2c2bd51ab4849ac8d7ef37b6fc
diff --git a/cmd/merge_zips/merge_zips.go b/cmd/merge_zips/merge_zips.go
index e178036..7874a41 100644
--- a/cmd/merge_zips/merge_zips.go
+++ b/cmd/merge_zips/merge_zips.go
@@ -28,7 +28,7 @@
 
 var (
 	sortEntries = flag.Bool("s", false, "sort entries (defaults to the order from the input zip files)")
-	sortJava    = flag.Bool("j", false, "sort zip entries using jar ordering (META-INF first)")
+	emulateJar  = flag.Bool("j", false, "sort zip entries using jar ordering (META-INF first)")
 )
 
 func main() {
@@ -76,7 +76,7 @@
 	}
 
 	// do merge
-	if err := mergeZips(readers, writer, *sortEntries, *sortJava); err != nil {
+	if err := mergeZips(readers, writer, *sortEntries, *emulateJar); err != nil {
 		log.Fatal(err)
 	}
 }
@@ -109,7 +109,7 @@
 	dest   string
 }
 
-func mergeZips(readers []namedZipReader, writer *zip.Writer, sortEntries bool, sortJava bool) error {
+func mergeZips(readers []namedZipReader, writer *zip.Writer, sortEntries bool, emulateJar bool) error {
 
 	mappingsByDest := make(map[string]fileMapping, 0)
 	orderedMappings := []fileMapping{}
@@ -128,24 +128,33 @@
 			source := zipEntry{path: zipEntryPath{zipName: namedReader.path, entryName: file.Name}, content: file}
 			newMapping := fileMapping{source: source, dest: dest}
 
-			// handle duplicates
 			if exists {
+				// handle duplicates
 				wasDir := existingMapping.source.content.FileHeader.FileInfo().IsDir()
 				isDir := newMapping.source.content.FileHeader.FileInfo().IsDir()
-				if !wasDir || !isDir {
+				if wasDir != isDir {
+					return fmt.Errorf("Directory/file mismatch at %v from %v and %v\n",
+						dest, existingMapping.source.path, newMapping.source.path)
+				}
+				if emulateJar &&
+					file.Name == jar.ManifestFile || file.Name == jar.ModuleInfoClass {
+					// Skip manifest and module info files that are not from the first input file
+					continue
+				}
+				if !isDir {
 					return fmt.Errorf("Duplicate path %v found in %v and %v\n",
 						dest, existingMapping.source.path, newMapping.source.path)
 				}
+			} else {
+				// save entry
+				mappingsByDest[mapKey] = newMapping
+				orderedMappings = append(orderedMappings, newMapping)
 			}
-
-			// save entry
-			mappingsByDest[mapKey] = newMapping
-			orderedMappings = append(orderedMappings, newMapping)
 		}
 
 	}
 
-	if sortJava {
+	if emulateJar {
 		jarSort(orderedMappings)
 	} else if sortEntries {
 		alphanumericSort(orderedMappings)
diff --git a/cmd/soong_zip/soong_zip.go b/cmd/soong_zip/soong_zip.go
index ae176df..4cf0764 100644
--- a/cmd/soong_zip/soong_zip.go
+++ b/cmd/soong_zip/soong_zip.go
@@ -62,9 +62,6 @@
 	io.Closer
 }
 
-// the file path in the zip at which a Java manifest file gets written
-const manifestDest = "META-INF/MANIFEST.MF"
-
 type fileArg struct {
 	pathPrefixInZip, sourcePrefixToStrip string
 	sourceFiles                          []string
@@ -360,7 +357,7 @@
 		if !*emulateJar {
 			return errors.New("must specify --jar when specifying a manifest via -m")
 		}
-		pathMappings = append(pathMappings, pathMapping{manifestDest, manifest, zip.Deflate})
+		pathMappings = append(pathMappings, pathMapping{jar.ManifestFile, manifest, zip.Deflate})
 	}
 
 	if *emulateJar {
@@ -372,7 +369,7 @@
 		defer close(z.writeOps)
 
 		for _, ele := range pathMappings {
-			if *emulateJar && ele.dest == manifestDest {
+			if *emulateJar && ele.dest == jar.ManifestFile {
 				err = z.addManifest(ele.dest, ele.src, ele.zipMethod)
 			} else {
 				err = z.addFile(ele.dest, ele.src, ele.zipMethod)