diff options
author | Ivan Gavrilovic <gavra@google.com> | 2017-03-22 17:47:16 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-03-22 17:47:16 +0000 |
commit | e4ecc9ff1d3ce159645db761747a5c1dda54ad24 (patch) | |
tree | fad6892fc54a1e03fc896f8d67503e8ac41cc377 | |
parent | f9dd52a4ebed02d3a4dace355ba7c34b7664ef47 (diff) | |
parent | eebf335a7f3bcf53a3f2cf9437eaabdf40c3aefe (diff) | |
download | dalvik-e4ecc9ff1d3ce159645db761747a5c1dda54ad24.tar.gz |
Merge "Dex merger handles empty sections"
am: eebf335a7f
Change-Id: I29915084793481443cec1c7fd5eeeee3223f7762
-rw-r--r-- | dx/junit-tests/com/android/dx/merge/DexMergerTest.java | 93 | ||||
-rw-r--r-- | dx/src/com/android/dx/merge/DexMerger.java | 13 |
2 files changed, 106 insertions, 0 deletions
diff --git a/dx/junit-tests/com/android/dx/merge/DexMergerTest.java b/dx/junit-tests/com/android/dx/merge/DexMergerTest.java new file mode 100644 index 000000000..b9f03929b --- /dev/null +++ b/dx/junit-tests/com/android/dx/merge/DexMergerTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dx.merge; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import com.android.dex.Dex; +import com.android.dx.command.Main; +import com.android.dx.command.dexer.DxContext; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class DexMergerTest { + static class NoFieldsClassA { + } + static class NoFieldsClassB { + } + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void test_merge_dexesWithEmptyFieldsSection() throws IOException { + List<Dex> outputDexes = new ArrayList<>(); + outputDexes.add(getDexForClass(NoFieldsClassA.class)); + outputDexes.add(getDexForClass(NoFieldsClassB.class)); + + Dex merged = + new DexMerger( + outputDexes.toArray(new Dex[outputDexes.size()]), + CollisionPolicy.FAIL, + new DxContext()) + .merge(); + assertNotNull(merged); + assertNotNull(merged.getTableOfContents()); + assertEquals(0, merged.getTableOfContents().fieldIds.off); + } + + private Dex getDexForClass(Class<?> clazz) throws IOException { + String path = clazz.getName().replace('.', '/') + ".class"; + Path classesJar = temporaryFolder.newFile(clazz.getName() + ".jar").toPath(); + try (InputStream in = getClass().getClassLoader().getResourceAsStream(path); + ZipOutputStream zip = new ZipOutputStream(Files.newOutputStream(classesJar))) { + + ZipEntry entry = new ZipEntry(path); + zip.putNextEntry(entry); + zip.write(readEntireStream(in)); + zip.closeEntry(); + } + + Path output = temporaryFolder.newFolder().toPath(); + Main.main(new String[]{"--dex", "--output=" + output.toString(), classesJar.toString()}); + + return new Dex(Files.readAllBytes(output.resolve("classes.dex"))); + } + + private static byte[] readEntireStream(InputStream inputStream) throws IOException { + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + byte[] buffer = new byte[8192]; + + int count; + while ((count = inputStream.read(buffer)) != -1) { + bytesOut.write(buffer, 0, count); + } + + return bytesOut.toByteArray(); + } +} diff --git a/dx/src/com/android/dx/merge/DexMerger.java b/dx/src/com/android/dx/merge/DexMerger.java index 470d8fb22..81ad2ddb7 100644 --- a/dx/src/com/android/dx/merge/DexMerger.java +++ b/dx/src/com/android/dx/merge/DexMerger.java @@ -166,6 +166,9 @@ public final class DexMerger { unionAnnotationSetsAndDirectories(); mergeClassDefs(); + // computeSizesFromOffsets expects sections sorted by offset, so make it so + Arrays.sort(contentsOut.sections); + // write the header contentsOut.header.off = 0; contentsOut.header.size = 1; @@ -255,6 +258,11 @@ public final class DexMerger { offsets[i] = readIntoMap( dexSections[i], sections[i], indexMaps[i], indexes[i], values, i); } + if (values.isEmpty()) { + getSection(contentsOut).off = 0; + getSection(contentsOut).size = 0; + return; + } getSection(contentsOut).off = out.getPosition(); int outCount = 0; @@ -299,6 +307,11 @@ public final class DexMerger { for (int i = 0; i < dexes.length; i++) { all.addAll(readUnsortedValues(dexes[i], indexMaps[i])); } + if (all.isEmpty()) { + getSection(contentsOut).off = 0; + getSection(contentsOut).size = 0; + return; + } Collections.sort(all); int outCount = 0; |