Skip to content
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

Twint classname clash between Datatrans & Adyen #25

Open
jschmid opened this issue Jul 11, 2024 · 8 comments
Open

Twint classname clash between Datatrans & Adyen #25

jschmid opened this issue Jul 11, 2024 · 8 comments

Comments

@jschmid
Copy link

jschmid commented Jul 11, 2024

We are trying to include both Datatrans & Adyen SDKs, and name clashes prevent us to do so.

To Reproduce
Include ch.datatrans:android-sdk:3.6.1 and com.adyen.checkout:drop-in:5.6.0 in the same project.
Try to compile the project. You get an error:

Execution failed for task ':app:checkDebugDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
   > Duplicate class a.a found in modules android-sdk-3.6.1.aar -> android-sdk-3.6.1-runtime (ch.datatrans:android-sdk:3.6.1) and twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0)
     Duplicate class a.b found in modules android-sdk-3.6.1.aar -> android-sdk-3.6.1-runtime (ch.datatrans:android-sdk:3.6.1) and twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0)
     Duplicate class ch.twint.payment.sdk.Twint found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-7.0.0.aar -> twint-sdk-android-7.0.0-runtime (ch.twint.payment:twint-sdk-android:7.0.0)
     Duplicate class ch.twint.payment.sdk.TwintPayResult found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-7.0.0.aar -> twint-sdk-android-7.0.0-runtime (ch.twint.payment:twint-sdk-android:7.0.0)
     Duplicate class ch.twint.payment.sdk.exceptions.TwintCodeEmptyOrBlankException found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-7.0.0.aar -> twint-sdk-android-7.0.0-runtime (ch.twint.payment:twint-sdk-android:7.0.0)
     Duplicate class ch.twint.payment.sdk.exceptions.TwintException found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-7.0.0.aar -> twint-sdk-android-7.0.0-runtime (ch.twint.payment:twint-sdk-android:7.0.0)
     Duplicate class ch.twint.payment.sdk.exceptions.TwintMethodCalledBeforeOnCreateException found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-7.0.0.aar -> twint-sdk-android-7.0.0-runtime (ch.twint.payment:twint-sdk-android:7.0.0)
     Duplicate class ch.twint.payment.sdk.exceptions.TwintResultPendingException found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-7.0.0.aar -> twint-sdk-android-7.0.0-runtime (ch.twint.payment:twint-sdk-android:7.0.0)

Expected behavior

It is possible to include Datatrans & Adyen SDKs in the same project, and use Twint.

Additional context

I have a repro project that shows the issue: https://github.com/jschmid/AdyenDatatransClash
This is the default Android Studio project, with only the dependencies added.

If you take commit jschmid/AdyenDatatransClash@ae250c5, you will see that it does not compile.

A workaround is to exclude the Adyen Twint library: jschmid/AdyenDatatransClash@29b9085
Excluding the Twint SDK that your publish under your Jfrog does not work as you have other class name clashes jschmid/AdyenDatatransClash@e1e0169 This was reported here #22 but not acknowledged by Datatrans.

However this exclusion does not work for us as we want to use Twint on both platforms.


