-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Insufficient keep rules for R8 in full mode #3005
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Can the use of a |
R8 does not have any interprocedural tracking of class literals at this point. Even with such tracking, the keep rules would still be insufficient depending on the program. It should be possible to keep the relevant interfaces if they are used by the program with a rule inspired by the following one.
|
I guess that's not that terrible because the methods can still be removed. You might wind up with an empty interface or two if you have unused ones coming from libraries. |
I've got another full mode problem. R8 replaces interfaces used as return types in service interface methods with a subtype which then breaks reflective lookup. Is there a way to issue a |
You should be able to use the following rule:
This is assuming that the return type is an interface. If the return type could also be a class or enum type, then the following rules are unfortunately also needed:
It would be easy to extend the grammar a bit, though. I am considering if this rule should not be written as:
This rule should then suffice to handle the cases where the return type is an array, class, enum, and interface. This would no longer be compatible with Proguard, though. |
The duplication is okay since Retrofit is the only one that needs to ship those rules. But I can't get those rules to actually work. I tried with just Here's my input: @GET("_s/getsuggestions?p=/&s=irina&c=3")
fun list(): Deferred<Map<String, List<Item>>> However, upon more investigation as to what's happening, R8 is performing vertical class merging of the
When using reflection on the parameterized return type, this annotation is checked for the type which is then loaded.
This seems like an R8 bug, right? It should be updating the signature annotation when it changes the types. |
Have you tried with a recent version of R8, e.g., 'com.android.tools:r8:1.4.39'? I verified that a variant of the rule worked on a small test. If it doesn't work with 1.4.39, I will try to create a small repro that uses Retrofit. (You may also try to add the rule
It is. Would you mind filing an issue on the R8 bug tracker? |
I'm stuck on AGP 3.3.x for unrelated reasons which I'm guessing uses R8 1.3.x. I'll try with the latest R8. |
I couldn't get far enough to build a repro because there appears to be a regression in |
...and unblocked again. Back working on it. |
I can't get it to reproduce in a small project. I have filed https://issuetracker.google.com/issues/124357885 with a link to a branch of this project using AGP 3.5.0-alpha03 which reproduces the issue reliably though. |
Fixed upstream 🎉 |
Reason: When we moved to Android Gradle Plugin(AGP) 3.4.0, it switched from using Proguard for minification to R8. There were a couple of compatibility issues with Moshi, Retrofit, and R8 (links to GitHub issues below) which caused: 1. Values of enum fields to be removed from JsonAdapters 2. Breaking of JSON parsing where an interface is implemented by multiple response types (See DataPullResponse and its class hierarchy) to all enums, but #2 is an invasive change since that will require us to change how our sync works. In addition, the Sentry gradle plugin that we were using was incompatible with AGP 3.4.0 (or rather, Gradle 5.+ which AGP 3.4.0 requires). Changes: - Disable R8 for now and raise an issue on the Moshi repository regd how to make it work with R8. - Update the Sentry plugin to the latest version See square/retrofit#3005
Reason: When we moved to Android Gradle Plugin(AGP) 3.4.0, it switched from using Proguard for minification to R8. There were a couple of compatibility issues with Moshi, Retrofit, and R8 (links to GitHub issues below) which caused: 1. Values of enum fields to be removed from JsonAdapters 2. Breaking of JSON parsing where an interface is implemented by multiple response types (See DataPullResponse and its class hierarchy) to all enums, but #2 is an invasive change since that will require us to change how our sync works. In addition, the Sentry gradle plugin that we were using was incompatible with AGP 3.4.0 (or rather, Gradle 5.+ which AGP 3.4.0 requires). Changes: - Disable R8 for now and raise an issue on the Moshi repository regd how to make it work with R8. - Update the Sentry plugin to the latest version See square/retrofit#3005
Reason: When we moved to Android Gradle Plugin(AGP) 3.4.0, it switched from using Proguard for minification to R8. There were a couple of compatibility issues with Moshi, Retrofit, and R8 (links to GitHub issues below) which caused: 1. Values of enum fields to be removed from JsonAdapters 2. Breaking of JSON parsing where an interface is implemented by multiple response types (See DataPullResponse and its class hierarchy) Problem #1 is easy to fix by adding "@JsonClass(generateAdapter=true)" to all enums, but #2 is an invasive change since that will require us to change how our sync works. In addition, the Sentry gradle plugin that we were using was incompatible with AGP 3.4.0 (or rather, Gradle 5.+ which AGP 3.4.0 requires). Changes: - Disable R8 for now and raise an issue on the Moshi repository regd how to make it work with R8. - Update the Sentry plugin to the latest version See square/retrofit#3005
Reason: When we moved to Android Gradle Plugin(AGP) 3.4.0, it switched from using Proguard for minification to R8. There were a couple of compatibility issues with Moshi, Retrofit, and R8 (links to GitHub issues below) which caused: 1. Values of enum fields were being removed from JsonAdapters 2. Breaking of JSON parsing where an interface is implemented by multiple response types (See DataPullResponse and its class hierarchy) Problem #1 is easy to fix by adding "@JsonClass(generateAdapter=false)" to all enums, but #2 is an invasive change since that will require us to change how our sync works. In addition, the Sentry gradle plugin that we were using was incompatible with AGP 3.4.0 (or rather, Gradle 5.+ which AGP 3.4.0 requires). Changes: - Disable R8 for now and raise an issue on the Moshi repository regd how to make it work with R8. - Update the Sentry plugin to the latest version See square/retrofit#3005
Reason: When we moved to Android Gradle Plugin(AGP) 3.4.0, it switched from using Proguard for minification to R8. There were a couple of compatibility issues with Moshi, Retrofit, and R8 (links to GitHub issues below) which caused: 1. Values of enum fields were being removed from JsonAdapters 2. Breaking of JSON parsing where an interface is implemented by multiple response types (See DataPullResponse and its class hierarchy) Problem #1 is easy to fix by adding "@JsonClass(generateAdapter=false)" to all enums, but #2 is an invasive change since that will require us to change how our sync works. In addition, the Sentry gradle plugin that we were using was incompatible with AGP 3.4.0 (or rather, Gradle 5.+ which AGP 3.4.0 requires). Changes: - Disable R8 for now and raise an issue on the Moshi repository regd how to make it work with R8. - Update the Sentry plugin to the latest version See square/retrofit#3005
Hi @JakeWharton , I've just updated to gradle 8 and I'm getting this error when using R8 in full mode
That happen in every call the app trying to do, when R8 full mode is disabled it's working well. |
I'm likewise seeing this become a problem again after I've updated to gradle 8 (I'm on the latest retrofit version v2.9.0). In my case the exception reads:
If I disable full mode everything works as expected. Revisiting the workaround suggested for the original manifestation of this bug works, ie if I add the following rule everything works as expected even in full model:
UPDATE: adding the "Call" rule added in this comit likewise resolves the problem.
It seems said commit has yet to be released. |
Now, when R8 full mode is officially available for everyone, a new version of RetroFit that fix could be really released. |
The keep rules in https://github.com/square/retrofit/blob/master/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro are insufficient for R8 in full mode.
See for example https://issuetracker.google.com/issues/120168590#comment3 and https://issuetracker.google.com/issues/122940365#comment9.
As a simple example, consider the 'SimpleService' sample:
https://github.com/square/retrofit/blob/master/samples/src/main/java/com/example/retrofit/SimpleService.java
The interface 'GitHub' is never instantiated in the code (except via reflection), and it is not explicitly kept by a keep rule, so R8 can safely replace all values in the program that have type 'GitHub' with constant null.
The text was updated successfully, but these errors were encountered: