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

nbb does not launch on GraalVM's distribution of nodejs #118

Closed
littleli opened this issue Jan 16, 2022 · 10 comments
Closed

nbb does not launch on GraalVM's distribution of nodejs #118

littleli opened this issue Jan 16, 2022 · 10 comments

Comments

@littleli
Copy link
Contributor

littleli commented Jan 16, 2022

I used the latest GraalVM (21.3.0) on MacOS (Big Sur)

After installing nodejs with gu:

$ gu install nodejs

I installed nbb and received this output, so it apears to be happy:

$ npm install -g nbb
/Users/alesnajmann/local/graalvm-ce-java17-21.3.0/Contents/Home/languages/nodejs/bin/nbb -> /Users/alesnajmann/local/graalvm-ce-java17-21.3.0/Contents/Home/languages/nodejs/lib/node_modules/nbb/out/nbb_main.js
+ [email protected]
updated 1 package in 2.253s

but after I try to run it it ends up with following error:

$ ./nbb 
----- Error --------------------------------------
Type:     TypeError
Message:  Invalid host defined options
Invalid host defined options

If there is a minimal possibility to make it work 🙏🏻

I think there is a huge opportunity to direct interop between nodejs<->java interop using GraalVM, and so is for nbb.

@littleli littleli changed the title nbb does not launch on GraalVM distribution of nodejs nbb does not launch on GraalVM's distribution of nodejs Jan 16, 2022
@borkdude
Copy link
Collaborator

Oh wow, I didn't think of that use case yet. Thank you!

@borkdude
Copy link
Collaborator

@littleli It seems to be related to dynamic import.

This works though. So as long as you use only clojure core stuff and js/... it should work for now. I think nodejs on Graal might not have parity with the newest node.

$ $GRAALVM_HOME/bin/node out/nbb_main.js -e '(+ 1 2 3)'
6

@borkdude
Copy link
Collaborator

It seems the regular interop isn't working for nodejs on Graal

$ $GRAALVM_HOME/bin/node --jvm --polyglot out/nbb_main.js -e '(def bigint (js/Java.type "java.math.BigInteger")) (-> (.valueOf bigint 2))'
----- Error --------------------------------------
Type:     TypeError
Message:  invokeMember (apply) on java.lang.Class.valueOf failed due to: Message not supported.
invokeMember (apply) on java.lang.Class.valueOf failed due to: Message not supported.

But using js/Reflect it does work (I recently learned that this exists from @zane):

$ $GRAALVM_HOME/bin/node --jvm --polyglot out/nbb_main.js -e '(def bigint (js/Java.type "java.math.BigInteger")) (-> (js/Reflect.apply (.-valueOf bigint) nil #js [2]) str)'
"2"

Perhaps the interop in SCI should default to Reflect if it's available (not sure if it's supported everywhere).

@littleli
Copy link
Contributor Author

@borkdude
Copy link
Collaborator

borkdude commented Jan 30, 2022

A repro in pure JS:

> var BigInteger = Java.type('java.math.BigInteger');
> var x = BigInteger.valueOf.apply(BigInteger, [10])
Uncaught:
TypeError: invokeMember (apply) on java.lang.Class.valueOf failed due to: Message not supported.

> var x = Reflect.apply(BigInteger.valueOf, BigInteger, [10])
undefined
> x.toString()
'10'

@borkdude
Copy link
Collaborator

Btw, it seems now that js/import works on the newest GraalVM release (22.0.0.2):

$ GRAALVM_HOME/bin/node out/nbb_main.js -e '(ns foo (:require ["path" :as path])) (path/resolve "README.md")'
"/Users/borkdude/Dropbox/dev/clojure/nbb/README.md"

I have asked on the graalvm slack why the first example using .apply doesn't work, but I will ultimately fix it in nbb or SCI.

@borkdude
Copy link
Collaborator

Reply from Graal Slack:

Jan Štola 3 minutes ago
The first version assumes that BigInteger.valueOf has apply property. This is not true for Java functions (foreign/non-JavaScript executable objects) by default.

Jan Štola < 1 minute ago
Reflect.apply is a generic request to call the the function/callable/executable. There is no need for a particular property in this case.

@borkdude
Copy link
Collaborator

Should be fixed in 0.1.4, releasing on CI

@borkdude
Copy link
Collaborator

@borkdude
Copy link
Collaborator

Also got this response from the GraalVM slack:

FYI: --js.foreign-object-prototype puts Function.prototype on the prototype chain of foreign executables. In other words, the first test-case works with this option.

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