Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Kotlin : java.lang.NoClassDefFoundError: Failed resolution of: <KotlinObject>

Every second run of our android app, we get a crash that says

java.lang.NoClassDefFoundError: Failed resolution of: Lin/blahapp/xxx/BlahUtil

BlahUtil is a kotlin object with @JvmStatic annotations in it. I call these static methods from the rest of the android app(All in java) .

We use multidex 1.0.1.

I am on android studio 2.1.2, using JDK 7.

Relevant gradle configs:

compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
        minSdkVersion 16
        targetSdkVersion 23
}
dexOptions {
        incremental true
        dexInProcess true
        javaMaxHeapSize "10g"
        preDexLibraries true
}
buildscript {
    ext.kotlin_version = '1.0.3'

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
apply plugin: 'kotlin-android'
dependencies {
  compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
  compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}

Trace:

at in.blahapp.xxx.OurActivity 
at android.app.Activity.performCreate(Activity.java:6251)
at ndroid.app.Instrumentation.callActivityOnCreate
at android.app.ActivityThread.performLaunchActivity
at android.app.ActivityThread.handleLaunchActivity
at android.app.ActivityThread.-wrap11
at android.app.ActivityThread$H.handleMessage
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Caused by: java.lang.ClassNotFoundException: Didn't find class "in.blahapp.xxx.BlahUtil" on path: DexPathList[[dex file ....

logcat output

like image 685
letronje Avatar asked Aug 01 '16 04:08

letronje


Video Answer


3 Answers

The only workaround I've found is to set android.compileOptions.incremental = false

See this issue for details.

like image 109
Dmide Avatar answered Oct 18 '22 03:10

Dmide


java.lang.ClassNotFoundException is a fun exception to debug. Notably because it can occur from any number of reasons. In this case, due to the every other launch behavior, it's most likely occurring due to being unable to initialize the class. If you have resources that you load statically that are singleton in nature, open files, or any "exclusive" resources on class creation in the JVM, when it goes to initialize it the second time, as the class is already loaded into the JVM, regardless of whether or not you've restarted the application. When the second instance of loading the class occurs, it clashes with the existing one and both instances are removed from the JVM, making the third execution run just fine.

tl;dr I'd have to see your code to be positive, but it's most likely (especially with @JvmStatic annotations), that you're failing on the second static loading of the class. When it fails, all instances are removed from the JVM and the process repeats.

like image 37
Shayne Fitzgerald Avatar answered Oct 18 '22 02:10

Shayne Fitzgerald


You should turn off 'Instant Run'. Android Studio -> Preferences -> Build, Execution, Deployment -> Instant Run. Turn off everything.

like image 3
BurtK Avatar answered Oct 18 '22 03:10

BurtK