[TIMOB-27915] Android: Hyperloop generated code can cause "Cannot redefine property" error
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Critical |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2020-10-06T18:26:17.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 9.2.1, hyperloop 6.0.2 |
Components | Android |
Labels | android, hyperloop |
Reporter | kaypro |
Assignee | Joshua Quick |
Created | 2020-05-29T16:40:59.000+0000 |
Updated | 2020-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?
I'm able to reproduce this issue. Thanks for reporting it.
Any temporary hacks / workaround for the interim until this get's patched up? Thanks
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.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!
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.[~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
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!
FR Passed
PR (hyperloop.next): https://github.com/appcelerator/hyperloop.next/pull/346 PR (master): https://github.com/appcelerator/titanium_mobile/pull/12156
Verified the fix with SDK 9.2.1.v20201005155347. Closing.