Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LoadMainFile JX package #104

Open
Minishlink opened this issue Nov 19, 2015 · 10 comments
Open

LoadMainFile JX package #104

Minishlink opened this issue Nov 19, 2015 · 10 comments

Comments

@Minishlink
Copy link

Hello there.

I'm trying to load a (not corrupted ;) cf jxcore/jxcore#651) jx package based on this package.json:

{
  "name": "A6",
  "version": "0.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "dependencies": {
    "express": "^4.13.3",
    "express-pouchdb": "^1.0.1",
    "leveldown-mobile": "^1.0.10",
    "pouchdb": "^5.1.0",
    "thali": "^2.0.2"
  }
}

I generate the package with jx package app.js --show-progress percent and copy the *.node in the correct folder. (see last paragraph)

I load it like this:

document.addEventListener('deviceready', function() {
    console.log('deviceready');
    var initJXCore = setInterval(function() {
        if (typeof jxcore == 'undefined')
            return;

        clearInterval(initJXCore);

        jxcore.isReady(function() {
            jxcore('app.jx').loadMainFile(function (ret, err) {
                if (err) {
                    console.error(JSON.stringify(err));
                } else {
                    console.info("jxcore ready");
                }
            });
        });
    }, 5);
});

And for testing purpose, my app.js only contains console.log("test");.

Logcat gives log.txt. In short, jxcore throws a "null" error, and "test" is not printed in logcat.

On my computer, running jx app.jx does print "test".

If it can help I can upload app.jx.

There are several reasons for loading a jx package:

  • my node_modules folder is pretty huge and it takes a lot of times to run cordova run android because it merges the folder with the platform www folder
  • not only does it take a lot of time, but during the packaging in apk, cordova or the Android build tools don't add every subfolders (certainly because path is too long, as Windows throws me this error if I create a basic zip from node_modules)

At first I was creating the package with jx package app.js --extract-what "*.node" --extract-app-root --extract-verbose --show-progress percent. But doing so, I would get an error in logcat saying that the corresponding directory could not be created (as extraction tried to create a folder inside the apk, so yeah it cannot work).

Any ideas ? Thanks for your help.

@ktrzeciaknubisa
Copy link
Member

I'm not sure if loadMainFile() call supports jx package directly, so I would recommend to keep a main file as javascript:

# index.html
jxcore('app.js').loadMainFile() 

but inside of app.js you may call:

# app.js
require('./app.jx');

Update: I meant app.js from loadMainFile() is different than app.js from inside of your package. Let's then rename the main file to avoid confusion: jxcore('start.js').loadMainFile()

@ktrzeciaknubisa
Copy link
Member

But, if you have .node files and you hope to run it with jxcore-cordova, then see jxcore/jxcore#654 (comment)

@Minishlink
Copy link
Author

