Unable to execute dex: method ID not in [0, 0xffff]: 65536
Asked Answered
F

12

346

I have seen various versions of the dex erros before, but this one is new. clean/restart etc won't help. Library projects seems intact and dependency seems to be linked correctly.

Unable to execute dex: method ID not in [0, 0xffff]: 65536
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536

or

Cannot merge new index 65950 into a non-jumbo instruction

or

java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536

tl;dr: Official solution from Google is finally here!

http://developer.android.com/tools/building/multidex.html

Only one small tip, you will likely need to do this to prevent out of memory when doing dex-ing.

dexOptions {
        javaMaxHeapSize "4g"
}

There's also a jumbo mode that can fix this in a less reliable way:

dexOptions {
        jumboMode true
}

Update: If your app is fat and you have too many methods inside your main app, you may need to re-org your app as per

http://blog.osom.info/2014/12/too-many-methods-in-main-dex.html

Froggy answered 4/3, 2013 at 19:46 Comment(10)
Do you use api which is not aviable on your currient device?Fallon
It's there, because another project build fine targeting the same API version.Froggy
So you use at some point API which is not available? Do you check with a line like if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) that you don't call this function if it is not available?Fallon
Yea, I do. The project built fine before. Also, that should be a runtime error even if I missed the line.Froggy
It's probably one of the dependencies is messed up. (doing a mix of maven+project lib right now)Froggy
I have the same problem. Could you tell me how did you solve it?Advisable
@Froggy is it possible that you a) downvoted my answer and b) took a part from it to add to the question as a tip (it really looks like it comparing the time from your edit, and my answer&downvote). Apart from that being a very strange behavior, this is a Q&A site NOT a forum, the answers should NOT be in the question, if you think you have an answer answer your own question and then update it (this is how it should be done)Josuejosy
I added the tip base on my own experience and I didn't downvote your answer, and I did upvote most of the old answers, I didn't upvote yours because I felt you were just trying to summarize the rest of the page but not ideal because people should really just follow the official page. I wouldn't sacrifice a point for that.Froggy
Also, This is not JUST a Q&A site, this is a site that helps people. So I don't agree on that answers shouldn't be in the question if I believe that more people would find it useful. You don't have to agree with me on this, but I think a lot people do find this helpful and many of the questions are done this way, we all trying to help people better. re: @for3stFroggy
@Froggy dexOptions's jumbo mode has no effect on method indices (though it can help when dex file has too many strings), therefore I'd suggest to remove this to prevent confusion and mislead.Cogitate
C
379

Update 3 (11/3/2014)
Google finally released official description.


Update 2 (10/31/2014)
Gradle plugin v0.14.0 for Android adds support for multi-dex. To enable, you just have to declare it in build.gradle:

android {
   defaultConfig {
      ...
      multiDexEnabled  true
   }
}

If your application supports Android prior to 5.0 (that is, if your minSdkVersion is 20 or below) you also have to dynamically patch the application ClassLoader, so it will be able to load classes from secondary dexes. Fortunately, there's a library that does that for you. Add it to your app's dependencies:

dependencies {
  ...
  compile 'com.android.support:multidex:1.0.0'
} 

You need to call the ClassLoader patch code as soon as possible. MultiDexApplication class's documentation suggests three ways to do that (pick one of them, one that's most convenient for you):

1 - Declare MultiDexApplication class as the application in your AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.multidex.myapplication">
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
</manifest>

2 - Have your Application class extend MultiDexApplication class:

public class MyApplication extends MultiDexApplication { .. }

3 - Call MultiDex#install from your Application#attachBaseContext method:

public class MyApplication {
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
        ....
    }
    ....
}

Update 1 (10/17/2014):
As anticipated, multidex support is shipped in revision 21 of Android Support Library. You can find the android-support-multidex.jar in /sdk/extras/android/support/multidex/library/libs folder.


Multi-dex support solves this problem. dx 1.8 already allows generating several dex files.
Android L will support multi-dex natively, and next revision of support library is going to cover older releases back to API 4.

