[TIMOB-24932] Android Hybrid modules: cannot instantiate a proxy in a js file that is packaged in the same module
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Critical |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2017-07-11T16:57:48.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 6.1.2 |
Components | Android |
Labels | android, module |
Reporter | Andrea Vitale |
Assignee | Christopher Williams |
Created | 2017-07-05T08:45:24.000+0000 |
Updated | 2017-07-20T22:29:16.000+0000 |
Description
Suppose that I have a module is called
it.andreavitale.commonjs.test
:
it has a it.andreavitale.commonjs.test.js
file inside my-module/android/assets
folder and a proxy file under my-module/android/src/it/andreavitale/commonjs/test/ExampleProxy.java
If inside it.andreavitale.commonjs.test.js
file I call require('it.andreavitale.commonjs.test').createExample()
I always get this error:
[ERROR] TiExceptionHandler: (main) [126,126] ----- Titanium Javascript Runtime Error -----
[ERROR] TiExceptionHandler: (main) [0,126] - In ti:/module.js:129,37
[ERROR] TiExceptionHandler: (main) [0,126] - Message: Uncaught TypeError: Cannot read property 'length' of undefined
[ERROR] TiExceptionHandler: (main) [0,126] - Source: var invocationsLen = invocationAPIs.length;
[ERROR] V8Exception: Exception occurred at ti:/module.js:129: Uncaught TypeError: Cannot read property 'length' of undefined
If I call require('it.andreavitale.commonjs.test').createExample()
inside my app alloy.js the proxy is correctly created.
I attach a sample module project to reproduce the error.
If you comment the line 9
inside android/assets/it.andreavitale.commonjs.test.js
and you run the example app everything will work fine.
Attachments
File | Date | Size |
---|---|---|
commonjs-test.zip | 2017-07-05T08:39:45.000+0000 | 867279 |
it.andreavitale.commonjs.test-android-1.0.0.zip | 2017-07-05T11:48:36.000+0000 | 50553 |
I am able to reproduce the issue using the below Ti SDK: 6.1.1.GA OnePlus 3 7.1.1
Add the attached module zip (it.andreavitale.commonjs.test-android-1.0.0.zip) either globally or in your app
Add the below code and tiapp module entry to your app
Build for Android (device or emulator)
So I'm not entirely sure this is really a bug here, or at least I think there's a simple workaround to avoid this. What happens when we create a hybrid module is that the CommonJS file and the native module get "merged". In practice what that really means is that we instantiate the native module, then we load the commonjs file as a module and "copy" all the own properties of the module.exports from it onto the native module's wrapper object. So in this case, if you wanted to invoke the native module's createExample() in the commonjs portion, you'd actually call
this.createExample();
Here's the whole file:Calling
require("module.id")
from the commonjs extension file may just confuse the system a bit. I think specifically our caching of the combined native + CommonJS is somehow getting confused in this specific case. We cache the native module portion globally, but the combined native+CommonJS portion gets cached per-module (i.e. we try to re-generate it from each module that attempts to require it). We may still need to investigate and better handle this issue, but for now please just use "this".6.1.2: https://github.com/appcelerator/titanium_mobile/pull/9206 master: https://github.com/appcelerator/titanium_mobile/pull/9207
Passing review according to [~eharris]'s comments in the PR.
Closing ticket. The changes are compiled to a binary so I cannot see the actually. However by grepping contents, I am able to see ASCII texts in the file that was changed. Changes are in SDK 6.1.2.v20170710160853.