Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-24932] Android Hybrid modules: cannot instantiate a proxy in a js file that is packaged in the same module

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2017-07-11T16:57:48.000+0000
Affected Version/sn/a
Fix Version/sRelease 6.1.2
ComponentsAndroid
Labelsandroid, module
ReporterAndrea Vitale
AssigneeChristopher Williams
Created2017-07-05T08:45:24.000+0000
Updated2017-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

FileDateSize
commonjs-test.zip2017-07-05T08:39:45.000+0000867279
it.andreavitale.commonjs.test-android-1.0.0.zip2017-07-05T11:48:36.000+000050553

Comments

  1. Ewan Harris 2017-07-05

    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)

       var win = Ti.UI.createWindow({ backgroundColor: 'green', layout: 'vertical' });
       var x = require("it.andreavitale.commonjs.test");
       x.sayHello();
       win.open();
       
       <modules>
           <module>it.andreavitale.commonjs.test</module>
       </modules>
       
  2. Christopher Williams 2017-07-07

    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:
       module.exports = {
           secondFile: require("it.andreavitale.commonjs.test/another.file"),
           sayHello: function() {
               alert('hello');
       
               Ti.API.info("Creating Example proxy");
       
               // This will not work
               // return require("it.andreavitale.commonjs.test").createExample();
               //This WILL work
               return this.createExample();
           }
       };
       
    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".
  3. Christopher Williams 2017-07-07

    6.1.2: https://github.com/appcelerator/titanium_mobile/pull/9206 master: https://github.com/appcelerator/titanium_mobile/pull/9207
  4. Lokesh Choudhary 2017-07-11

    Passing review according to [~eharris]'s comments in the PR.
  5. Abir Mukherjee 2017-07-13

    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.

JSON Source