It was stated in this Android Developers Backstage podcast episode by Anwar Ghuloum. I've posted a transcript (and general multi-dex explanation) of the relevant part.

Cogitate answered 4/10, 2014 at 19:32 Comment(29)
blog post is a saver! :DFlareup
Marking this as the answer as of time of this comment.Froggy
Hi Alex, thanks for all the info. Today i tried to multidex my app according to the new Google Documentation and it compiles just fine but when running it, i get the following exception: java.lang.RuntimeException: Unable to instantiate application android.support.multidex.MultiDexApplication: java.lang.ClassNotFoundException: Didn't find class "android.support.multidex.MultiDexApplication" on path: DexPathList Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.multidex.MultiDexApplication" on path:Bristletail
@dustedrob Have you added the support library as dependency?Cogitate
I did: compile 'com.android.support:multidex:1.0.0' and compile 'com.android.support:appcompat-v7:21.0.0'. I made sure to have the latest support library 8Bristletail
I have installed the latest Android Support Library revision 21.0.1, using the Android SDK Manager. I then restarted the Luna Eclipse, and tried to run my Project, it is still giving me the same problem. Please help me solve my problem.Sappanwood
this solution for android studio or eclipse, I have same problem and using eclipse junoEnnis
@Ennis Android Studio only. For eclipse, see my answer here: https://mcmap.net/q/94245/-android-multidex-support-library-using-eclipseCogitate
If you are using Android Studio make sure that it is at least version 0.9.Impasto
Anything for eclipse users?Fivepenny
@AlexLipov Eversince i have added this option i keep on getting crash at NoClassDefFoundError on most of my functions everywhere in code. What has happened? i am using android studio 1.1.0Endocranium
@MuhammadUmar See if this helps: stackoverflow.com/questions/26655541. If it doesn't, post your stack trace. Do you use plugin's 'multiDexEnabled = true' or adding dx parameters manually?Cogitate
@AlexLipov I Used multiDexEnabled = trueEndocranium
@MuhammadUmar can you post your stack trace (on external resource, i.e. privatepaste.com and post the link here)?Cogitate
privatepaste.com/8e81fecf14 check this. I am getting NoClassDefFoundError at new GetAllContacts().execute();. There is no other stackTrace Info except this error. Its extremely simple code. If i comment out this, there are a lot other places where i get this same errorEndocranium
@MuhammadUmar Start with verifying that your GetAllContacts class is listed in maindexlist (/app/build/intermediates/multi-dex/{debug/release}/maindexlist.txt). Also, look for verifier warnings in logcat (dalvikvm with VFY tag).Cogitate
@MuhammadBabar There is Android studio for Eclipse users.Surprint
Adding Multi-Dex has the disadvantage that build time increases significantly. My build time went up to 4 mins on enabling Multi-Dex. Its best to avoid it (eg by selectively compile Google Play service APIs into your app see developers.google.com/android/guides/setup).Tawny
@MohammedAli Sure, avoid using it if you can. But what should you do if you really have too many methods in your app, and you already tried all the tricks like the one that you mentioned? Regarding the build time - there's solution for this, at least for development builds - see my answer here: https://mcmap.net/q/94246/-speed-up-gradle-build-in-multidex-applicationCogitate
thanks! the entire google build system is a piece of work.Deadly
How does this work for Maven users? How do I generate the main dex list via maven?Fenske
hello , @Alex Lipov After multiDexEnabled = true in my gradle file , in my device samsung galaxy edge -> run sccuessfully but in other devices it generate fatal error class not found.. so any solution for it ?Vanquish
@JosephMekwan There're many ClassNotFound/multidex related questions in SO - search for them. If you can't find something that solves your problem then post new question.Cogitate
For eclipse users, after adding the jar to libs, take a look at this Also all the jars/library projects that your project uses should only have 1 copy and shouldn't have any transitive dependency. You can confirm this by seeing all the jars in bin/dexedLibs directory of your project. There should only be 1 copy of each jar in itNottage
On Qt for Android, I was having issues at runtime for my app when integrating Facebook+Twitter's SDKs together, even after enabling multidex support (this one error in particular gave me nightmares: java.lang.ClassNotFoundException: Didn't find class "org.qtproject.qt5.android.QtActivityDelegate" on path: DexPathList[[],nativeLibraryDirectories=[/vendor/lib, /system/lib]]). It turned out that my mistake was that I wasn't applying the additional steps for Android support prior to 5.0. With that said, option #3 solved it, and I had no more ClassNotFoundException issues. Thanks, @Alex Lipov!Apollus
if you wish to know more info about what happend here try to read this: medium.com/@rotxed/…Burge
This solved my problem thank you. But I want to know the reason why it occured and how this piece of code solved the issue.Goggle
@Goggle Did you read the official documentation that I've mentioned in my answer?Cogitate
Just blindly pasted the code snippets from this answer in the respective files, and it worked like a charm.Woodworm
J
78

