Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-5123] Android: CommonJS Modules not included/functional in distribution build

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2012-01-06T12:02:29.000+0000
Affected Version/sRelease 1.7.2
Fix Version/sRelease 1.7.4, Sprint 2011-47, Release 1.8.0
ComponentsAndroid
Labelsbranch-v8, dr-list, qe-testadded, verified-1.7.3
ReporterKevin Whinnery
AssigneeBill Dawson
Created2011-08-26T13:32:37.000+0000
Updated2012-01-06T12:02:29.000+0000

Description

Multiple reports have come in from the community that CommonJS modules (in the Resources directory) are not being found in Android .apk files that have been packaged for distribution. I have confirmed this to be the case myself on both Gingerbread and Froyo devices with a .apk I built for distribution through Titanium Studio To reproduce, try packaging an application for distribution using CommonJS JavaScript modules. Any simple module should be able to reproduce it, but you can use my sample app from here: https://github.com/appcelerator-developer-relations/Forging-Titanium/tree/master/ep-003/CustomComponents The stack trace I got from my device is located here: http://www.pastie.org/pastes/2435429/text

Attachments

FileDateSize
device-2011-11-10-171754.png2011-11-10T17:37:08.000+0000129320
device-2011-11-10-173441.png2011-11-10T17:37:08.000+000068192
timob5123.zip2011-10-25T09:53:38.000+00002328708

Comments

  1. Kevin Whinnery 2011-08-26

    Also, reported in the Q&A here: http://developer.appcelerator.com/question/124473/commonjs-modules---typeerror-in-production
  2. Mark Burggraf 2011-08-26

    NOTE: on iOS, it appears that packaged apps crash when trying to run code from a CommonJS module. I'm not sure if this is related, or is a separate bug.
  3. Mark Burggraf 2011-08-28

    I finally got my Galaxy Tab working with adb under Lion. As a result, I can run the CommonJS test project on the Android device (by selecting "Android Device" from the drop-down menu.) So it's only the Distribute command that does not work. Summary: Run on Android device WORKS Distribute - Android FAILS Distribute - iOS FAILS All emulators WORK
  4. Mark Burggraf 2011-09-12

    Any word on when this issue might be addressed? Without the ability to deploy, a lot of us are hedging our plans for refactoring code to use the CommonJS module format.
  5. Shawn Lipscomb 2011-09-13

    Please escalate this problem! We are dying on the vine, having just tried to release our app on the Android Market, and our very first customer ran into this. Is there a workaround? We have got to do something, and quick.
  6. Jon Barnhart 2011-09-13

    Looking for a workaround for this, or possibly a fix in one of the nightly builds of the SDK. This is a complete show stopper for us.
  7. Joe Johnson 2011-09-13

    We are having the same problem. Is there a quick fix? Hate to be a pain but I need something.
  8. Pete Berry 2011-09-13

    After lots of hard work and overtime our team was very excited to deploy. Our library is built around the "require" feature so there is no quick fix! Now we have to tell the president of the company that we had to pull the app off the market. It sure would be nice to give him a time frame as to when this issue will be addressed! To make matters worse, there is a board of directors meeting this week. A demo of the new Titanium based Smartphone app is on the agenda. Please help our president save face by escalating this ASAP!
  9. Kevin Whinnery 2011-09-13

    I have documented a workaround here. This is issue is starting to be addressed in 1.8, but as a platform team we need to verify CommonJS use cases before 1.8 ships: http://developer.appcelerator.com/question/124473/commonjs-modules---typeerror-in-production#answer-218739
  10. Bill Dawson 2011-09-23

    Pull requests ready: Rhino: https://github.com/appcelerator/rhino_titanium/pull/4 TiMobile: https://github.com/appcelerator/titanium_mobile/pull/493
  11. Kevin Whinnery 2011-09-26

    It would be super fantastically awesome if these commonJS changes would get processed sooner rather than later - lots of folks running up against it with current prod release now that we've been demoing CommonJS so much (and since it's the wave of the future).
  12. Bill Dawson 2011-09-26

    Totally agree. The relevant peeps (those who will review my changes) won't see your comment since they don't watch here, but I'd anyway already told them it's high prio.
  13. Kevin Whinnery 2011-09-27

    Thanks!
  14. Bill Dawson 2011-09-28

    Going to merge into 1.7.X, so re-opening.
  15. Bill Dawson 2011-09-28

    Merged into 1_7_X as well
  16. Bill Dawson 2011-09-28

    We have a regression whereby if you put a forward slash in the front of the module path (require("/lib/mymodule"), for example), it will fail.
  17. Bill Dawson 2011-09-28

    New testing notes: Please test Kevin's original failcase (in the description) in *production* (i.e., "Distribute - Android" in Titanium Studio). THEN, test the attached app in timob5123.zip. Test it twice: once with the tiapp.xml's "compilejs" setting to false, once to true.
  18. Bill Dawson 2011-09-28

    Newer fix in master and 1_7_X
  19. Eric Merriman 2011-09-29

    Verified fixed with Mac OS X 10.6.8, Titanium Studio build: 1.0.5.201109261308 , SDK 1.7.3.v20110928185013. Packaged CustomComponents sample, and TIMOB5123 Zip with false and true. Installed all 3 on Nexus S 2.3.4. All packaged and run on device with no issue.
  20. Dan Tamas 2011-10-05

    It seems is not fixed yet. ( 1.7.3 and 1.8 ) I'm trying to deploy to device with Android 2.1 and I get this error: ~~~ 10-05 10:53:33.819: ERROR/TiJSError(29889): (kroll$6: app://mycards/carddetail.js) [2,56885] - Message: TypeError: Cannot find function makeInit in object [object Object]. (app://mycards/carddetail.js#76) ~~~ Of course that the module is ok and it works with 1.7.2 without any problem. With or without false Thank you.
  21. Bill Dawson 2011-10-05

    Were you setting the exports object directly, by chance? Such as ...
        examples={...};
        
    If so, note that that is **not** part of the CommonJS standard. The fact that it worked in previous versions of the Android require() implementation (and in iOS) was more or less accident. We now use the official Rhino (the javascript engine) CommonJS implementation in Android. Regarding it not being part of CommonJS, see http://groups.google.com/group/commonjs/browse_thread/thread/1f4fa28f304d4d35 Node (nodejs) does not support if either, for example.
  22. Bill Dawson 2011-10-05

    FYI re the exports = ... issue that I note above, we have already a parity ticket for that, meaning a ticket to address the fact that it works in iOS but not Android. So it will either be removed from iOS or a new solution will be found for Android. TIMOB-5406
  23. Dan Tamas 2011-10-05

    Yes sir, it seems that setting an object that will be assigned to exports later breaks the things :) It would be better (imho) to be removed from ios to stick with the standard. Thank you.
  24. Kevin Whinnery 2011-10-05

    The module spec provides for assignment of an object to the exports variable. This is a case where an addition to Android is needed.
  25. Bill Dawson 2011-10-05

    I haven't been able to find it in any spec. Where do you see it?
  26. Dan Tamas 2011-10-05

    I'm lost. So
        var mod = {a:'b'};
        exports = mod;
        
    is valid (from the standard point of view)? if so
        exports.a = 'b';
        
    will still work ? thnx
  27. Kevin Whinnery 2011-10-05

    Dan, you are correct, the first format should work. The Module spec: http://wiki.commonjs.org/wiki/Modules/1.1 indicates that exports must be a free variable - a free variable (in computer science terms) is a placeholder value to which other values can be assigned. By that definition, it should be possible to assign a value to the exports object.
        function MyObject() {}
        MyObject.prototype.sayHello() {
          alert('hello');
        };
        exports = MyObject;
        
        var MyObject = require('MyObject');
        var o = new MyObject();
        
    The above should be a valid use of CommonJS modules.
  28. Bill Dawson 2011-10-05

    Period? End of story? I think not! :) Anyway, I'm moving my response to the appropriate place, TIMOB-5406. We need any more comments here. We already have the ticket that came out specifically because of this issue.
  29. Bill Dawson 2011-10-21

    Re-opened for full re-test after changes to be made for TIMOB-5748
  30. Bill Dawson 2011-10-21

    New pull request ready: https://github.com/appcelerator/titanium_mobile/pull/578
  31. Bill Dawson 2011-10-25

    Uploaded new version of timob5123.zip. The other one accidentally had a file with an underscore beginning its name.
  32. Eric Merriman 2011-11-10

    Now occurring with timob5123.apk on both rhino and v8 with SDK 1.8.0.1.v20111109152300. See attached screenshots
  33. Bill Dawson 2011-11-22

    It's not related to distributed mode, so I'll create a different ticket. It's related to forward slashes, and occurs also on emulators and non-distributed-mode devices. If you took my two forward-slashed references out of timob5123.zip, it works fine in distributed build. To test that, here is the modified app.js
        Titanium.UI.setBackgroundColor('#000');
        var win = Titanium.UI.createWindow({  
            title:'Test',
            backgroundColor:'#000',
        	exitOnClose: true
        });
        
        var testmod = require("lib/testmod");
        win.add(Ti.UI.createLabel({
        	top: "20dp", left: "20dp", right: "20dp", height: "40dp",
        	text: testmod.sayHi("from a non-forward-slashed module.")
        }));
        
        win.open();
        
  34. David Rodriguez 2011-12-10

    Just to make sure, quoting Kevin Whinnery above, is the following now working on android and iOS without problems? {quote} Dan, you are correct, the first format should work. The Module spec: http://wiki.commonjs.org/wiki/Modules/1.1 indicates that exports must be a free variable - a free variable (in computer science terms) is a placeholder value to which other values can be assigned. By that definition, it should be possible to assign a value to the exports object. function MyObject() {} MyObject.prototype.sayHello() { alert('hello'); }; exports = MyObject; var MyObject = require('MyObject'); var o = new MyObject(); The above should be a valid use of CommonJS modules. {quote}
  35. Michael Pettiford 2011-12-19

    Tested with Titanium Studio 1.0.7.201112152014 Ti Mob SDK 1.8.0.1.RC3 OSX Lion Nexus One OS 2.2.2 Tested both CustomComponents with true/false, and timob5123 with true/false
  36. Wilson Luu 2012-01-06

    Updating tags

JSON Source