Proguard for Wire + Retrofit NoSuchMethodException

660 Views Asked by At

My brain is fried. I searched S.O. for help but it seems Proguard issues with this exception are specific to the app in question. I've been trying to use Proguard to obfucate/minify my app and when I run it in the Generated APK form my app either crashes or hits me with:

com.company.project E/a: java.lang.NoSuchMethodException: fromValue [int]

Stacktrace:

java.lang.AssertionError: java.lang.NoSuchMethodException: fromValue [int]
     at com.squareup.wire.RuntimeEnumAdapter.decode(Unknown Source)
     at com.squareup.wire.RuntimeEnumAdapter.getFromValueMethod(Unknown Source)
     at com.squareup.wire.RuntimeEnumAdapter.decode(Unknown Source)
     at com.company.project.utils.wiremodels.d.a(Unknown Source)
     at com.company.project.utils.wiremodels.d.decode(Unknown Source)
     at com.company.project.utils.wiremodels.g.a(Unknown Source)
     at com.company.project.utils.wiremodels.g.decode(Unknown Source)
     at com.squareup.wire.ProtoAdapter.decode(Unknown Source)
     at retrofit2.converter.wire.WireResponseBodyConverter.convert(Unknown Source)
     at retrofit2.converter.wire.WireResponseBodyConverter.convert(Unknown Source)
     at retrofit2.ServiceMethod.toResponse(Unknown Source)
     at retrofit2.OkHttpCall.parseResponse(Unknown Source)
     at retrofit2.OkHttpCall$1.onResponse(Unknown Source)
     at a.az.b(Unknown Source)
     at a.a.l.run(Unknown Source)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
     at java.lang.Thread.run(Thread.java:818)
 Caused by: java.lang.NoSuchMethodException: fromValue [int]
     at java.lang.Class.getMethod(Class.java:624)
     at java.lang.Class.getMethod(Class.java:603)
    ... 18 more

My app uses Retrofit (2.1.0) and Wire, both from Square. Then when my app crashes I'm checking the mapping.txt file to see what class is causing the issue (I believe it's com.company.project.a, right?)

Anyway here's my proguard file (with obscure class names fyi):

-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keep class com.squareup.wire.** { *; }
-keep class com.company.project.utils.wiremodels.ProtoFile1 { *; }
-keep class com.company.project.utils.wiremodels.ProtoFile2 { *; }
-keep class com.company.project.utils.wiremodels.ProtoFile3 { *; }
-keep class com.company.project.utils.wiremodels.ProtoFile4 { *; }
-keep class com.company.project.utils.wiremodels.ProtoFile5 { *; }
-dontwarn com.google.**
-keepattributes Signature
-keepattributes *Annotation*
-keepattributes Exceptions
-dontwarn org.w3c.dom.bootstrap.DOMImplementationRegistry
-dontwarn org.simpleframework.xml.stream.**

It would be amazing if I can get some help with this, please let me know if there's more info I should provide.

EDIT: Question answered in the comments of marked answer (for future references)

1

There are 1 best solutions below

5
On BEST ANSWER

You can keep methods in some classes with :

-keepclassmembers,allowobfuscation class com.company.project.yourClass.** {
    <methods>;
}

As you are using wire, form these indications proguard recommended is :

-keep class com.squareup.wire.** { *; }
-keep class com.yourcompany.yourgeneratedcode.** { *; }

If the problem is coming from retrofit here is a proguard example :

-keep class com.squareup.okhttp.** { *; }
-keep class retrofit.** { *; }
-keep interface com.squareup.okhttp.** { *; }

-dontwarn com.squareup.okhttp.**
-dontwarn okio.**
-dontwarn retrofit.**
-dontwarn rx.**

-keepclasseswithmembers class * {
    @retrofit.http.* <methods>;
}

# If in your rest service interface you use methods with Callback argument.
-keepattributes Exceptions

# If your rest service methods throw custom exceptions, because you've defined an ErrorHandler.
-keepattributes Signature