From 45e4d877614b194e24afbb90024130fd4e3156f5 Mon Sep 17 00:00:00 2001 From: Yohann Roussel Date: Thu, 8 Jan 2015 10:54:55 +0100 Subject: Allow to disable forced keep of annotated We force all classes annotated with runtime annotation to be kept in the main dex list. This allow to workaround a Dalvik bug when accessing the annotations. But this increase the pressure in the main dex indexes. The new option is to allow to disable this workaround for application facing the index limit in their main dex and that don't access annotation at runtime or that have only annotations not subject to the resolution bug. Bug: 18928046 Change-Id: Ibcd7e579a7fef3451ec8aeb266ea67514d82cd50 --- dx/etc/mainDexClasses | 11 ++++++- dx/etc/mainDexClasses.bat | 12 +++++-- .../com/android/multidex/MainDexListBuilder.java | 38 +++++++++++++++++++--- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/dx/etc/mainDexClasses b/dx/etc/mainDexClasses index 28c0f0c89..178ab1810 100755 --- a/dx/etc/mainDexClasses +++ b/dx/etc/mainDexClasses @@ -137,10 +137,19 @@ else jarpath="$libdir/$jarfile" fi +disableKeepAnnotated= + +while true; do if expr "x$1" : 'x--output' >/dev/null; then exec 1>$2 shift 2 +elif expr "x$1" : 'x--disable-annotation-resolution-workaround' >/dev/null; then + disableKeepAnnotated=$1 + shift 1 +else + break fi +done if [ $# -ne 1 ]; then echo "Usage : $0 [--output ] " 1>&2 @@ -155,4 +164,4 @@ ${proguard} -injars ${@} -dontwarn -forceprocessing -outjars ${tmpOut} \ -libraryjars "${shrinkedAndroidJar}" -dontoptimize -dontobfuscate -dontpreverify \ -include "${baserules}" 1>/dev/null || exit 10 -java -cp "$jarpath" com.android.multidex.MainDexListBuilder "${tmpOut}" ${@} || exit 11 +java -cp "$jarpath" com.android.multidex.MainDexListBuilder ${disableKeepAnnotated} "${tmpOut}" ${@} || exit 11 diff --git a/dx/etc/mainDexClasses.bat b/dx/etc/mainDexClasses.bat index f6a4b56ca..1923ee4f5 100755 --- a/dx/etc/mainDexClasses.bat +++ b/dx/etc/mainDexClasses.bat @@ -67,6 +67,7 @@ REM followed by "value". Dx has been changed to know how to deal with that. set params= set output= +set disableKeepAnnotated= :firstArg if [%1]==[] goto endArgs @@ -78,6 +79,13 @@ if [%1]==[] goto endArgs goto firstArg :notOut + + if %1 NEQ --disable-annotation-resolution-workaround goto notDisable + set "disableKeepAnnotated=%1" + shift + goto firstArg + +:notDisable if defined params goto usage set params=%1 shift @@ -96,10 +104,10 @@ set "exitStatus=0" call "%proguard%" -injars %params% -dontwarn -forceprocessing -outjars "%tmpJar%" -libraryjars "%shrinkedAndroidJar%" -dontoptimize -dontobfuscate -dontpreverify -include "%baserules%" 1>nul if DEFINED output goto redirect -call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.MainDexListBuilder "%tmpJar%" "%params%" +call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.MainDexListBuilder "%disableKeepAnnotated%" "%tmpJar%" "%params%" goto afterClassReferenceListBuilder :redirect -call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.MainDexListBuilder "%tmpJar%" "%params%" 1>"%output%" +call "%java_exe%" -Djava.ext.dirs="%frameworkdir%" com.android.multidex.MainDexListBuilder "%disableKeepAnnotated%" "%tmpJar%" "%params%" 1>"%output%" :afterClassReferenceListBuilder del %tmpJar% diff --git a/dx/src/com/android/multidex/MainDexListBuilder.java b/dx/src/com/android/multidex/MainDexListBuilder.java index c9e1a186c..7fed11925 100644 --- a/dx/src/com/android/multidex/MainDexListBuilder.java +++ b/dx/src/com/android/multidex/MainDexListBuilder.java @@ -53,18 +53,43 @@ public class MainDexListBuilder { "Slightly longer version: This tool is used by mainDexClasses script to build" + EOL + "the main dex list." + EOL; + /** + * By default we force all classes annotated with runtime annotation to be kept in the + * main dex list. This option disable the workaround, limiting the index pressure in the main + * dex but exposing to the Dalvik resolution bug. The resolution bug occurs when accessing + * annotations of a class that is not in the main dex and one of the annotations as an enum + * parameter. + * + * @see bug discussion + * + */ + private static final String DISABLE_ANNOTATION_RESOLUTION_WORKAROUND = + "--disable-annotation-resolution-workaround"; + private Set filesToKeep = new HashSet(); public static void main(String[] args) { - if (args.length != 2) { + int argIndex = 0; + boolean keepAnnotated = true; + while (argIndex < args.length -2) { + if (args[argIndex].equals(DISABLE_ANNOTATION_RESOLUTION_WORKAROUND)) { + keepAnnotated = false; + } else { + System.err.println("Invalid option " + args[argIndex]); + printUsage(); + System.exit(STATUS_ERROR); + } + argIndex++; + } + if (args.length - argIndex != 2) { printUsage(); System.exit(STATUS_ERROR); } try { - - MainDexListBuilder builder = new MainDexListBuilder(args[0], args[1]); + MainDexListBuilder builder = new MainDexListBuilder(keepAnnotated, args[argIndex], + args[argIndex + 1]); Set toKeep = builder.getMainDexList(); printList(toKeep); } catch (IOException e) { @@ -74,7 +99,8 @@ public class MainDexListBuilder { } } - public MainDexListBuilder(String rootJar, String pathString) throws IOException { + public MainDexListBuilder(boolean keepAnnotated, String rootJar, String pathString) + throws IOException { ZipFile jarOfRoots = null; Path path = null; try { @@ -91,7 +117,9 @@ public class MainDexListBuilder { for (String className : mainListBuilder.getClassNames()) { filesToKeep.add(className + CLASS_EXTENSION); } - keepAnnotated(path); + if (keepAnnotated) { + keepAnnotated(path); + } } finally { try { jarOfRoots.close(); -- cgit v1.2.3