Description:
We are experiencing a critical crash in our release builds when using the Datatrans Android SDK (version 3.10.0). The crash occurs during the payment flow, specifically leading to an AuthenticationException which is then followed by a NullPointerException because essential methods in internal classes are being stripped by R8.
Environment:
- Datatrans Android SDK version: 3.10.0
- R8/ProGuard enabled: Yes
- Android Gradle Plugin: 9.1.0
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
Steps to Reproduce:
- Integrate Datatrans SDK 3.10.0.
- Build the app in release mode with R8 shrinking enabled.
- Start a payment transaction.
- The app crashes when the SDK attempts to access internal state.
Stacktrace:
1 ch.datatrans.payment.exception.AuthenticationException: Authentication Error
2 at ch.datatrans.payment.C7$$ExternalSyntheticLambda5.invoke(SourceFile:444)
3 at ch.datatrans.payment.O1$$ExternalSyntheticLambda2.onClick(SourceFile:272)
4 ...
5 Caused by: java.lang.NullPointerException
6 at ch.datatrans.payment.M2.e(Unknown Source:1)
7 at ch.datatrans.payment.E3$$ExternalSyntheticLambda0.invoke(SourceFile:39)
8 at ch.datatrans.payment.Eb.invokeSuspend(SourceFile:1893)
9 at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(SourceFile:8)
10 at kotlinx.coroutines.DispatchedTask.run(SourceFile:120)
Analysis:
Using proguard-removed.txt and -whyareyoukeeping class ch.datatrans.payment.M2 { void e(); }, we identified that while the class ch.datatrans.payment.M2 is kept, R8 is aggressively stripping its methods because it doesn't detect direct usage. Specifically, the method e() in ch.datatrans.payment.M2 is removed:
Nothing is keeping void ch.datatrans.payment.M2.e()
This leads to a NullPointerException when the SDK's internal coroutines or lambdas try to access this method at runtime. It seems the SDK relies on reflection that isn't fully covered by the current consumer ProGuard rules.
Current Workaround:
We had to add the following broad rule to our proguard-rules.pro to stop the crashes:
keep class ch.datatrans.payment.** { *; }
Expected Behavior:
The SDK should provide comprehensive consumer ProGuard rules to ensure that its internal orchestration logic and data models (especially those accessed via reflection/lambdas) are not stripped or broken by R8.
Description:
We are experiencing a critical crash in our release builds when using the Datatrans Android SDK (version 3.10.0). The crash occurs during the payment flow, specifically leading to an AuthenticationException which is then followed by a NullPointerException because essential methods in internal classes are being stripped by R8.
Environment:
Steps to Reproduce:
Stacktrace:
10 at kotlinx.coroutines.DispatchedTask.run(SourceFile:120)
Analysis:
Using proguard-removed.txt and
-whyareyoukeeping class ch.datatrans.payment.M2 { void e(); }, we identified that while the class ch.datatrans.payment.M2 is kept, R8 is aggressively stripping its methods because it doesn't detect direct usage. Specifically, the method e() in ch.datatrans.payment.M2 is removed:This leads to a NullPointerException when the SDK's internal coroutines or lambdas try to access this method at runtime. It seems the SDK relies on reflection that isn't fully covered by the current consumer ProGuard rules.
Current Workaround:
We had to add the following broad rule to our proguard-rules.pro to stop the crashes:
Expected Behavior:
The SDK should provide comprehensive consumer ProGuard rules to ensure that its internal orchestration logic and data models (especially those accessed via reflection/lambdas) are not stripped or broken by R8.