AdaptySDK-React-Native icon indicating copy to clipboard operation
AdaptySDK-React-Native copied to clipboard

TypeToken must be created with a type argument: new TypeToken<...>() {}; When using code shrinkers (ProGuard, R8, ...) make sure that generic signatures are preserved.

Open SergiOnGit opened this issue 10 months ago • 17 comments

Description

App crashes on production and firebase logs this error:

Fatal Exception: java.lang.IllegalStateException: TypeToken must be created with a type argument: new TypeToken<...>() {}; When using code shrinkers (ProGuard, R8, ...) make sure that generic signatures are preserved. at com.google.gson.reflect.TypeToken.getTypeTokenTypeArgument(TypeToken.java:100) at com.google.gson.reflect.TypeToken.<init>(TypeToken.java:70) at com.adapty.internal.di.Dependencies$init$1$1.<init>(Dependencies.kt:137) at com.adapty.internal.di.Dependencies$init$1.invoke(Dependencies.kt:137) at com.adapty.internal.di.Dependencies$init$1.invoke(Dependencies.kt:56) at com.adapty.internal.di.DIObject.provide(DIObject.kt:19) at com.adapty.internal.di.Dependencies.injectInternal$default(Dependencies.java:35) at com.adapty.internal.di.Dependencies$init$17.invoke(Dependencies.kt:287) at com.adapty.internal.di.Dependencies$init$17.invoke(Dependencies.kt:286) at com.adapty.internal.di.DIObject.provide(DIObject.kt:19) at com.adapty.internal.di.Dependencies.injectInternal$default(Dependencies.java:35) at com.adapty.internal.di.Dependencies$init$15.invoke(Dependencies.kt:272) at com.adapty.internal.di.Dependencies$init$15.invoke(Dependencies.kt:270) at com.adapty.internal.di.DIObject.provide(DIObject.kt:19) at com.adapty.internal.di.Dependencies.injectInternal$default(Dependencies.java:35) at com.adapty.internal.di.Dependencies$init$7.invoke(Dependencies.kt:217) at com.adapty.internal.di.Dependencies$init$7.invoke(Dependencies.kt:214) at com.adapty.internal.di.DIObject.provide(DIObject.kt:19) at com.adapty.internal.di.Dependencies.injectInternal$default(Dependencies.java:35) at com.adapty.internal.di.Dependencies$init$5.invoke(Dependencies.kt:200) at com.adapty.internal.di.Dependencies$init$5.invoke(Dependencies.kt:198) at com.adapty.internal.di.DIObject.provide(DIObject.kt:19) at com.adapty.internal.di.Dependencies.injectInternal$default(Dependencies.java:35) at com.adapty.internal.di.Dependencies$init$47.invoke(Dependencies.kt:446) at com.adapty.internal.di.Dependencies$init$47.invoke(Dependencies.kt:444) at com.adapty.internal.di.DIObject.provide(DIObject.kt:19) at com.adapty.internal.di.Dependencies.injectInternal$default(Dependencies.java:35) at com.adapty.internal.di.Dependencies$init$48.invoke(Dependencies.kt:458) at com.adapty.internal.di.Dependencies$init$48.invoke(Dependencies.kt:456) at com.adapty.internal.di.DIObject.provide(DIObject.kt:19) at com.adapty.internal.di.Dependencies.injectInternal$default(Dependencies.java:35) at com.adapty.Adapty$special$$inlined$inject$adapty_release$default$1.invoke(Dependencies.kt:31) at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81) at com.adapty.Adapty.<clinit>(Adapty.kt:500) at com.adapty.Adapty.getAdaptyInternal(Adapty.kt:500) at com.adapty.Adapty.init(Adapty.kt:520) at com.adapty.Adapty.activate(Adapty.kt:64) at com.adapty.react.AdaptyCallHandler.handleActivate$lambda$1(AdaptyCallHandler.kt:64) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7680) at java.lang.reflect.Method.invokeNative(Method.java) at java.lang.reflect.Method.invoke(Method.java:423) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

At first, I could even build in production mode, I tried playing with proguard rules but no luck, then installed @adapty/react-native-ui lib and build went soccessfully, It is really bad that we have to install @adapty/react-native-ui even if we don't use it. Also docs doesn't say anything about it. After this I tried to open app, but crashed at startup.

