Status Update
Comments
ch...@google.com <ch...@google.com> #2
Thanks for the report. If the data class SocialImage is only instantiated by reflection (by gson), then a keep rule is needed to specify this. Otherwise R8 will treat the class as never being instantiated, and remove its constructor(s).
Could you please try to build with the following rule?
-if class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keep class <1> {
<init>();
}
[Deleted User] <[Deleted User]> #3
ap...@google.com <ap...@google.com> #4
Branch: master
commit d467a9607e261f062a9b7098f266bd2e68b454bd
Author: Christoffer Quist Adamsen <christofferqa@google.com>
Date: Tue Feb 25 15:10:24 2020
Also consider referenced fields in if rule evaluator
Bug: 150189783
Change-Id: If18800c138048a2e803589160f3cb645ea7f346f
M src/main/java/com/android/tools/r8/shaking/Enqueuer.java
M src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java
A src/test/java/com/android/tools/r8/shaking/ifrule/KeepClassesWithAnnotatedFieldsTest.java
[Deleted User] <[Deleted User]> #5
ch...@google.com <ch...@google.com> #6
The change in
If you would be able to share an Android Studio project where this reproduces that would be super helpful. Snippets of the relevant code might also suffice for us to reproduce the problem.
ch...@google.com <ch...@google.com> #7
For the record, I've managed to reproduce the problem.
[Deleted User] <[Deleted User]> #8
Just run it, and it crashes immediately inside MainActivity.
Though I've determined in the meantime that @Keep annotation on the data class fixes this issue.. So now I'm not sure if this is something you should fix, or something we should have inside R8 rules?
But anyways, can you at least give us a nice universal R8 rule, so we don't have to add @Keep annotation on every data class cause there can be many?
Thanks.
ap...@google.com <ap...@google.com> #9
Branch: master
commit 1ca3c03f19433af83693046fd946b781bb59af3d
Author: Christoffer Quist Adamsen <christofferqa@google.com>
Date: Wed Feb 26 10:15:19 2020
Reproduce Gson issue in Kotlin with full mode (in Java)
Change-Id: Id8a67428fc58277c8da34e5df0cd40e7716bd5cf
Bug: 150189783
A src/test/java/com/android/tools/r8/shaking/ifrule/KeepClassesWithAnnotatedFieldsReferencedFromGetterTest.java
M src/test/java/com/android/tools/r8/shaking/ifrule/KeepClassesWithAnnotatedFieldsTest.java
[Deleted User] <[Deleted User]> #10
ch...@google.com <ch...@google.com> #11
We've been analyzing the problem, and came to the conclusion that no fixes should be needed for this to work. Instead, you need the following slightly stronger rule with R8 in full mode:
-if class *
-keepclasseswithmembers class <1> {
<init>(...);
@com.google.gson.annotations.SerializedName <fields>;
}
I hope this solves your problem!
[Deleted User] <[Deleted User]> #12
ch...@google.com <ch...@google.com> #13
Yes, that will also do the trick. Note that @Keep will prevent the getters (and all other methods) on your data classes from being inlined (and thus removed). The rule in
I would suggest using the version of R8 that is bundled with AGP, at least if you update AGP regularly.
You can also build using a more recent version of R8 (e.g., 2.0.38, or even 2.1.8-dev) by making the following changes to build.gradle.
buildscript {
repositories {
maven {
url 'https://storage.googleapis.com/r8-releases/raw'
}
}
dependencies {
classpath 'com.android.tools:r8:2.0.38' // Must be before the Gradle Plugin for Android.
classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
}
}
However, this has the disadvantage that, if you update AGP, but forget to update R8, then you will be stuck on the old version of the compiler.
The R8 versions can be found from
[Deleted User] <[Deleted User]> #14
ap...@google.com <ap...@google.com> #15
Branch: master
commit b390592f7d5a190bd1fbe135f3e15f4889b67356
Author: Christoffer Quist Adamsen <christofferqa@google.com>
Date: Wed Feb 26 12:57:00 2020
Use a keepclasseswithmembers rule in Gson reproduction
Change-Id: I99d6abc7082907df62c5dacd6d5fddb22990be8a
Bug: 150189783
M src/test/java/com/android/tools/r8/shaking/ifrule/KeepClassesWithAnnotatedFieldsReferencedFromGetterTest.java
[Deleted User] <[Deleted User]> #16
[Deleted User] <[Deleted User]> #17
sg...@google.com <sg...@google.com> #18
When the --info
option is passed to AGP the version of R8 will be printed, e.g. for AGP 3.6.0 the follwing line will be printed:
Current version is: 1.6.67 (build 63035baeff4ab2f5079d99c54d86d9a4839c158c from go/r8bot (luci-r8-ci-xenial-7-83cg)).
To just rerun the R8 release task (to get that version number) the following command can be used:
./gradlew --info :app:cleanMinifyReleaseWithR8 :app:minifyReleaseWithR8
[Deleted User] <[Deleted User]> #19
ap...@google.com <ap...@google.com> #20
Branch: 2.0
commit 7e8955152326cf60d772eca65803326eff56eb02
Author: Christoffer Quist Adamsen <christofferqa@google.com>
Date: Thu Feb 27 08:16:56 2020
Version 2.0.39
Cherry pick: Mark types with dependent instance constructor as instantiated
CL:
Cherry pick: Also consider referenced fields in if rule evaluator
CL:
Bug: 150189783, 149729626, 147972078
Change-Id: I52855f85275708631a765f2c806cda7db82fd9d7
M src/main/java/com/android/tools/r8/Version.java
M src/main/java/com/android/tools/r8/shaking/Enqueuer.java
M src/main/java/com/android/tools/r8/shaking/IfRuleEvaluator.java
M src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
M src/test/java/com/android/tools/r8/TestShrinkerBuilder.java
M src/test/java/com/android/tools/r8/compatproguard/CompatKeepClassMemberNamesTestRunner.java
A src/test/java/com/android/tools/r8/shaking/annotations/B149729626.java
M src/test/java/com/android/tools/r8/shaking/ifrule/ConditionalKeepIfKeptTest.java
A src/test/java/com/android/tools/r8/shaking/ifrule/KeepClassesWithAnnotatedFieldsTest.java
ua...@gmail.com <ua...@gmail.com> #21
I have slight diff. error coming with AGP 8.0 and Android studio flamingo.
Using Retrofit with gson gives error related to Abstract class can't be initiated.
But i solved this error with
-if class *
-keepclasseswithmembers class <1> {
<init>(...);
@com.google.gson.annotations.SerializedName <fields>;
}
Description
W/System.err: java.lang.RuntimeException: Unable to invoke no-args constructor for class com.optima_apps.fkcz.models.SocialImage. Registering an InstanceCreator with Gson for this type may fix this problem.
W/System.err: at com.google.gson.internal.j.a(ConstructorConstructor.java:228)
W/System.err: at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$b.a(ReflectiveTypeAdapterFactory.java:212)
W/System.err: at com.google.gson.internal.bind.g.a(TypeAdapterRuntimeTypeWrapper.java:41)
W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$a.a(CollectionTypeAdapterFactory.java:82)
W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$a.a(CollectionTypeAdapterFactory.java:61)
W/System.err: at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$a.a(ReflectiveTypeAdapterFactory.java:131)
W/System.err: at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$b.a(ReflectiveTypeAdapterFactory.java:222)
W/System.err: at com.google.gson.r.a(Gson.java:932)
W/System.err: at com.google.gson.r.a(Gson.java:1003)
W/System.err: at com.optima_apps.fkcz.v.h.n.a(HomeFeedRequest.kt:31)
W/System.err: at com.optima_apps.fkcz.v.h.b.a(BaseRequest.java:106)
W/System.err: at l.p0.b(RealCall.java:203)
W/System.err: at l.c1.b.run(NamedRunnable.java:32)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:919)
W/System.err: Caused by: java.lang.UnsupportedOperationException: Abstract class can't be instantiated! Class name: com.optima_apps.fkcz.models.SocialImage
W/System.err: at com.google.gson.internal.m0.b(UnsafeAllocator.java:120)
W/System.err: at com.google.gson.internal.i0.a(UnsafeAllocator.java:49)
W/System.err: at com.google.gson.internal.j.a(ConstructorConstructor.java:225)
W/System.err: ... 15 more
The data class looks like this:
data class SocialImage(
@field:SerializedName("src") val src: String,
@field:SerializedName("width") val width: Int,
@field:SerializedName("height") val height: Int
)
I also mentioned that this doesn't happen with data classes which are also @Parcelized