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
diff --git a/dx/etc/mainDexClasses b/dx/etc/mainDexClasses
index 28c0f0c..178ab18 100755
--- a/dx/etc/mainDexClasses
+++ b/dx/etc/mainDexClasses
@@ -137,10 +137,19 @@
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 <output file>] <application path>" 1>&2
@@ -155,4 +164,4 @@
-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 f6a4b56..1923ee4 100755
--- a/dx/etc/mainDexClasses.bat
+++ b/dx/etc/mainDexClasses.bat
@@ -67,6 +67,7 @@
set params=
set output=
+set disableKeepAnnotated=
:firstArg
if [%1]==[] goto endArgs
@@ -78,6 +79,13 @@
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 @@
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 c9e1a18..7fed119 100644
--- a/dx/src/com/android/multidex/MainDexListBuilder.java
+++ b/dx/src/com/android/multidex/MainDexListBuilder.java
@@ -53,18 +53,43 @@
"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 <a href="https://code.google.com/p/android/issues/detail?id=78144">bug discussion</a>
+ *
+ */
+ private static final String DISABLE_ANNOTATION_RESOLUTION_WORKAROUND =
+ "--disable-annotation-resolution-workaround";
+
private Set<String> filesToKeep = new HashSet<String>();
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<String> toKeep = builder.getMainDexList();
printList(toKeep);
} catch (IOException e) {
@@ -74,7 +99,8 @@
}
}
- 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 @@
for (String className : mainListBuilder.getClassNames()) {
filesToKeep.add(className + CLASS_EXTENSION);
}
- keepAnnotated(path);
+ if (keepAnnotated) {
+ keepAnnotated(path);
+ }
} finally {
try {
jarOfRoots.close();