-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Add ProGuard / R8 integration tests & add default ProGuard rules #2397
Add ProGuard / R8 integration tests & add default ProGuard rules #2397
Conversation
They are automatically applied for all users of Gson, see https://developer.android.com/build/shrink-code#configuration-files
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Maven build currently produces the following warning for the shrinker-test
module:
Warning: Missing POM for com.android.tools:r8:jar:8.0.40
I haven't really figured out why that is the case; the artifact seems to have a POM file. Even adding the Google Maven repository (containing R8) as regular repository in the shrinker-test pom.xml
does not seem to have solved this. But I guess the warning can be ignored.
Also R8 logs the following:
Proguard configuration rule does not match anything: `-keep class * implements com.google.gson.JsonSerializer { <init>(); }`
(same also for JsonDeserializer
)
I guess these can be ignored since the shrinker-test project simply does not have a test for JsonSerializer
and JsonDeserializer
at the moment. I am a bit surprised though that R8 logs this for a library rules file (gson.pro
) in the first place; maybe that is an issue with R8?
Edit: Have adjusted the tests to also cover JsonSerializer
and JsonDeserializer
so now the warnings above are not shown anymore for the tests. They might still occur for users, but they should be safe to ignore I guess.
Also note that this new shrinker-test module causes the build for the complete Maven project to take a bit longer but I hope that is acceptable for the advantages it (hopefully) provides.
public static <T> T same(T t) { | ||
// This is essentially `return t`, but contains some redundant code to try | ||
// prevent the code shrinkers from simplifying this | ||
return Optional.of(t) | ||
.map(v -> Optional.of(v).get()) | ||
.orElseThrow(() -> new AssertionError("unreachable")); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not completely sure if this is actually needed, but for now I just kept it to be safe. I think removing the static toJson
and fromJson
methods (and implicitly the same(...)
calls) from Main
made a difference; but I am not completely sure anymore.
@@ -83,7 +84,12 @@ | |||
<groupId>junit</groupId> | |||
<artifactId>junit</artifactId> | |||
<version>4.13.2</version> | |||
<scope>test</scope> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this here from the <dependencyManagement>
because specifying the scope there seems to be discouraged, see https://stackoverflow.com/q/15221299
All the modules of this project using JUnit as test dependency already set the scope anyways apparently
@christofferqa, I hope it is ok to ask you, since you suggested some improvements to the existing ProGuard rules file in the past (#1930), does the Also, slightly off-topic, but to what extent does R8 support the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks very much for doing this!
Like you I am not hugely familiar with ProGuard and R8, so I'll give @christofferqa a chance to weigh in before I merge it.
I have extended the tests a bit more and added a new section to the troubleshooting guide. But I think this pull request is ready now. As disclaimer: The code shrinking tests are a bit brittle, so if they fail in the future when adjusting the default Gson ProGuard rules or when upgrading the ProGuard or R8 version used by the test, it might be necessary to rewrite them or maybe even remove some of them if rewriting them is not easily possible. |
OK, if this is ready for merging then I'll merge it. :-) We can always adjust later. |
@Marcono1234 It is fine to add only There has not been much work on supporting Regarding the rules added by this CL, there are a few issues that would be good to address:
|
I agree with @christofferqa on the comments above. For the rules for Finally is |
* Add code shrinking tools integration test * Keep no-args constructor of classes usable with JsonAdapter * Add library ProGuard rules for Gson They are automatically applied for all users of Gson, see https://developer.android.com/build/shrink-code#configuration-files * Skip japicmp-maven-plugin for shrinker-test * Add more tests for JsonAdapter, add tests for generic classes * Extend default constructor test * Add Troubleshooting Guide entry for TypeToken
Thanks to you both for your answers!
It appears
I assume you mean the following:
Yes looks like
So the following rule from https://issuetracker.google.com/issues/150189783#comment11 should then also solve the issues with the constructors, right?
Or is explicitly specifying And to clarify, what is the purpose of the
I would also prefer explicitly matching only Gson annotations instead, but restricting this only to specific annotation types is apparently not possible for
Yes I guess that makes sense. Except for
If I remove it then the integration test fails because R8 seems to remove the annotation here:
gson/shrinker-test/src/main/java/com/example/GenericClasses.java Lines 41 to 42 in 2d7cc2e
I can try using this 'magic' I will try to create a pull request then which addresses this and the other points I wrote down in #2401. |
@christofferqa and @sgjesse, I have created #2420 as follow-up. If you have the time, could you please have a look at my comment above and the ProGuard rule changes in that pull request and see if they are reasonable? |
Thank you for working on this! I have added a few comments in #2420, but it looks good, and great to have the right rules be part of the GSON library! |
…gle#2397) * Add code shrinking tools integration test * Keep no-args constructor of classes usable with JsonAdapter * Add library ProGuard rules for Gson They are automatically applied for all users of Gson, see https://developer.android.com/build/shrink-code#configuration-files * Skip japicmp-maven-plugin for shrinker-test * Add more tests for JsonAdapter, add tests for generic classes * Extend default constructor test * Add Troubleshooting Guide entry for TypeToken
Purpose
Adds integration tests using ProGuard and R8 with Gson, and adds default ProGuard rules as
META-INF/proguard/gson.pro
, see also https://developer.android.com/build/shrink-code#configuration-filesResolves #1945
Supersedes #1929
Description
Adds a new
shrinker-test
Maven module which has both ProGuard and R8 configured to process a JAR file and then run integration tests on the JAR. These tests are (hopefully) more extensive than the the existingEnumWithObfuscatedTest
(I have still kept it though).Additionally the file
META-INF/proguard/gson.pro
is added which contains common ProGuard and R8 rules relevant for all users. This file is recognized by R8 (see https://developer.android.com/build/shrink-code#configuration-files) and apparently also by the ProGuard Android plugin (haven't verified this myself yet).However, for user specific code (such as model classes) it might still be necessary that the users specify additional custom rules themselves, such as disabling obfuscation for specific fields.
This pull request also adds a new troubleshooting entry for the "Abstract classes can't be instantiated!" exception which recently occurred pretty frequently (see #2379) due to R8 "full mode" being enabled by default. The integration test covers a case where that exception is thrown as well.
gson.pro
instead of 4. I hope that this should work fine nonetheless for recent R8 versions (integration test aims to verify this) and for ProGuard (automatic detection not checked by integration test due to Guardsquare/proguard#337).I am however not that familiar with ProGuard and R8, so I might have overlooked or failed to consider something. Any feedback is appreciated.
Checklist
null
@since $next-version$
(
$next-version$
is a special placeholder which is automatically replaced during release)TestCase
)mvn clean verify javadoc:jar
passes without errors