Dexopt failed on a very big APK (Out-of-order method_idx) when dex.force.jumbo=true

Gili Nachum picture Gili Nachum · Nov 25, 2012 · Viewed 7.8k times · Source

I have a very big Android project with a multiple, big, 3rd party jars (as Android Libraries).
I believe I've hit a Dex's max number of method limitation (compiling via eclipse):

[2012-11-18 02:28:45 - Find In Files] Dx processing classes.dex...
[2012-11-18 02:28:48 - Dex Loader] Unable to execute dex: Cannot merge new index 66774 into a non-jumbo instruction!
[2012-11-18 02:28:48 - Find In Files] Conversion to Dalvik format failed: Unable to execute dex: Cannot merge new index 66774 into a non-jumbo instruction!

Taking advantage of SDK tools 21 (platform tools 16), I therefore, edited my main project project.properties to set dex.force.jumbo=true.
The flag allowed to me generate the APK. But I couldn't install it properly (on physical and emulator alike). There seems to be a dex optimizer failure:

11-18 20:11:05.338: I/PackageManager(103): Running dexopt on: com.mypackage.myapp
11-18 20:11:08.577: E/dalvikvm(868): Out-of-order method_idx: 0x2ae0 then 0x1
11-18 20:11:08.577: E/dalvikvm(868): Trouble with item 1544 @ offset 0xf7ae24
11-18 20:11:08.577: E/dalvikvm(868): Swap of section type 2006 failed
11-18 20:11:08.577: E/dalvikvm(868): ERROR: Byte swap + verify failed
11-18 20:11:08.597: E/dalvikvm(868): Optimization failed
11-18 20:11:08.597: W/installd(39): DexInv: --- END '/data/app/com.mypackage.myapp-1.apk' --- status=0xff00, process failed
11-18 20:11:08.597: E/installd(39): dexopt failed on '/data/dalvik-cache/data@[email protected]@classes.dex' res = 65280
11-18 20:11:08.697: W/PackageManager(103): Package couldn't be installed in /data/app/com.mypackage.myapp-1.apk
11-18 20:11:09.018: D/dalvikvm(103): GC_EXPLICIT freed 1698K, 13% free 17034K/19463K, paused 7ms+135ms
11-18 20:11:09.068: D/AndroidRuntime(780): Shutting down VM

Am I trying to use the dex.force.jumbo flag for a purpose it was not intended for, or is this error unpredictable?
If so, is there a better strategy to generate a project that includes a very big number of classes/methods?

Answer

Gili Nachum picture Gili Nachum · Jan 27, 2013

The 64K methods limit is a Dex format limitation (it uses 2 bytes to lookup a method).
Nandeesh comment's points out that jumbo solves string only, not methods.

Alternatives I tried/considered (brace yourselves, they all suck):
1. Do It Yourself - Throw away the fattest 3rd party libraries and write the exact parts of its functionality yourself. This is the approach I ended up taking, as I realized I'm including a lot of code for a small functionality.
2. Custom class loading in Dalvik - Compile a separate Dex and load it on runtime. Cons: cumbersome, requires reflection.
3. Code Pruning - Turn on verbose class loading, run the app and try to remove 3rd party libraries, or parts of the library that are not really used. Cons: time consuming, error prone as classes are dynamically loaded.
4. Divide And Concur - Package 3rd party libraries in a separate process (a service). This service will provide the 3rd party libraries functionality. Perform calls on this service from your main program.

I believe that it's a case of 640k ought to be enough for anybody OR No way will have this on every 2nd phone in the planet on the part of Dalvik's early design team.

If you want to read more or simply cry out load to Google, I've created this defect: http://code.google.com/p/android/issues/detail?id=40409