write dex archives uncompressed RELNOTES: none PiperOrigin-RevId: 164620306
diff --git a/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java b/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java index 2c27f4b..5f1bb82 100644 --- a/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java +++ b/src/test/java/com/google/devtools/build/android/dexer/DexConversionEnqueuerTest.java
@@ -141,11 +141,12 @@ stuffer.call(); Future<ZipEntryContent> f = stuffer.getFiles().remove(); assertThat(f.isDone()).isTrue(); + byte[] dexcode = f.get().getContent(); assertThat(f.get().getEntry().getName()).isEqualTo(filename + ".dex"); assertThat(f.get().getEntry().getTime()).isEqualTo(FILE_TIME); - assertThat(f.get().getEntry().getSize()).isEqualTo(-1); - assertThat(f.get().getEntry().getCompressedSize()).isEqualTo(-1); - byte[] dexcode = f.get().getContent(); + assertThat(f.get().getEntry().getSize()).isEqualTo(dexcode.length); + assertThat(f.get().getEntry().getCompressedSize()).isEqualTo(dexcode.length); + Dex dex = new Dex(dexcode); assertThat(dex.classDefs()).hasSize(1); assertThat(cache.getIfPresent(DexingKey.create(false, false, bytecode))).isSameAs(dexcode);
diff --git a/src/tools/android/java/com/google/devtools/build/android/dexer/DexConversionEnqueuer.java b/src/tools/android/java/com/google/devtools/build/android/dexer/DexConversionEnqueuer.java index b66e725..9e94b47 100644 --- a/src/tools/android/java/com/google/devtools/build/android/dexer/DexConversionEnqueuer.java +++ b/src/tools/android/java/com/google/devtools/build/android/dexer/DexConversionEnqueuer.java
@@ -28,6 +28,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; +import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.annotation.Nullable; @@ -108,7 +109,7 @@ private Future<ZipEntryContent> toDex(ZipEntry entry, byte[] content) { byte[] cached = dexCache != null ? dexCache.getIfPresent(dexer.getDexingKey(content)) : null; return cached != null - ? immediateFuture(newDexEntry(entry, cached)) + ? immediateFuture(storedDexEntry(entry, cached)) : executor.submit(new ClassToDex(entry, content, dexer, dexCache)); } @@ -126,13 +127,25 @@ return files; } - private static ZipEntryContent newDexEntry(ZipEntry classfile, byte[] dexed) { - return new ZipEntryContent(withFileName(classfile, classfile.getName() + ".dex"), dexed); + private static ZipEntryContent storedDexEntry(ZipEntry classfile, byte[] dexed) { + return new ZipEntryContent( + storedEntry(classfile.getName() + ".dex", classfile.getTime(), dexed), + dexed); } - private static ZipEntry withFileName(ZipEntry orig, String filename) { + private static ZipEntry storedEntry(String filename, long time, byte[] content) { + // Need to pre-compute checksum for STORED (uncompressed) entries) + CRC32 checksum = new CRC32(); + checksum.update(content); + ZipEntry result = new ZipEntry(filename); - result.setTime(orig.getTime()); + result.setTime(time); + result.setCrc(checksum.getValue()); + result.setSize(content.length); + result.setCompressedSize(content.length); + // Write uncompressed, since this is just an intermediary artifact that + // we will convert to .dex + result.setMethod(ZipEntry.STORED); return result; } @@ -162,7 +175,7 @@ dexCache.put(dexer.getDexingKey(content), dexed); } // Use .class.dex suffix expected by SplitZip - return newDexEntry(entry, dexed); + return storedDexEntry(entry, dexed); } } }