I went down the rabbit hole and found this:

  • twint-5.6.0.aar from Adyen bundles the Twint SDK (it seems, as we don't have access to the Twint SDK). There are classes with package name ch.twint.payment.sdk.
  • twint-sdk-android-7.0.0.aar from Datatrans also packages a similar Twint SDK. (Some classes are the same, some are different)

We kindly request that you find a way to not clash with Twint classes. If you are going to keep publishing the Twint SDK under your own Jfrog, one solution would be to repackage the SDK under your own package, using Proguard repackageclasses.

Similar request on Adyen: Adyen/adyen-android#1701

@luiscosta
Copy link
Collaborator

Hello @jschmid,

About the a.b classes, we will repackage our SDK in the next release.

About TWINT you should exclude ours or Adyen's, unless you want to use TWINT in both SDKs at same time.

The way you can exclude from us is very simple:

implementation("ch.datatrans:android-sdk:3.6.1") {
    exclude("ch.twint.payment", "twint-sdk-android")
}

Although, we advise you to exclude the oldest version, which in this case, is Adyen's.

@jschmid
Copy link
Author

jschmid commented Jul 15, 2024

Thanks @luiscosta for the reply.

We do want to use both SDKs as the same time, as we present a different PSP based on a remote configuration.

I don't think it's a good idea to exclude one or another Twint SDKs like that. We have no way to know if there are compatibility issues.
We also have no definitive way to know which one is the most recent. You mention that Datatrans publishes a more recent version of the SDK. Adyen contains a jar "TwintSdk-android-8.0.0.jar" in the SDK and Datatrans publishes an aar called "twint-sdk-android-7.0.0.aar". This is a guessing game really.

In the end Twint should publish a canonical library on their own Maven repository. But I guess everyone knows that already 🫠

@jschmid
Copy link
Author

jschmid commented Jul 16, 2024

I'm going on vacation. Handing over the topic to my colleague @gtomek.

@bacherma
Copy link

@jschmid @gtomek, this approach is not theoretically feasible. If our SDK requires version X of a dependency, and another SDK requires version Y of the same dependency, then an app can't add both SDKs without clashes. It doesn't matter if these versions are hosted by us or in a central repository managed by TWINT – there still can be only one version in the app and if X and Y are incompatible it would not work.

In practice, TWINT SDK updates are relatively infrequent. So you might get lucky with both SDKs using the same TWINT version. But it is not a stable construct.

@jschmid
Copy link
Author

jschmid commented Aug 21, 2024

In release 3.7.0 you mention that this bug is fixed. That is not true.

You still use your own dependency published at https://datatrans.jfrog.io/ui/native/mobile-sdk/ch/twint/payment/twint-sdk-android/8.0.0/

I have updated my repro project with version 3.7.0. We still get the same name clashes:

Duplicate class ch.twint.payment.sdk.Twint found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-8.0.0.jar -> twint-sdk-android-8.0.0 (ch.twint.payment:twint-sdk-android:8.0.0)
Duplicate class ch.twint.payment.sdk.TwintPayResult found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-8.0.0.jar -> twint-sdk-android-8.0.0 (ch.twint.payment:twint-sdk-android:8.0.0)
Duplicate class ch.twint.payment.sdk.exceptions.TwintCodeEmptyOrBlankException found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-8.0.0.jar -> twint-sdk-android-8.0.0 (ch.twint.payment:twint-sdk-android:8.0.0)
Duplicate class ch.twint.payment.sdk.exceptions.TwintException found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-8.0.0.jar -> twint-sdk-android-8.0.0 (ch.twint.payment:twint-sdk-android:8.0.0)
Duplicate class ch.twint.payment.sdk.exceptions.TwintMethodCalledBeforeOnCreateException found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-8.0.0.jar -> twint-sdk-android-8.0.0 (ch.twint.payment:twint-sdk-android:8.0.0)
Duplicate class ch.twint.payment.sdk.exceptions.TwintResultPendingException found in modules twint-5.6.0.aar -> twint-5.6.0-runtime (com.adyen.checkout:twint:5.6.0) and twint-sdk-android-8.0.0.jar -> twint-sdk-android-8.0.0 (ch.twint.payment:twint-sdk-android:8.0.0)

@bacherma
Copy link

bacherma commented Sep 2, 2024

The two issues are unrelated. Issue #22 is about the repackaging of our SDK classes. However, the TWINT SDK is an external dependency provided by TWINT and has nothing to do with that.

As mentioned before, your approach does not work in theory, no matter how the TWINT SDK is obtained. In practice you can just try to exclude one of the TWINT SDKs as shown by @luiscosta above. Currently this should work because Adyen and Datatrans are both using TWINT 8.0 (at the moment!).

@jschmid
Copy link
Author

jschmid commented Sep 2, 2024

For the record, I now tried to exclude one of the two Twint SDK, and it compiles fine. I have not tried running in though. We will not do that in prod as it is obviously too risky.

Let's wait for Twint to publish their own artifact now...

I know this won't fix the clashing Twint SDK version. One thing at a time... 🙂

@bacherma
Copy link

bacherma commented Sep 2, 2024

As far as risk is concerned, it is the same thing whether Twint publishes the SDK itself or not. Both SDKs depend on TWINT 8.0 at the moment, so for the current payment SDK versions you can run it in prod if you want. Our SDK checks if TWINT is on the classpath to enable TWINT flows. If TWINT 8.0 is added to your app via Adyen it will automatically work for Datatrans.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants