Reputation: 1521
Recently, when I was going to finish my work at home on my PC with Windows 8.1, I've found out the project doesn't work properly - it compiles, runs on the emulator and crashes at some specific point (it's 100% reproducible on my PC).
However, the same repository revision works on a Mac at work and on my colleagues Windows 10 machine.
Every mentioned environment was using Android Studio 2.3.1, gradle 3.3 and Kotlin 1.1.1 and running the application on the API 25 x86_64 image.
The project is using multidex 1.0.1 library.
The crash happens due to the following exception:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.project.app, PID: 2533
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/project/package/SomeActivityKt$sam$Action1$22181393;
at com.project.package.SomeActivity.getDataFor(SomeActivity.kt:164)
at com.project.package.SomeActivity.getData(SomeActivity.kt:147)
at com.project.package.SomeActivity.onResume(SomeActivity.kt:142)
at android.app.Instrumentatcomn.callActivityOnResume(Instrumentatcomn.java:1269)
at android.app.Activity.performResume(Activity.java:6783)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3406)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3469)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2732)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.project.package.SomeActivityKt$sam$Action1$22181393" on path: DexPathList[[zip file "/data/app/com.project.app-1/base.apk", zip file "/data/app/com.project.app-1/split_lib_dependencies_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_0_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_1_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_2_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_3_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_4_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_5_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_6_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_7_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_8_apk.apk", zip file "/data/app/com.project.app-1/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.project.app-1/lib/x86_64, /data/app/com.project.app-1/base.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_dependencies_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_0_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_1_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_2_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_3_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_4_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_5_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_6_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_7_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_8_apk.apk!/lib/x86_64, /data/app/com.project.app-1/split_lib_slice_9_apk.apk!/lib/x86_64, /system/lib64, /vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at com.project.package.SomeActivity.getDataFor(SomeActivity.kt:164)
at com.project.package.SomeActivity.getData(SomeActivity.kt:147)
at com.project.package.SomeActivity.onResume(SomeActivity.kt:142)
at android.app.Instrumentatcomn.callActivityOnResume(Instrumentatcomn.java:1269)
at android.app.Activity.performResume(Activity.java:6783)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3406)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3469)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2732)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
BaseActivity.kt
abstract class BaseActivity : RxAppCompatActivity(), HasErrorHandler (...)
SomeActivity.kt - this crashes
class SomeActivity : BaseActivity(), HasFullWindowProgress (...) {
(...)
private fun getDataFor(id: String) {
apiClient.somethingList(id)
.map { response -> response.toSomethingList() }
.lifecycle(this)
.showProgress(this)
.observeOnMainThread() // <== line 164
.subscribe({
LOG.info("Something list fetched ${it.size}")
adapter.setItems(it)
}, defaultOnError("Fetching something list failed"))
}
}
AnotherActivity.kt - uses the same functions as SomeActivity
and does not crash
class AnotherActivity : BaseActivity(), HasFullWindowProgress (...) {
(...)
private fun getData() {
somethingElse.user?.id?.let { id ->
apiClient.somethingElseList()
.map { response -> response.toAnotherList(id) }
.lifecycle(this)
.showProgress(this)
.observeOnMainThread()
.subscribe({
onNewSomethingElseList(id, it)
}, defaultOnError("Fetching somethingElseList for somethingElse failed"))
}
}
}
ActivityErrorHandlingExtensions.kt
fun <T> T.defaultOnError(message: String, vararg args: Any?): (Throwable) -> Unit where T : HasErrorHandler, T : Activity {
val targetClass = javaClass
val activity = this
return { err ->
val messageFormats = (args.toList() + err).toTypedArray()
LoggerFactory.getLogger(targetClass).error(message, *messageFormats)
errorHandler.default(err, activity)
}
}
ObservableExtensions.kt
fun <T> Observable<T>.lifecycle(activity: RxAppCompatActivity) : Observable<T> {
return compose(activity.bindToLifecycle<T>())
}
fun <T> Observable<T>.observeOnMainThread() : Observable<T> {
return observeOn(AndroidSchedulers.mainThread())
}
Progress.kt
fun <T> Observable<T>.showProgress(hasProgress: HasFullWindowProgress): Observable<T> {
return compose {
it.doOnSubscribe {
MAIN_THREAD_WORKER.schedule {
hasProgress.fullWindowProgress.visibility = View.VISIBLE
}
}.doAfterTerminate {
MAIN_THREAD_WORKER.schedule {
hasProgress.fullWindowProgress.visibility = View.GONE
}
}
}
}
All this code was in the project for over a month or two and it was working on my PC two weeks ago.
What I have already tried:
./gradlew cleanBuildCache
deleted $HOME/.gradle/caches
deleted $HOME/.android/build-cache
deleted $HOME/.AndroidStudio2.3/system/caches
deleted build
and app/build
dirs
deleted .gradle
dir in the projects root directory
Android Studio invalidate caches and restart
uninstalling the app from the emulator manually and installing it again
Reinstalling Android Studio 2.3.1
Downgraded Android Studio to 2.3 (that's the version I used 2 weeks ago and I know it worked then)
Any ideas what's wrong here?
Kotlin bytecode of the getDataFor
method:
private final getDataFor(Ljava/lang/String;)V
L0
LINENUMBER 160 L0
L1
LINENUMBER 165 L1
L2
LINENUMBER 160 L2
L3
LINENUMBER 164 L3
L4
LINENUMBER 160 L4
L5
LINENUMBER 163 L5
L6
LINENUMBER 160 L6
L7
LINENUMBER 162 L7
L8
LINENUMBER 160 L8
L9
LINENUMBER 161 L9
L10
LINENUMBER 160 L10
ALOAD 0
GETFIELD com/project/package/SomeActivity.apiClient : Lcom/project/network/ApiClient;
DUP
IFNONNULL L11
LDC "apiClient"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.throwUninitializedPropertyAccessException (Ljava/lang/String;)V
L11
ALOAD 1
INVOKEVIRTUAL com/project/network/ApiClient.somethingList (Ljava/lang/String;)Lrx/Observable;
GETSTATIC com/project/package/SomeActivity$getDataFor$1.INSTANCE : Lcom/project/package/SomeActivity$getDataFor$1;
CHECKCAST rx/functions/Func1
L12
LINENUMBER 161 L12
INVOKEVIRTUAL rx/Observable.map (Lrx/functions/Func1;)Lrx/Observable;
ALOAD 0
CHECKCAST com/trello/rxlifecycle/components/support/RxAppCompatActivity
L13
LINENUMBER 162 L13
INVOKESTATIC com/project/extensions/ObservableExtensionsKt.lifecycle (Lrx/Observable;Lcom/trello/rxlifecycle/components/support/RxAppCompatActivity;)Lrx/Observable;
ALOAD 0
CHECKCAST com/project/widgets/HasFullWindowProgress
L14
LINENUMBER 163 L14
INVOKESTATIC com/project/widgets/ProgressKt.showProgress (Lrx/Observable;Lcom/project/widgets/HasFullWindowProgress;)Lrx/Observable;
L15
LINENUMBER 164 L15
INVOKESTATIC com/project/extensions/ObservableExtensionsKt.observeOnMainThread (Lrx/Observable;)Lrx/Observable;
NEW com/project/package/SomeActivity$getDataFor$2
DUP
ALOAD 0
INVOKESPECIAL com/project/package/SomeActivity$getDataFor$2.<init> (Lcom/project/package/SomeActivity;)V
CHECKCAST rx/functions/Action1
NEW com/project/package/SomeActivityKt$sam$Action1$22181393
DUP
ALOAD 0
LDC "Fetching something list failed"
ICONST_0
ANEWARRAY java/lang/Object
INVOKESTATIC com/project/extensions/ActivityErrorHandlingExtensionsKt.defaultOnError (Landroid/app/Activity;Ljava/lang/String;[Ljava/lang/Object;)Lkotlin/jvm/functions/Function1;
DUP
IFNONNULL L16
POP
POP2
ACONST_NULL
GOTO L17
L16
INVOKESPECIAL com/project/package/SomeActivityKt$sam$Action1$22181393.<init> (Lkotlin/jvm/functions/Function1;)V
L17
CHECKCAST rx/functions/Action1
L18
LINENUMBER 165 L18
INVOKEVIRTUAL rx/Observable.subscribe (Lrx/functions/Action1;Lrx/functions/Action1;)Lrx/Subscription;
POP
L19
LINENUMBER 170 L19
RETURN
L20
LOCALVARIABLE this Lcom/project/package/SomeActivity; L0 L20 0
LOCALVARIABLE id Ljava/lang/String; L0 L20 1
MAXSTACK = 7
MAXLOCALS = 2
Upvotes: 3
Views: 1104
Reputation: 3681
I ran into a similar problem few weeks ago. Here is basically what I did to avoid the ClassNotFoundException
, in my case was due to the Multidex "configuration" after updating Android Studio, gradle, etc.
compile 'com.android.support:multidex:1.0.1'
to the dependencies list in your app gradle file.Remove Multidex.install(this);
from the onCreate()
method of your Application class and add the following in your Application class:
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(context);
MultiDex.install(this);
}
I got the error after updating the gradle version, etc., so make sure you have everything up to date as well.
Hope it helps.
Upvotes: 1