Version

v2.10.0

What platforms are you seeing the problem on?

Android

System info

System:
  OS: macOS 14.4.1
  CPU: (11) arm64 Apple M3 Pro
  Memory: 102.56 MB / 18.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.11.0
    path: ~/.nvm/versions/node/v20.11.0/bin/node
  Yarn:
    version: 1.22.21
    path: ~/.nvm/versions/node/v20.11.0/bin/yarn
  npm:
    version: 10.2.4
    path: ~/.nvm/versions/node/v20.11.0/bin/npm
  Watchman:
    version: 2024.01.22.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /Users/warlock/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.4
      - iOS 17.4
      - macOS 14.4
      - tvOS 17.4
      - visionOS 1.1
      - watchOS 10.4
  Android SDK:
    API Levels:
      - "33"
      - "34"
    Build Tools:
      - 30.0.3
      - 33.0.0
      - 33.0.1
      - 34.0.0
    System Images:
      - android-33 | Google APIs ARM 64 v8a
      - android-34 | Google APIs ARM 64 v8a
      - android-34 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2023.1 AI-231.9392.1.2311.11330709
  Xcode:
    version: 15.3/15E204a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.10
    path: /usr/bin/javac
  Ruby:
    version: 2.7.6
    path: /Users/warlock/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.6
    wanted: 0.73.6
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

SergiOnGit avatar Apr 10 '24 20:04 SergiOnGit

hi @SergiOnGit!

It is really bad that we have to install @adapty/react-native-ui even if we don't use it

No, you don't have to.

vladd-g avatar Apr 10 '24 23:04 vladd-g

@SergiOnGit what rules do you currently have in the proguard config?

vladd-g avatar Apr 10 '24 23:04 vladd-g

@vladd-g I had -keep class com.adapty.** { *; } in proguard, Then I removed it and fixed with android.enableR8.fullMode=false in gradle.properties. But what is correct solution? I don't want to have ui lib installed. Also you don't mention anything in docs about proguard. Guide me please.

SergiOnGit avatar Apr 11 '24 07:04 SergiOnGit

@SergiOnGit

Then I removed it and fixed with android.enableR8.fullMode=false

Do you mean it works well now?

I don't want to have ui lib installed

You can simply remove the @adapty/react-native-ui dependency if you don't use the Paywall Builder feature

I don't want to have ui lib installed. Also you don't mention anything in docs about proguard.

Actually, only -keep class com.adapty.** { *; } is sufficient in most cases. If disabling full mode prevented obfuscation-related crashes, that's okay too. We'll check and add all the necessary info to the docs if anything is missing. Thank you!

vladd-g avatar Apr 11 '24 08:04 vladd-g

Yes it works now. So I can remove ui module and should add -keep class com.adapty.** { *; } rule to proguard. And should leave full mode disabled right? Would be great if you add all the necessary info in docs. Also cases where app may still crash with possible fix.

SergiOnGit avatar Apr 11 '24 08:04 SergiOnGit

Yes it works now. So I can remove ui module and should add -keep class com.adapty.** { *; } rule to proguard. And should leave full mode disabled right?

If everything works fine, why not

vladd-g avatar Apr 11 '24 08:04 vladd-g

@vladd-g I added -keep class com.adapty.** { *; } and removed ui lib. Also leave full mode disabled and now build fails. See the log:

ERROR: Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in /Users/warlock/Desktop/Mobile/movebody/android/app/build/outputs/mapping/release/missing_rules.txt. ERROR: R8: Missing class com.adapty.ui.AdaptyUI$Action$Close (referenced from: void com.adapty.internal.crossplatform.AdaptyUIActionTypeAdapterFactory$create$result$1.write(com.google.gson.stream.JsonWriter, com.adapty.ui.AdaptyUI$Action)) Missing class com.adapty.ui.AdaptyUI$Action$Custom (referenced from: void com.adapty.internal.crossplatform.AdaptyUIActionTypeAdapterFactory$create$result$1.write(com.google.gson.stream.JsonWriter, com.adapty.ui.AdaptyUI$Action)) Missing class com.adapty.ui.AdaptyUI$Action$OpenUrl (referenced from: void com.adapty.internal.crossplatform.AdaptyUIActionTypeAdapterFactory$create$result$1.write(com.google.gson.stream.JsonWriter, com.adapty.ui.AdaptyUI$Action)) Missing class com.adapty.ui.AdaptyUI$Action (referenced from: com.adapty.ui.AdaptyUI$Action com.adapty.internal.crossplatform.AdaptyUIActionTypeAdapterFactory$create$result$1.read(com.google.gson.stream.JsonReader) and 3 other contexts)

