Moshi: R8 triggers VerifyError on KitKat devices

Created on 1 Feb 2019  ·  9Comments  ·  Source: square/moshi

AGP 3.3.0
Kotlin 1.3.20
Moshi 1.8.0
minSdk 19

On KitKat devices I'm getting this runtime error on first retrofit call.

W/dalvikvm: DexOpt: method is in an interface
I/dalvikvm: Could not find method java.util.Map.getOrDefault, referenced from method com.squareup.moshi.kotlin.reflect.KotlinJsonAdapter$IndexedParameterMap.getOrDefault
W/dalvikvm: VFY: unable to resolve virtual method 50960: Ljava/util/Map;.getOrDefault (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
W/dalvikvm: VFY:  rejecting opcode 0x6f at 0x0000
W/dalvikvm: VFY:  rejected Lcom/squareup/moshi/kotlin/reflect/KotlinJsonAdapter$IndexedParameterMap;.getOrDefault (Lkotlin/reflect/KParameter;Ljava/lang/Object;)Ljava/lang/Object;
W/dalvikvm: Verifier rejected class Lcom/squareup/moshi/kotlin/reflect/KotlinJsonAdapter$IndexedParameterMap;

Even is i disable R8 and force latest proguard version to be used and android.proguard.enableRulesExtraction=false i get this compile error:

Failed to notify project evaluation listener.
  proguard.ConfigurationParser.parseClassSpecificationArguments()Lproguard/ClassSpecification;

Did i miss something?

Most helpful comment

Hey folks, as mentioned above this appears to be a Kotlin issue. Please pursue this in the linked ticket above

All 9 comments

As a workaround i've used LinkedHashMap instead of IndexedParameterMap (for KitKat)

Seems like a Kotlin bug. I don't know why its generating those bridge methods for getOrDefault in the classsfile.

@JakeWharton raised ticket. You can close this issue here.

@ZacSweers
Same problem here:
Android Studio version: 3.4
Kotlin version: 1.3.30
Moshi version: 1.7.0
minSdk : 19

io.reactivex.exceptions.UndeliverableException: java.lang.VerifyError: com/squareup/moshi/c/a/a$b
        at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
        at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:69)
        at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:841)
     Caused by: java.lang.VerifyError: com/squareup/moshi/c/a/a$b
        at com.squareup.moshi.c.a.a.a(KotlinJsonAdapter.kt:103)
        at com.squareup.moshi.p.a(JsonAdapter.java:137)
        at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:45)
        at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:27)
        at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:223)
        at retrofit2.OkHttpCall.execute(OkHttpCall.java:186)
        at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:45)
        at io.reactivex.Observable.subscribe(Observable.java:12030)
        at retrofit2.adapter.rxjava2.ResultObservable.subscribeActual(ResultObservable.java:34)
        at io.reactivex.Observable.subscribe(Observable.java:12030)
        at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
        at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:579)

I'm able to pass the error when I remove these line from proguard.role:

# Moshi - Retain generated JsonAdapters if annotated type is retained.
-if @com.squareup.moshi.JsonClass class *
-keep class <1>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*
-keep class <1>_<2>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*$*
-keep class <1>_<2>_<3>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*$*$*
-keep class <1>_<2>_<3>_<4>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*$*$*$*
-keep class <1>_<2>_<3>_<4>_<5>JsonAdapter {
    <init>(...);
    <fields>;
}
-if @com.squareup.moshi.JsonClass class **$*$*$*$*$*
-keep class <1>_<2>_<3>_<4>_<5>_<6>JsonAdapter {
    <init>(...);
    <fields>;
}

As a workaround i've used LinkedHashMap instead of IndexedParameterMap (for KitKat)

I encounter the same issue (suddenly) – could you help what do you mean by "using instead"? I thought this class is used somewhere internally 🤔

@bulatgaleev Would you please answer to the above question? 🙏

Any update on this bug?

Hey folks, as mentioned above this appears to be a Kotlin issue. Please pursue this in the linked ticket above

There is simple fix, please approve pull request:

https://github.com/square/moshi/pull/1168

Was this page helpful?
0 / 5 - 0 ratings