As already stated, you have too many methods (more than 65k) in your project and libaries.

Prevent the Problem: Reduce the number of methods with Play Services 6.5+ and support-v4 24.2+

Since often the Google Play Services is one of the main suspects in "wasting" methods with its 20k+ methods. Google Play Services version 6.5 or later, it is possible for you to include Google Play Services in your application using a number of smaller client libraries. For example, if you only need GCM and maps you can choose to use these dependencies only:

dependencies {
    compile 'com.google.android.gms:play-services-base:6.5.+'
    compile 'com.google.android.gms:play-services-maps:6.5.+'
}

The full list of sub libraries and its responsibilities can be found in the official google doc.

Update: Since Support Library v4 v24.2.0 it was split up into the following modules:

support-compat, support-core-utils, support-core-ui, support-media-compat and support-fragment

dependencies {
    compile 'com.android.support:support-fragment:24.2.+'
}

Do note however, if you use support-fragment, it will have dependencies to all the other modules (i.e. if you use android.support.v4.app.Fragment there is no benefit)

See here the official release notes for support-v4 lib


Enable MultiDexing

Since Lollipop (aka build tools 21+) it is very easy to handle. The approach is to work around the 65k methods per DEX file problem to create multiple DEX files for your app. Add the following to your Gradle build file (this is taken from the official google doc on applications with more than 65k methods):

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.0"

    defaultConfig {
        ...
        // Enabling multidex support.
        multiDexEnabled true
    }
    ...
}

dependencies {
  compile 'com.android.support:multidex:1.0.1'
}

The second step is to either prepare your Application class or if you don't extend Application use the MultiDexApplication in your Android Manifest:

Either add this to your Application.java

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}

or use the provided application from the mutlidex lib

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.myapplication">
    <application
        ...
        android:name="android.support.multidex.MultiDexApplication">
        ...
    </application>
</manifest>

Prevent OutOfMemory with MultiDex

As further tip, if you run into OutOfMemory exceptions during the build phase you could enlarge the heap with

android {
    ...
    dexOptions {
        javaMaxHeapSize "4g"
    }
}

which would set the heap to 4 gigabytes.

See this question for more detail on the DEX heap memory issue.


Analyze the source of the Problem

To analyze the source of the methods the Gradle plugin https://github.com/KeepSafe/dexcount-gradle-plugin can help in combination with the dependency tree provided by Gradle with e.g.

.\gradlew app:dependencies

See this answer and question for more information on method count in android

Josuejosy answered 19/2, 2015 at 12:45 Comment(4)
I've used Play Services 6.5+ solution and it worked perfectly. Incredible useful tip. Thanks so much!Wylie
I'd upvote more if I could - cutting out all the other Play Services stuff that we weren't using fixed this issue, without having to resort to multi-dex, which has negative performance implications when building.Countryfied
Than you so much with tears in my eyes. You saved meDaguerre
I used client library for GCM, because I am using only gcm service from play service, now it fixed my problem with this. Thanks! to save my time.Latter
S
56