SergiOnGit avatar Apr 11 '24 10:04 SergiOnGit

@SergiOnGit please try adding -dontwarn com.adapty.ui.** to the proguard rules

vladd-g avatar Apr 11 '24 11:04 vladd-g

-dontwarn com.adapty.ui.** made it work, But only after I removed -keep class com.adapty.** { *; }

Also, I know you have mentioned in docs to add multidex true but I removed it and it still works. Should I expect errors on some stage with disabled multidex?

SergiOnGit avatar Apr 11 '24 11:04 SergiOnGit

But only after I removed -keep class com.adapty.** { *; }

What was the error before you removed it?

Should I expect errors on some stage with disabled multidex?

If it compiled with success, you don't need it

Unlike obfuscation issues that can occur at runtime, so I'd try keeping -keep class com.adapty.** { *; }

vladd-g avatar Apr 11 '24 11:04 vladd-g

I managed to figure it out. This two rule together

-keep class com.adapty.** { *; } -dontwarn com.adapty.ui.**

Works when I removed android.enableR8.fullMode=false No matter if you enable multidex or not.

Also no need to install ui lib. Looks like, it just needed correct proguard rules. App builds and starts.

SergiOnGit avatar Apr 11 '24 13:04 SergiOnGit

Looks like I made a mistake, android.enableR8.fullMode=false is still needed, without it app startup ends with error:

Fatal Exception: java.lang.IllegalStateException: TypeToken must be created with a type argument: new TypeToken<...>() {}; When using code shrinkers (ProGuard, R8, ...) make sure that generic signatures are preserved. at com.google.gson.reflect.TypeToken.getTypeTokenTypeArgument(TypeToken.java:100) at com.google.gson.reflect.TypeToken.<init>(TypeToken.java:70)...

SergiOnGit avatar Apr 11 '24 17:04 SergiOnGit

This two rule together

-keep class com.adapty.** { *; } -dontwarn com.adapty.ui.**

Works when I removed android.enableR8.fullMode=false

What error did you see before removing android.enableR8.fullMode=false?

vladd-g avatar Apr 11 '24 18:04 vladd-g

This two rule together -keep class com.adapty.** { *; } -dontwarn com.adapty.ui.** Works when I removed android.enableR8.fullMode=false

What error did you see before removing android.enableR8.fullMode=false?

I don't clearly understand what you mean before removing, I I don't remove it, there is no error app works with this configs:

-keep class com.adapty.** { *; }
-dontwarn com.adapty.ui.**
android.enableR8.fullMode=false

But I noticed that disabling full mode increases app size dramatically, 21mb app download size is 56mb on play store. Can you fix it for full mode? Without it, app starts at startup with this log:

Fatal Exception: java.lang.IllegalStateException: TypeToken must be created with a type argument: new TypeToken<...>() {}; When using code shrinkers (ProGuard, R8, ...) make sure that generic signatures are preserved. at com.google.gson.reflect.TypeToken.getTypeTokenTypeArgument(TypeToken.java:100) at com.google.gson.reflect.TypeToken.<init>(TypeToken.java:70)...

Let me know if you need any additional info.

SergiOnGit avatar Apr 12 '24 07:04 SergiOnGit

Could you please try adding these rules? (If they are not sufficient for correct functioning, also add these)

vladd-g avatar Apr 12 '24 08:04 vladd-g

@vladd-g Checked. These rules made it work without disabling full mode

-keep class com.adapty.** { *; }
-dontwarn com.adapty.ui.**
-keepattributes Signature
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken

SergiOnGit avatar Apr 13 '24 11:04 SergiOnGit

@SergiOnGit, so now everything works fine?

vladd-g avatar Apr 21 '24 20:04 vladd-g

@vladd-g Sorry for late reply. Yes, everything works fine.

SergiOnGit avatar May 31 '24 19:05 SergiOnGit