diff options
-rw-r--r-- | dx/src/com/android/dx/command/dexer/Main.java | 18 | ||||
-rw-r--r-- | dx/src/com/android/dx/dex/file/MemberIdsSection.java | 36 | ||||
-rw-r--r-- | dx/src/com/android/dx/dex/file/TypeIdsSection.java | 4 | ||||
-rw-r--r-- | tests/089-many-methods/expected.txt | 4 |
4 files changed, 53 insertions, 9 deletions
diff --git a/dx/src/com/android/dx/command/dexer/Main.java b/dx/src/com/android/dx/command/dexer/Main.java index 042a0866e..ab6d2f788 100644 --- a/dx/src/com/android/dx/command/dexer/Main.java +++ b/dx/src/com/android/dx/command/dexer/Main.java @@ -77,12 +77,6 @@ import java.util.jar.Manifest; */ public class Main { /** - * {@code non-null;} Error message for too many method/field/type ids. - */ - public static final String TO_MANY_ID_ERROR_MESSAGE = - "Dex limit exceeded. You may try option " + Arguments.MULTI_DEX_OPTION; - - /** * File extension of a {@code .dex} file. */ private static final String DEX_EXTENSION = ".dex"; @@ -240,6 +234,18 @@ public class Main { } } + /** + * {@code non-null;} Error message for too many method/field/type ids. + */ + public static String getTooManyIdsErrorMessage() { + if (args.multiDex) { + return "The list of classes given in " + Arguments.MAIN_DEX_LIST_OPTION + + " is too big and does not fit in the main dex."; + } else { + return "You may try using " + Arguments.MULTI_DEX_OPTION + " option."; + } + } + private static int runMonoDex() throws IOException { File incrementalOutFile = null; diff --git a/dx/src/com/android/dx/dex/file/MemberIdsSection.java b/dx/src/com/android/dx/dex/file/MemberIdsSection.java index 6c6eb49f5..bd15df765 100644 --- a/dx/src/com/android/dx/dex/file/MemberIdsSection.java +++ b/dx/src/com/android/dx/dex/file/MemberIdsSection.java @@ -20,6 +20,11 @@ import com.android.dex.DexException; import com.android.dex.DexFormat; import com.android.dx.command.dexer.Main; +import java.util.Formatter; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.atomic.AtomicInteger; + /** * Member (field or method) refs list section of a {@code .dex} file. */ @@ -42,7 +47,7 @@ public abstract class MemberIdsSection extends UniformItemSection { int idx = 0; if (items().size() > DexFormat.MAX_MEMBER_IDX + 1) { - throw new DexException(Main.TO_MANY_ID_ERROR_MESSAGE); + throw new DexException(getTooManyMembersMessage()); } for (Object i : items()) { @@ -50,4 +55,33 @@ public abstract class MemberIdsSection extends UniformItemSection { idx++; } } + + private String getTooManyMembersMessage() { + Map<String, AtomicInteger> membersByPackage = new TreeMap<String, AtomicInteger>(); + for (Object member : items()) { + String packageName = ((MemberIdItem) member).getDefiningClass().getPackageName(); + AtomicInteger count = membersByPackage.get(packageName); + if (count == null) { + count = new AtomicInteger(); + membersByPackage.put(packageName, count); + } + count.incrementAndGet(); + } + + Formatter formatter = new Formatter(); + try { + String memberType = this instanceof MethodIdsSection ? "method" : "field"; + formatter.format("Too many %s references: %d; max is %d.%n" + + Main.getTooManyIdsErrorMessage() + "%n" + + "References by package:", + memberType, items().size(), DexFormat.MAX_MEMBER_IDX + 1); + for (Map.Entry<String, AtomicInteger> entry : membersByPackage.entrySet()) { + formatter.format("%n%6d %s", entry.getValue().get(), entry.getKey()); + } + return formatter.toString(); + } finally { + formatter.close(); + } + } + } diff --git a/dx/src/com/android/dx/dex/file/TypeIdsSection.java b/dx/src/com/android/dx/dex/file/TypeIdsSection.java index 1603f7cc9..ef47262a5 100644 --- a/dx/src/com/android/dx/dex/file/TypeIdsSection.java +++ b/dx/src/com/android/dx/dex/file/TypeIdsSection.java @@ -85,7 +85,9 @@ public final class TypeIdsSection extends UniformItemSection { int offset = (sz == 0) ? 0 : getFileOffset(); if (sz > DexFormat.MAX_TYPE_IDX + 1) { - throw new DexException(Main.TO_MANY_ID_ERROR_MESSAGE); + throw new DexException("Too many type references: " + sz + + "; max is " + (DexFormat.MAX_TYPE_IDX + 1) + ".\n" + + Main.getTooManyIdsErrorMessage()); } if (out.annotates()) { diff --git a/tests/089-many-methods/expected.txt b/tests/089-many-methods/expected.txt index fc97b3dbd..b74e0eef8 100644 --- a/tests/089-many-methods/expected.txt +++ b/tests/089-many-methods/expected.txt @@ -1,4 +1,6 @@ -trouble writing output: Too many fields: 131000; max is 65536. By package: +trouble writing output: Too many field references: 131000; max is 65536. +You may try using --multi-dex option. +References by package: 131000 default build exit status: 2 |