So it seems it does work with jxcore('app.jx').loadMainFile( on my other computer. (I can access successfully the express server that way) I'm not sure yet what causes the issue on the first computer...

Now of course playing with the .node native module does not work as expected, as you pointed out. I guess I will use only memdown for the moment but I'd prefer to find a better solution.

If you compiled the .node using ndk-build, wouldn't the .node run well ?

Also, when doing the --extract-what method and also having the .node in the right location under www/jxcore, why does jxcore throws this:

11-19 22:03:01.908 18235-18235/app I/jxcore-log: �[33mextracting�[39m node_modules/leveldown-mobile/build/Release/leveldown.node
11-19 22:03:01.967 18235-18235/app  E/jxcore-log: �[31mCannot create directory: node_modules/leveldown-mobile/build/Release�[39m

The .node being in the apk, jxcore should load it instead of extracting it from app.jx. It should show skipping leveldown.node (file already exists) just like on a computer, shouldn't it ?

Anyway I hope these discussions will help other newcomers like me. :)

@ktrzeciaknubisa
Copy link
Member

So it seems it does work with jxcore('app.jx').loadMainFile(

Good to know :)

If you compiled the .node using ndk-build, wouldn't the .node run well ?

On same platform yes, but then the mobile where you deploy is a different machine.

It should show skipping leveldown.node (file already exists) just like on a computer, shouldn't it ?

The jx package extraction feature is meant for desktop apps only. It will not work on mobiles. Thus when you create a package for jxcore-cordova usage, you should skip extract options. Or better we should disable the extraction when running on mobiles. I didn't realize, that the extractable package wants to be extracted when using cordova :)

Just keep in www/jxcore the app.jx file and (for testing purpose) .node files in their own folders (starting from node_modules i guess).

@Minishlink
Copy link
Author

I really don't get how leveldown-mobile can work then... I mean there must be a way to get it working since the project states it's compatible with JXcore. (cc @obastemur)

@ktrzeciaknubisa
Copy link
Member

That's because leveldown is already embedded in jxcore-cordova plugin.

@Minishlink
Copy link
Author

Uh. Cool so that means it works indeed. That was not very obvious... :/
For information, it still throws this error, though I don't know if it comes from jxcore or thali:

11-19 23:53:52.040 12512-12512/app E/jxcore: Error!: NativeModule.Roots[dir] is undefined
Stack: [{"_fileName":"fs.js","_functionName":"__hasFile","_lineNumber":"2241","_columnNumber":"5","_msg":"    at __hasFile@fs.js:2241:5"},{"_fileName":"fs.js","_functionName":"__existJX","_lineNumber":"2252","_columnNumber":"16","_msg":"    at __existJX@fs.js:2252:16"},{"_fileName":"fs.js","_functionName":"cb","_lineNumber":"147","_columnNumber":"11","_msg":"    at cb@fs.js:147:11"},{"_fileName":"fs.js","_functionName":"unknown","_lineNumber":2241,"_columnNumber":4,"_msg":"    at "}]

Thanks again for your help !

@ktrzeciaknubisa
Copy link
Member

This is probably JXcore. How can I reproduce this?

@Minishlink
Copy link
Author

// app.js
var fs = require('fs');
var express = require('express');
var path = require('path');
var os = require('os');
var PouchDB = require('pouchdb');
var ThaliReplicationManager = require('thali/thalireplicationmanager');

console.log('starting app.js');

var app = express();
app.disable('x-powered-by');

var dbPath = path.join(os.tmpdir(), 'dbPath');

var env = process.env.NODE_ENV || 'production'; // default to production

if (process.env.MOCK_MOBILE) {
  global.Mobile = require('thali/mockmobile.js');
}

if (process.platform === 'ios' || process.platform === 'android') {
  Mobile.getDocumentsPath(function(err, location) {
    if (err) {
      console.error("Error", err);
    } else {
      dbPath = path.join(location, 'dbPath');
      console.log("Mobile Documents dbPath location: ", dbPath);
    }
  });
}

var LevelDownPouchDB = PouchDB.defaults({db: require('leveldown-mobile'), prefix: dbPath});

app.use('/db', require('express-pouchdb')(LevelDownPouchDB, { mode: 'minimumForPouchDB'}));
var db = new LevelDownPouchDB('thali');

app.use(function allowCrossDomain(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'http://127.0.0.1:5000');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
});

var server = app.listen(5000, function () {
    console.log('Express server started. (port: 5000)');

    var manager = new ThaliReplicationManager(db);
    manager.start(5000, 'thali');
});

The steps:

  1. cordova create test com.test.test test && cordova platform add android
  2. copy above package.json and app.js to test/app/jxcore
  3. jx npm install --production --autoremove "*.gz"
  4. jx package app.js --show-progress percent
  5. copy app.jx to test/www/jxcore
  6. in www/index.html copy above script (with event listener on "deviceready")
  7. cordova run android (having an Android device in debug mode, as it won't work in an emulator)
  8. Look at logcat.

At step 2, you could copy to test/www/jxcore and skip step 5 but running cordova run android will be enormously long due to the numbers of folders under node_modules.

Step 3 can fail sometimes due to thali installation. If it's the case, simply run jx npm install thali --production --autoremove "*.gz". And check that the other packages installed well.

Oh and I got the error null again one time this morning... But I haven't since. (EDIT: just got it two times in a row...)

@ktrzeciaknubisa
Copy link
Member

Thanks for this detailed instructions. I was able to reproduce this. It happens for jxcore-cordova 0.0.7 (since Thali installs this exact version). Then I upgraded binaries to 0.0.8 but the app crashed:

11-23 14:39:06.976: W/jxcore-log(2172): Process ARCH ia32
11-23 14:39:06.976: W/jxcore-log(2172): --------- beginning of crash
11-23 14:39:06.977: A/libc(2172): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x3b0029 in tid 2172 (m.example.hello)

so I guess this needs to be fixed before we start looking at NativeModule.Roots[dir] is undefined error.

I'm reopening for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants