Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27915] Android: Hyperloop generated code can cause "Cannot redefine property" error

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2020-10-06T18:26:17.000+0000
Affected Version/sn/a
Fix Version/sRelease 9.2.1, hyperloop 6.0.2
ComponentsAndroid
Labelsandroid, hyperloop
Reporterkaypro
AssigneeJoshua Quick
Created2020-05-29T16:40:59.000+0000
Updated2020-10-06T18:26:17.000+0000

Description

When using the Android Stripe SDK and when I require CardInputWidget (no other code):
const CardInputWidget = require("com.stripe.android.view.CardInputWidget");
dependencies {
  implementation 'com.stripe:stripe-android:14.4.1'
}
I get this error:
[ERROR] TiExceptionHandler: (main) [91,18169] /hyperloop/com.stripe.android.view.CardInputWidget.js:169
[ERROR] TiExceptionHandler: Object.defineProperty(CardInputWidget, 'Companion', {
[ERROR] TiExceptionHandler:        ^
[ERROR] TiExceptionHandler: TypeError: Cannot redefine property: Companion
[ERROR] TiExceptionHandler:     at Function.defineProperty (<anonymous>)
[ERROR] TiExceptionHandler:     at /hyperloop/com.stripe.android.view.CardInputWidget.js:169:8
[ERROR] TiExceptionHandler:     at Module._runScript (ti:/module.js:587:9)
[ERROR] TiExceptionHandler:     at Module.load (ti:/module.js:106:7)
[ERROR] TiExceptionHandler:     at Module.loadJavascriptText (ti:/module.js:436:9)
[ERROR] TiExceptionHandler:     at Module.loadAsFile (ti:/module.js:488:15)
[ERROR] TiExceptionHandler:     at Module.loadAsFileOrDirectory (ti:/module.js:410:20)
[ERROR] TiExceptionHandler:     at Module.require (ti:/module.js:245:23)
[ERROR] TiExceptionHandler:     at Module.global.Module.require (<embedded>:19311:34)
[ERROR] TiExceptionHandler:     at require (ti:/module.js:550:15)
[ERROR] TiExceptionHandler:
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.runtime.v8.V8Object.nativeFireEvent(Native Method)
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.runtime.v8.V8Object.fireEvent(V8Object.java:63)
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.KrollProxy.doFireEvent(KrollProxy.java:975)
[ERROR] TiExceptionHandler:     org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1204)
[ERROR] TiExceptionHandler:     org.appcelerator.titanium.proxy.TiViewProxy.handleMessage(TiViewProxy.java:267)
[ERROR] TiExceptionHandler:     android.os.Handler.dispatchMessage(Handler.java:102)
[ERROR] TiExceptionHandler:     android.os.Looper.loop(Looper.java:193)
[ERROR] TiExceptionHandler:     android.app.ActivityThread.main(ActivityThread.java:6718)
[ERROR] TiExceptionHandler:     java.lang.reflect.Method.invoke(Native Method)
[ERROR] TiExceptionHandler:     com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
[ERROR] V8Exception: Exception occurred at /hyperloop/com.stripe.android.view.CardInputWidget.js:169: Uncaught TypeError: Cannot redefine property: Companion
In the com.stripe.android.view.CardMultilineWidget.js file that get's generated there are two: Object.defineProperty(CardMultilineWidget, 'Companion', { Properties that I think need a: configurable: true set after the "enumerable: true," perhaps?

Comments

  1. Joshua Quick 2020-05-29

    I'm able to reproduce this issue. Thanks for reporting it.
  2. kaypro 2020-10-01

    Any temporary hacks / workaround for the interim until this get's patched up? Thanks
  3. Joshua Quick 2020-10-01

    I don't see any good work-around other than to do this via a native module. We think this issue is happening in hyperloop because the [CardInputWidget](https://github.com/stripe/stripe-android/blob/master/stripe/src/main/java/com/stripe/android/view/CardInputWidget.kt) class and the [CardWidget](https://github.com/stripe/stripe-android/blob/master/stripe/src/main/java/com/stripe/android/view/CardWidget.kt) class it inherits from both define the same inner class Companion. Hyperloop may not be correctly handling the "shadowing" of the inner class and that may be the causes of the collision.
  4. kaypro 2020-10-01

    Understood... make sense. Hope we can get hyperloop to accommodate... there's quite a few frameworks I've tried that I've come across the same issue. Fingers crossed... appreciate the insight!
  5. Joshua Quick 2020-10-03

    I dug into this some more. I was partly mistaken. What's going on is that the [CardInputWidget](https://github.com/stripe/stripe-android/blob/master/stripe/src/main/java/com/stripe/android/view/CardInputWidget.kt) class uses a kotlin language feature called "companion", which when transpiled into Java, will create an inner class named "Companion" and a public static field instance named "Companion". https://kotlinlang.org/docs/tutorials/kotlin-for-py/objects-and-companion-objects.html#companion-objects https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#static-fields This is legal when compiled to a JAR, but hyperloop needs to be changed to check for name collision and favor the field over the inner class with the same name. If anyone wants to access the inner class, then they would have to use require() to get a hold of it... although for the kotlin companion feature, this isn't practical.
  6. Joshua Quick 2020-10-03

    [~kaypro@gmail.com], would you mind trying the zipped up pre-release version of hyperloop from the link below please? It should fix the issue. Note that this version of the module only works with Titanium 9.0.0 and higher. https://github.com/appcelerator-modules/hyperloop-builds/releases/tag/v6.0.2
  7. kaypro 2020-10-03

    Confirmed!! Works like a charm. Nice find. Thanks for the efforts on this one... opens up a whole lot of options now on Android. Thank you!
  8. Satyam Sekhri 2020-10-05

    FR Passed
  9. Joshua Quick 2020-10-05

    PR (hyperloop.next): https://github.com/appcelerator/hyperloop.next/pull/346 PR (master): https://github.com/appcelerator/titanium_mobile/pull/12156
  10. Lokesh Choudhary 2020-10-06

    Verified the fix with SDK 9.2.1.v20201005155347. Closing.

JSON Source