-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
npm: node-rfc LoadLibraryExW failed #17411
Comments
Seems like the same problem as in #16642 |
Actually it seems that this problem is caused by "preinstall"/"postinstall" script that is not run, however I can't try it as I have ARM architecture that this package explicitly doesn't support. |
ok, |
Yes, Deno has support for native Node.js modules - but it's still experimental (hence requiring
This should compile the native bindings for the package. Let me know if you get around to it, I should be able to debug it further next week on Windows machine. |
node-rfc maintainer here
Probably not. The The SAP NWRFC SDK binaries are usually installed on Windows PATH or in some Linux folder and registered on Linux system, as described here I used Ubuntu docker container, with SAP NWRFC SDK binaries in mkdir deno-rfc
cd deno-rfc
npm init -y
npm i node-rfc
deno run -A --unstable test.ts test.ts import noderfc from "npm:node-rfc";
console.log(noderfc); Error error: Uncaught Error: Error in native callback
environment: {
"platform": {
"name": "linux",
"arch": "x64",
"release": "5.15.49-linuxkit"
},
"env": {
"SAPNWRFC_HOME": "/usr/local/sap/nwrfcsdk",
"RFC_INI": ""
},
"versions": {
"node": "18.12.1",
"uv": "1.43.0",
"zlib": "1.2.11",
"brotli": "1.0.9",
"ares": "1.18.1",
"modules": "108",
"nghttp2": "1.47.0",
"napi": "8",
"llhttp": "6.0.10",
"openssl": "3.0.7+quic",
"cldr": "41.0",
"icu": "71.1",
"tz": "2022b",
"unicode": "14.0",
"ngtcp2": "0.8.1",
"nghttp3": "0.7.0",
"deno": "1.29.3",
"v8": "10.9.194.5",
"typescript": "4.9.4"
}
}
at Object.Module._extensions..node (deno:ext/node/02_require.js:807:26)
at Module.load (deno:ext/node/02_require.js:658:34)
at Function.Module._load (deno:ext/node/02_require.js:515:14)
at Module.require (deno:ext/node/02_require.js:680:21)
at require (deno:ext/node/02_require.js:820:18)
at Object.<anonymous> (file:///home/www-admin/.cache/deno/npm/registry.npmjs.org/node-rfc/2.7.0/lib/wrapper/noderfc-bindings.js:36:49)
at Object.<anonymous> (file:///home/www-admin/.cache/deno/npm/registry.npmjs.org/node-rfc/2.7.0/lib/wrapper/noderfc-bindings.js:53:4)
at Module._compile (deno:ext/node/02_require.js:747:36)
at Object.Module._extensions..js (deno:ext/node/02_require.js:780:12)
at Module.load (deno:ext/node/02_require.js:658:34)
at Function.Module._load (deno:ext/node/02_require.js:515:14)
at Module.require (deno:ext/node/02_require.js:680:21)
at require (deno:ext/node/02_require.js:820:18)
at Object.<anonymous> (file:///home/www-admin/.cache/deno/npm/registry.npmjs.org/node-rfc/2.7.0/lib/index.js:20:14)
at Object.<anonymous> (file:///home/www-admin/.cache/deno/npm/registry.npmjs.org/node-rfc/2.7.0/lib/index.js:79:4)
at Module._compile (deno:ext/node/02_require.js:747:36) The source code line 36 referred in error message is the node-rfc require of local /home/www-admin/.cache/deno/npm/registry.npmjs.org/node-rfc/2.7.0/lib/wrapper/noderfc-bindings.js exports.noderfc_binding = noderfc_binding = require("../binding/sapnwrfc"); This statement normally fails when SAP NWRFC SDK is not found. I suppose this could be the cause here although not sure why, because all permissions are given? SAP NWRFC SDK binaries are properly installed and test with NodeJS works fine test.js const noderfc = require("node-rfc");
console.log(noderfc); cd deno-rfc # same folder of deno test
node test
{
setIniFileDirectory: [Function: setIniFileDirectory],
loadCryptoLibrary: [Function: loadCryptoLibrary],
sapnwrfcEvents: EventEmitter {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
[Symbol(kCapture)]: false
},
cancelClient: [Function: cancelClient],
USAGE_URL: [Getter],
Promise: [Getter],
noderfc_binding: [Getter],
environment: [Getter],
Client: [Getter],
Pool: [Getter],
Throughput: [Getter],
Server: [Getter]
} Hope this helps in further analysis |
I also added
and in
Both print the correct working directory, from which the |
Hey @bsrdjan, thank you so much for all the pointers! I have one additional question that should help me debug the problem: could you point me to the source code of |
Hello @bartlomieju, here the registration point: https://github.com/SAP/node-rfc/blob/main/src/addon.cc#L85 |
How can we add extended error information on error with LoadLibraryExW? https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw |
There's really not that much information that |
node-rfc is CommonJS module and comprises of TS/JS wrapper, which loads node binary C++ add-on sapnwrfc.node: /home/www-admin/.cache/deno/npm/registry.npmjs.org/node-rfc/2.7.0/lib/wrapper/noderfc-bindings.js exports.noderfc_binding = noderfc_binding = require("../binding/sapnwrfc"); I suspect this require might be failing because .node extension is not expected in deno, or deno does not load it correctly? Per deno documentation I tried npm init -y
npm install node-rfc
deno run -A --unstable deno-noderfc.js deno-noderfc.js import { createRequire } from "https://deno.land/std@0.109.0/node/module.ts";
// import.meta.url will be the location of "this" module (like `__filename` in
// Node.js), and then serve as the root for your "package", where the
// `package.json` is expected to be, and where the `node_modules` will be used
// for resolution of packages.
const require = createRequire(import.meta.url);
const noderfc = require("./node_modules/.deno/node-rfc@2.7.0/node_modules/node-rfc/lib/binding/sapnwrfc.node") Now the following error is thrown error: Uncaught {
thrown: SyntaxError: Invalid or unexpected token
at Object.evalContext (deno:core/01_core.js:392:14)
at wrapSafe (https://deno.land/std@0.109.0/node/module.ts:1141:39)
at Module._compile (https://deno.land/std@0.109.0/node/module.ts:163:29)
at Object.Module._extensions..js (https://deno.land/std@0.109.0/node/module.ts:1158:10)
at Module.load (https://deno.land/std@0.109.0/node/module.ts:151:34)
at Function._load (https://deno.land/std@0.109.0/node/module.ts:417:14)
at Module.require (https://deno.land/std@0.109.0/node/module.ts:137:21)
at require (https://deno.land/std@0.109.0/node/module.ts:1213:16)
at file:///home/www-admin/tmp/deno-rfc/deno-noderfc.js:10:17,
isNativeError: true,
isCompileError: true
} Invalid or unexpected token could be because sapnwrfc.node is binary and deno expects javascript? |
I need to dig into implementation of As for the Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "add"), Napi::Function::New(env, Add));
printf("Hello from C++!\n");
return exports;
}
NODE_API_MODULE(addon, Init) and not like: void Init(v8::Local<v8::Object> exports) {
v8::Local<v8::Context> context = exports->CreationContext();
exports->Set(context,
Nan::New("add").ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(Add)
->GetFunction(context)
.ToLocalChecked());
}
NODE_MODULE(addon, Init) I was under the impression that we supported both ways, but that seems to not be the case (or there's a small bug somewhere, since the module can be loaded, initializer gets called, but the error is thrown immediately after, I hit the same problem debugging #16460 and #16642 I will talk with @littledivy (who originally implemented Node-API integration into Deno) and sort this stuff out - a lot of packages use "node addon api" and so we should support it as well. |
@bsrdjan @JQ-pawelwypustek can you folks repeat this problem with Deno v1.34? |
Hi Bartek `C:\deno_sap_rfc_test2>deno run -A test.ts
C:\deno_sap_rfc_test2>deno --version test.ts: (async () => { |
I tried to run:
code 0xc000012f is "Bad Image" |
same file on ubuntu: |
it looks like node-rfc i not installed correctly on Windows system. How was it installed, by npm install node-rfc or by node-rfc repo clone and build from source Can you re-install it? The npm install first downloads the node-rfc package to host system and then sapnwrfc.node for that host platform is downloaded from node-rfc latest release assets: https://github.com/SAP/node-rfc/releases/latest The invalid header can be fixed if you can take sapnwrfc.node for Windows from there, unpack and copy over your sapnwrfc.node for Linux. But it first place check how the Linux version got installed? |
it is installed automatically by deno, file test.ts: command: automatically sapnwrfc.node gets downloaded: |
@JQ-pawelwypustek, I tested your .deno/node-rfc@2.7.1/node_modules/node-rfc/lib/binding/sapnwrfc.node When I replaced it with the correct version for Arm platform, the node-rfc loaded just fine in deno, Need to test more but the original issue, the node-rfc deno "compatibility" seem to be solved. I will investigate the installation issue, why |
I tested in new created folder on MacOS as follows test_noderfc.ts* import noderfc from "npm:node-rfc";
console.log(noderfc);
When On Linux no issues at all, without any workarounds. sapnwrfc.node pre-built binary is fetched by deno from here: https://github.com/SAP/node-rfc/releases/tag/v2.7.1. I tested with another node addon package and in that case the binary is not downloaded at all. It does not work even on Ubuntu 20.04 Linux deno
> import sqlite3 from "npm:sqlite3"
Uncaught Error: Cannot find module '/home/www-admin/.cache/deno/npm/registry.npmjs.org/sqlite3/5.1.6/lib/binding/napi-v6-linux-glibc-x64/node_sqlite3.node' It looks like node-rfc deno installation issue is related to platform resolution, which somehow "gets lost" on a way through deno? The npm install node-rfc finds correct binaries but not when done by deno. Is there something like --verbose option, to get more detailed trace of deno import command? |
verbose: I also tried: |
great! I will also try to change the packaging model of node-rfc, namely to pack and deliver binaries for all platforms. The minor disadvantage of that approach is that Windows and Linux binaries are also deployed to Darwin systems for example (and vice versa) but files are anyway under 1 MB, thus would not hurt. Once all binaries are there, the application should pick-up the correct one. |
|
Sorry, actually I just got a reproduction on Windows and it doesn't work. I'm looking into it. |
Ok, so this has nothing to do with npm os/arch selection and is because Deno does not run pre/post install scripts as Bartek mentioned a few months ago. You can reproduce the problem in npm/Node by doing the following:
The reason the Not running pre/post install scripts is a limitation in Deno. Package authors can get around it by initializing lazily on first run similar to how they could make it work for people who run with |
It explains why Linux binary is taken, not by deno but because included in node-rfc package.json "files". The last platform build is Linux and shipped in node-rfc package. It shall be changed because no binary should be shipped as default. |
@dsherret, initializing lazily on first run should work. The node-rfc can check if binary is present and if not, assume it is installed by deno. Then it could either build the binary using prebuild JS API, or ask the user to execute installation task? I was initially thinking of user running "npm run pre/-install" but deno is not using npm. But then I found this SO topic https://stackoverflow.com/questions/61763366/deno-how-to-substitute-npm-scripts-package-json Is there some kind of script/task functionality in deno, to substitute npm preinstall/install ? |
The node-rfc package is not re-factored so that node-rfc binaries for all platforms are packaged and installed on any platform. The binary for the host platform is determined at application runtime, thus independent of deno. The change is shipped as node-rfc 3.0.0-rc1 pre-release. @JQ-pawelwypustek, could you please test if node-rfc 3.0.0-rc1 works for you? |
can you give me a hint how to run this version? |
it is '3.0.0-rc.1', the point is missing in "npm:node-rfc@3.0.0-rc1" |
deno: deno run -A test.ts when I try nodejs: error: |
the bug is fixed, please try 3.0.0-rc.2 |
The error is not displayed now! import noderfc from "npm:node-rfc@3.0.0-rc.2" In nodejs this example works fine |
I tested on Linux and got a bit more descriptive error message: deno run --allow-read --allow-ffi --allow-sys ci/issues/test_import-rfc.ts --log-level debug
deno: symbol lookup error: /home/www-admin/src/sap/node-rfc/ci/issues/node_modules/.deno/node-rfc@3.0.0-rc.2/node_modules/node-rfc/prebuilds/linux-x64/node.napi.node: undefined symbol: uv_sem_init node-rfc is using libuv functions which are not supported by deno. These could be replaced with N-API counterparts, as described here, which requires more time and effort |
Deno platform is supported as of node-rfc@3.2. The platform resolution is not any more done during installation but in runtime. node-rfc binaries for all platforms are now deployed on client and the binary for client host platform is determined in runtime. Also the libuv is replaced by standard cpp mutex. Please test and if any issues let ne know. |
It looks like it works great, thanks, Srdjan! |
I dream of using node-rfc with deno :)
import noderfc from "npm:node-rfc"
tried with --node-modules-dir and got the same error
error: Uncaught TypeError: LoadLibraryExW failed
environment: {
"platform": {
"name": "win32",
"arch": "x64",
"release": "10.0.19044"
},
"env": {
"SAPNWRFC_HOME": "c:\nwrfcsdk",
"RFC_INI": "",
"nwrfcsdk_lib_on_path": true
},
"versions": {
"node": "18.12.1",
"uv": "1.43.0",
"zlib": "1.2.11",
"brotli": "1.0.9",
"ares": "1.18.1",
"modules": "108",
"nghttp2": "1.47.0",
"napi": "8",
"llhttp": "6.0.10",
"openssl": "3.0.7+quic",
"cldr": "41.0",
"icu": "71.1",
"tz": "2022b",
"unicode": "14.0",
"ngtcp2": "0.8.1",
"nghttp3": "0.7.0",
"deno": "1.29.3",
"v8": "10.9.194.5",
"typescript": "4.9.4"
}
}
The text was updated successfully, but these errors were encountered: