Android Kotlin: java.lang.NoClassDefFoundError: сбой разрешения: <KotlinObject>

Каждый второй запуск нашего приложения для Android, мы получаем сообщение об ошибке

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

BlahUtil - объект kotlin с аннотациями @JvmStatic. Я вызываю эти статические методы из остальной части приложения Android (все в java).

Мы используем multidex 1.0.1.

Я нахожусь в android studio 2.1.2, используя JDK 7.

Соответствующие 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"
}

Трассировка:

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

Ответ 1

Вы должны отключить "Мгновенный запуск". Android Studio → Настройки → Сборка, выполнение, развертывание → Мгновенный запуск. Выключите все.

Ответ 2

java.lang.ClassNotFoundException - забавное исключение для отладки. Примечательно, что это может происходить по ряду причин. В этом случае, из-за каждого другого поведения запуска, это, скорее всего, происходит из-за невозможности инициализировать класс. Если у вас есть ресурсы, которые вы загружаете статически, которые являются одноэлементными, открывайте файлы или любые "эксклюзивные" ресурсы при создании класса в JVM, когда он начинает инициализировать его во второй раз, поскольку класс уже загружен в JVM, независимо от того, перезапустили ли вы приложение. Когда происходит второй экземпляр загрузки класса, он сталкивается с существующим, и оба экземпляра удаляются из JVM, что делает выполнение третьего выполнения просто прекрасным.

tl; dr Мне нужно будет видеть, что ваш код будет положительным, но он наиболее вероятно (особенно с аннотациями @JvmStatic), что вы не выполняете вторую статическую загрузку класс. Когда он терпит неудачу, все экземпляры удаляются из JVM, и процесс повторяется.

Ответ 3

Единственным обходным решением, которое я нашел, является установка android.compileOptions.incremental = false

Подробнее см. эту проблему.