Your project is too large. You have too many methods. There can only be 65536 methods per application. see here https://code.google.com/p/android/issues/detail?id=7147#c6

Scabbard answered 11/3, 2013 at 11:15 Comment(5)
I see. I do have lots of dependencies for this project. It builds fine before I moved to use maven though, maybe maven added unnecessary dependencies. Will double check.Froggy
To be more specific, there can only be 65,536 methods per Dalvik executable (dex) file. And an application (APK) can have more than one dex file with such things as custom loading.Pforzheim
It's really embarrassing bug for android! Anyway, In me case I removed Jar that was in the libs and wasn't in use, and the app compiledDall
Time to clean up my project :/Philoctetes
A quick fix would be to use Proguard also with the debug buildsZibeline
R
12

The below code helps, if you use Gradle. Allows you to easily remove unneeded Google services (presuming you're using them) to get back below the 65k threshold. All credit to this post: https://gist.github.com/dmarcato/d7c91b94214acd936e42

Edit 2014-10-22: There's been a lot of interesting discussion on the gist referenced above. TLDR? look at this one: https://gist.github.com/Takhion/10a37046b9e6d259bb31

Paste this code at the bottom of your build.gradle file and adjust the list of google services you do not need:

def toCamelCase(String string) {
    String result = ""
    string.findAll("[^\\W]+") { String word ->
        result += word.capitalize()
    }
    return result
}

afterEvaluate { project ->
    Configuration runtimeConfiguration = project.configurations.getByName('compile')
    ResolutionResult resolution = runtimeConfiguration.incoming.resolutionResult
    // Forces resolve of configuration
    ModuleVersionIdentifier module = resolution.getAllComponents().find { it.moduleVersion.name.equals("play-services") }.moduleVersion

    String prepareTaskName = "prepare${toCamelCase("${module.group} ${module.name} ${module.version}")}Library"
    File playServiceRootFolder = project.tasks.find { it.name.equals(prepareTaskName) }.explodedDir

    Task stripPlayServices = project.tasks.create(name: 'stripPlayServices', group: "Strip") {
        inputs.files new File(playServiceRootFolder, "classes.jar")
        outputs.dir playServiceRootFolder
        description 'Strip useless packages from Google Play Services library to avoid reaching dex limit'

        doLast {
            copy {
                from(file(new File(playServiceRootFolder, "classes.jar")))
                into(file(playServiceRootFolder))
                rename { fileName ->
                    fileName = "classes_orig.jar"
                }
            }
            tasks.create(name: "stripPlayServices" + module.version, type: Jar) {
                destinationDir = playServiceRootFolder
                archiveName = "classes.jar"
                from(zipTree(new File(playServiceRootFolder, "classes_orig.jar"))) {
                    exclude "com/google/ads/**"
                    exclude "com/google/android/gms/analytics/**"
                    exclude "com/google/android/gms/games/**"
                    exclude "com/google/android/gms/plus/**"
                    exclude "com/google/android/gms/drive/**"
                    exclude "com/google/android/gms/ads/**"
                }
            }.execute()
            delete file(new File(playServiceRootFolder, "classes_orig.jar"))
        }
    }

    project.tasks.findAll { it.name.startsWith('prepare') && it.name.endsWith('Dependencies') }.each { Task task ->
        task.dependsOn stripPlayServices
    }
}
Rondarondeau answered 25/9, 2014 at 21:23 Comment(6)
Love it! def needed as companies like Google keep inflating the packages.Froggy
Nice - this did the job spot on. No hasswle and no worry!Gley
Note: this deleted google play services jars in my Android SDK in Android Studio! A bad idea since it's not easy to revert back to original jars. The author should modify the script to change the jars in the build directory.Pachysandra
@inder: I didn't have that problem. However, I did have to do a clean each time I monkeyed with the excludes (we use analytics).Engagement
how to exclude this from release builds?Deli
I didn't work for me, I got Error:Gradle: Execution failed for task ':myapp:compileDevDebugJava'. > Compilation failed; see the compiler error output for details. /Users/eric/tmp/myapp/android/MyApp/myapp/src/main/java/com/myapp/data/core/ChannelAnalyticDataHelper.java Error:(14, 36) Gradle: package com.google.android.gms.games does not existGuillotine
E
6

I've shared a sample project which solve this problem using custom_rules.xml build script and a few lines of code.

I used it on my own project and it is runs flawless on 1M+ devices (from android-8 to the latest android-19). Hope it helps.

https://github.com/mmin18/Dex65536

Exuberant answered 8/3, 2014 at 9:18 Comment(2)
Thanks for the scripts. you should watch out for ART. Device may convert only your default dex and not the secondary ones. Proguard solutions should be preferred.Froggy
When i import the projects into the Eclipse and run it gives error. "Unable to execute dex: method ID not in [0, 0xffff]: 65536". Can you explaing the usage of the projectAntediluvian
M
6

Faced the same problem and solved it by editing my build.gradle file on the dependencies section, removing:

compile 'com.google.android.gms:play-services:7.8.0'

And replacing it with:

compile 'com.google.android.gms:play-services-location:7.8.0'
compile 'com.google.android.gms:play-services-analytics:7.8.0' 
Mclaurin answered 19/8, 2015 at 23:31 Comment(1)
Perfect! I just use the Google Drive API and this works.Osmic
C
5

Try adding below code in build.gradle, it worked for me -

compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
    multiDexEnabled true
}
Correlation answered 3/11, 2015 at 22:9 Comment(0)
S
2

