*/
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";
}
}
+ /**
+ * {@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;
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.
*/
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()) {
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();
+ }
+ }
+
}
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()) {