The perfect solution for this would be to work with Proguard. as aleb mentioned in the comment. It will decrease the size of the dex file by half.

Sectarianism answered 31/7, 2014 at 11:1 Comment(1)
Agreed, with an increasingly large google play services jar especially *(18k methods by itself)Froggy
K
2

You can analyse problem (dex file references) using Android Studio:

Build -> Analyse APK ..

On the result panel click on classes.dex file

And you'll see:

enter image description here

Koph answered 3/6, 2017 at 0:1 Comment(0)
P
0

gradle + proguard solution:

afterEvaluate {
  tasks.each {
    if (it.name.startsWith('proguard')) {
        it.getInJarFilters().each { filter ->
            if (filter && filter['filter']) {
                filter['filter'] = filter['filter'] +
                        ',!.readme' +
                        ',!META-INF/LICENSE' +
                        ',!META-INF/LICENSE.txt' +
                        ',!META-INF/NOTICE' +
                        ',!META-INF/NOTICE.txt' +
                        ',!com/google/android/gms/ads/**' +
                        ',!com/google/android/gms/cast/**' +
                        ',!com/google/android/gms/games/**' +
                        ',!com/google/android/gms/drive/**' +
                        ',!com/google/android/gms/wallet/**' +
                        ',!com/google/android/gms/wearable/**' +
                        ',!com/google/android/gms/plus/**' +
                        ',!com/google/android/gms/topmanager/**'
            }
        }
    }
  }
}
Particle answered 22/10, 2014 at 7:12 Comment(0)
A
0

Remove some jar file from Libs folder and copy to some other folder, And Go to _Project Properties > Select Java Build Path, Select Libraries, Select Add External Jar, Select the Removed jar to your project, Click save, this will be added under Referenced Library instead of Libs folder. Now clean and Run your project. You dont need to add Any code for MultDex. Its simply worked for me.

Accommodate answered 4/11, 2015 at 12:10 Comment(0)
R
0

I was facing the same issue today what worked for is below down

For ANDROID STUDIO... Enable Instant Run

In File->Preferences->Build, Execution, Deployment->Instant Run-> Check Enable Instant run for hot swap...

Hope it helps

Radial answered 10/10, 2017 at 10:22 Comment(1)
This worked for me - I simply disabled Enable Run, clicked Apply, reenabled it, and it worked again.Bevatron

© 2022 - 2024 — McMap. All rights reserved.