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

npm: node-rfc LoadLibraryExW failed #17411

Open
JQ-pawelwypustek opened this issue Jan 14, 2023 · 38 comments
Open

npm: node-rfc LoadLibraryExW failed #17411

JQ-pawelwypustek opened this issue Jan 14, 2023 · 38 comments
Labels
needs investigation requires further investigation before determining if it is an issue or not node compat node native extension related to the node-api (.node)

Comments

@JQ-pawelwypustek
Copy link

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"
}
}

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:///C:/src/testy/deno_sap_rfc/node_modules/.deno/node-rfc@2.7.0/node_modules/node-rfc/lib/wrapper/noderfc-bindings.js:36:49)
at Object.<anonymous> (file:///C:/src/testy/deno_sap_rfc/node_modules/.deno/node-rfc@2.7.0/node_modules/node-rfc/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:///C:/src/testy/deno_sap_rfc/node_modules/.deno/node-rfc@2.7.0/node_modules/node-rfc/lib/index.js:20:14)
at Object.<anonymous> (file:///C:/src/testy/deno_sap_rfc/node_modules/.deno/node-rfc@2.7.0/node_modules/node-rfc/lib/index.js:79:4)
at Module._compile (deno:ext/node/02_require.js:747:36)
@bartlomieju
Copy link
Member

Seems like the same problem as in #16642

@bartlomieju bartlomieju added needs investigation requires further investigation before determining if it is an issue or not node compat node native extension related to the node-api (.node) labels Jan 14, 2023
@bartlomieju
Copy link
Member

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.

@JQ-pawelwypustek
Copy link
Author

ok,
I am looking for a temporary solution,
can i compile the module manually somehow?
can deno use native nodejs modules?

@bartlomieju
Copy link
Member

ok, I am looking for a temporary solution, can i compile the module manually somehow? can deno use native nodejs modules?

Yes, Deno has support for native Node.js modules - but it's still experimental (hence requiring --unstable flag) and we hit a bug here. You can try compile the extension manually - to do that you will need to find it in the cache folder. I recommend to go with the following:

$ deno run -A --unstable --node-modules-dir your_file.js
$ cd node_modules/node-rfc
$ npm install

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.

@bsrdjan
Copy link

bsrdjan commented Jan 16, 2023

node-rfc maintainer here

I should be able to debug it further next week on Windows machine.

Probably not. The node-rfc npm package has a local dependency SAP NWRFC SDK. These are platform specific binaries (DLL on Windows, SO on Linux ...) and must be downloaded and installed separately on host system. SAP developer, partner or customer account is required to access.

The import noderfc from "npm:node-rfc" loads the npm node-rfc javascript package, which loads sapnwrfc.node binary, from local node-rfc npm package subdirectory bindings. sapnwrfc.node requires locally installed SAP NWRFC SDK binaries and the loading fails when these are not found.

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 /usr/local/sap/nwrfcsdk/lib folder and reproduced the error as follows

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 sapnwrfc.node binary

/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

@bsrdjan
Copy link

bsrdjan commented Jan 16, 2023

I also added console.log(__dirname) just before the line 36, in deno node-rfc package

.cache/deno/npm/registry.npmjs.org/node-rfc/2.7.0/lib/wrapper/noderfc-bindings.js

and in

node_modules/node-rfc/lib/wrapper/noderfc-bindings.js

Both print the correct working directory, from which the sapnwrfc.node should be found by require("../binding/sapnwrfc");. Perhaps this statement does not find sapnwrfc.node in deno?

@bartlomieju
Copy link
Member

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 sapnwrfc.node so I can see how it gets registered? My hunch is that this error is related to #17349 which I haven't fixed yet (ie. the initializer function returns an "exports" object instead of assigning to it, which we currently don't handle properly).

@bsrdjan
Copy link

bsrdjan commented Jan 16, 2023

Hello @bartlomieju,

here the registration point: https://github.com/SAP/node-rfc/blob/main/src/addon.cc#L85

@JQ-pawelwypustek
Copy link
Author

How can we add extended error information on error with LoadLibraryExW?
Perhaps this will tell us the cause of the error

https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw
https://learn.microsoft.com/en-us/windows/win32/debug/retrieving-the-last-error-code

@bartlomieju
Copy link
Member

How can we add extended error information on error with LoadLibraryExW? Perhaps this will tell us the cause of the error

https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw https://learn.microsoft.com/en-us/windows/win32/debug/retrieving-the-last-error-code

There's really not that much information that libloading crate (that we use to load Node-API extensions) is providing. I will look into making it better, but it's unclear if I can eek out more info.

@bsrdjan
Copy link

bsrdjan commented Jan 17, 2023

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?

@bartlomieju
Copy link
Member

bartlomieju commented Jan 17, 2023

Invalid or unexpected token could be because sapnwrfc.node is binary and deno expects javascript?

I need to dig into implementation of deno_std/node/module.ts to determine what's the problem here - but all in all, we're most likely going to deprecate that module in favor of built-in implementation (the one used when you import "npm:node-rfc").

As for the error: Uncaught Error: Error in native callback error you were getting earlier - I dug a bit and I think I found the culprit - node-rfc uses the "node addon api" and not "Node-API", ie. the initializer has signature like:

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.

@bartlomieju
Copy link
Member

@bsrdjan @JQ-pawelwypustek can you folks repeat this problem with Deno v1.34?

@JQ-pawelwypustek
Copy link
Author

Hi Bartek
Unfortunately, the error still occurs:

`C:\deno_sap_rfc_test2>deno run -A test.ts
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.34.0",
"v8": "11.5.150.1",
"typescript": "5.0.4"
}
}

at Object.Module._extensions..node (ext:deno_node/01_require.js:1034:24)
at Module.load (ext:deno_node/01_require.js:885:32)
at Function.Module._load (ext:deno_node/01_require.js:719:12)
at Module.require (ext:deno_node/01_require.js:907:19)
at require (ext:deno_node/01_require.js:1047:16)
at Object.<anonymous> (file:///C:/deno_sap_rfc_test2/node_modules/.deno/node-rfc@2.7.0/node_modules/node-rfc/lib/wrapper/noderfc-bindings.js:36:49)
at Object.<anonymous> (file:///C:/deno_sap_rfc_test2/node_modules/.deno/node-rfc@2.7.0/node_modules/node-rfc/lib/wrapper/noderfc-bindings.js:53:4)
at Module._compile (ext:deno_node/01_require.js:974:34)
at Object.Module._extensions..js (ext:deno_node/01_require.js:1007:10)
at Module.load (ext:deno_node/01_require.js:885:32)
at Function.Module._load (ext:deno_node/01_require.js:719:12)
at Module.require (ext:deno_node/01_require.js:907:19)
at require (ext:deno_node/01_require.js:1047:16)
at Object.<anonymous> (file:///C:/deno_sap_rfc_test2/node_modules/.deno/node-rfc@2.7.0/node_modules/node-rfc/lib/index.js:20:14)
at Object.<anonymous> (file:///C:/deno_sap_rfc_test2/node_modules/.deno/node-rfc@2.7.0/node_modules/node-rfc/lib/index.js:79:4)
at Module._compile (ext:deno_node/01_require.js:974:34)

C:\deno_sap_rfc_test2>deno --version
deno 1.34.0 (release, x86_64-pc-windows-msvc)
v8 11.5.150.1
typescript 5.0.4`

test.ts:
`import noderfc from "npm:node-rfc"

(async () => {
const client = new noderfc.Client({ dest: "MME" });
await client.open();
})();
`

@JQ-pawelwypustek
Copy link
Author

I tried to run:
windbg deno run -A test.ts
and it gives:

4134:1498 @ 03545187 - LdrpFindLoadedDllInternal - RETURN: Status: 0x00000000 4134:1498 @ 03545187 - LdrGetDllHandleEx - RETURN: Status: 0x00000000 4134:1498 @ 03545187 - LdrpGetProcedureAddress - INFO: Locating procedure "NtWriteFile" by name 4134:35a4 @ 03546484 - LdrLoadDll - ENTER: DLL name: C:\deno_sap_rfc_test2\node_modules\.deno\node-rfc@2.7.1\node_modules\node-rfc\lib\binding\sapnwrfc.node 4134:35a4 @ 03546484 - LdrpLoadDllInternal - ENTER: DLL name: C:\deno_sap_rfc_test2\node_modules\.deno\node-rfc@2.7.1\node_modules\node-rfc\lib\binding\sapnwrfc.node 4134:35a4 @ 03546484 - LdrpResolveDllName - ENTER: DLL name: C:\deno_sap_rfc_test2\node_modules\.deno\node-rfc@2.7.1\node_modules\node-rfc\lib\binding\sapnwrfc.node 4134:35a4 @ 03546484 - LdrpResolveDllName - RETURN: Status: 0x00000000 4134:35a4 @ 03546484 - LdrpProcessWork - ERROR: Unable to load DLL: "C:\deno_sap_rfc_test2\node_modules\.deno\node-rfc@2.7.1\node_modules\node-rfc\lib\binding\sapnwrfc.node", Parent Module: "(null)", Status: 0xc000012f 4134:35a4 @ 03546484 - LdrpLoadDllInternal - RETURN: Status: 0xc000012f 4134:35a4 @ 03546484 - LdrLoadDll - RETURN: Status: 0xc000012f

code 0xc000012f is "Bad Image"
maybe that will help diagnose?

@JQ-pawelwypustek
Copy link
Author

I noticed something strange,
file sapnwrfc.node has Linux header (ELF) instead of Windows (PE):

C:\deno_sap_rfc_test2\node_modules.deno\node-rfc@2.7.1\node_modules\node-rfc\lib\binding\sapnwrfc.node

image

@JQ-pawelwypustek
Copy link
Author

same file on ubuntu:
user@pc:/media/user/k/temp$ readelf -h ./sapnwrfc.node
ELF Header:
Magic: 7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - GNU
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x15800
Start of program headers: 64 (bytes into file)
Start of section headers: 404432 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 11
Size of section headers: 64 (bytes)
Number of section headers: 30
Section header string table index: 29

@bsrdjan
Copy link

bsrdjan commented May 30, 2023

I noticed something strange, file sapnwrfc.node has Linux header (ELF) instead of Windows (PE):

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?

@JQ-pawelwypustek
Copy link
Author

it is installed automatically by deno,
my test case:

file test.ts:
import noderfc from "npm:node-rfc"
console.log(noderfc);

command:
deno run -A test.ts

automatically sapnwrfc.node gets downloaded:
AppData\Local\deno\npm\registry.npmjs.org\node-rfc\2.7.1\lib\binding\sapnwrfc.node
and file is with ELF header

@bsrdjan
Copy link

bsrdjan commented May 30, 2023

@JQ-pawelwypustek, I tested your test.ts on Arm64 Macbook and had the same issue: sapnwrfc.node for Linux landed in deno node_modules:

.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 import noderfc from "npm:node-rfc" always selects the Linux sapnwrfc.node, even on Arm or Windows systems.

@bsrdjan
Copy link

bsrdjan commented Jun 5, 2023

I tested in new created folder on MacOS as follows

test_noderfc.ts*

import noderfc from "npm:node-rfc";
console.log(noderfc);
deno run  --allow-read --allow-ffi --allow-sys test_noderfc.ts 
Error: /Users/d037732/Library/Caches/deno/npm/registry.npmjs.org/node-rfc/2.7.1/lib/binding/sapnwrfc.node' (not a mach-o file)

When /Users/d037732/Library/Caches/deno/npm/registry.npmjs.org/node-rfc/2.7.1/lib/binding/sapnwrfc.node replaced with sapnwrfc.node for arm64 platform, it works fine.

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.
As tested so far, it seems deno is always selecting Linux binary, even on MacOS and Windows platforms.

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?

@JQ-pawelwypustek
Copy link
Author

verbose:
deno run -A --log-level debug test.ts

I also tried:
deno run -A --node-modules-dir test.ts
and in this case library sapnwrfc.node is correct (windows)
But still there is some other problem with loading, running program shows same error:
Uncaught TypeError: LoadLibraryExW failed
Unfortunately, detailed information is missing even with --log-level debug

@bartlomieju
Copy link
Member

@bsrdjan thanks for investigating, I'm gonna ping @dsherret who recently implemented logic for selecting proper os/arch and might have more context how to solve the issue.

@bsrdjan
Copy link

bsrdjan commented Jun 6, 2023

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.

@dsherret
Copy link
Member

dsherret commented Jun 6, 2023

In the latest version, does it work on windows if you use --reload (ex. deno run --reload ...etc...)`? It might be using old out of date cache data which didn't include the platforms. We didn't cache bust for the platform change.

@dsherret
Copy link
Member

dsherret commented Jun 6, 2023

Sorry, actually I just got a reproduction on Windows and it doesn't work. I'm looking into it.

@dsherret
Copy link
Member

dsherret commented Jun 6, 2023

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:

> npm install --ignore-scripts node-rfc
> echo 'require("node-rfc")' > main.cjs
> node main.cjs
V:\scratch-npm\node_modules\node-rfc\lib\wrapper\noderfc-bindings.js:46
    throw err;
    ^

Error: \\?\V:\scratch-npm\node_modules\node-rfc\lib\binding\sapnwrfc.node is not a valid Win32 application.
\\?\V:\scratch-npm\node_modules\node-rfc\lib\binding\sapnwrfc.node

 The SAP NW RFC SDK could not be loaded, check the installation: https://github.com/SAP/node-rfc/blob/master/doc/installation.md#sap-nwrfc-sdk-installation
environment: 
...etc...

The reason the sapnwrf.node file is there is because it's distributed in the npm tarball: https://registry.npmjs.org/node-rfc/-/node-rfc-2.7.1.tgz

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 --ignore-scripts. It looks like this is using https://github.com/prebuild/prebuild which has a JS api https://github.com/prebuild/prebuild#javascript-api (though it's async)

@bsrdjan
Copy link

bsrdjan commented Jun 7, 2023

Deno does not run pre/post install scripts as Bartek mentioned

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.

@bsrdjan
Copy link

bsrdjan commented Jun 7, 2023

@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 ?

@bsrdjan
Copy link

bsrdjan commented Jun 30, 2023

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?

@JQ-pawelwypustek
Copy link
Author

can you give me a hint how to run this version?
tried:
import noderfc from "npm:node-rfc@3.0.0-rc1"
with no luck :(
error: Could not find npm package 'node-rfc' matching '3.0.0-rc1'

@bsrdjan
Copy link

bsrdjan commented Jul 3, 2023

it is '3.0.0-rc.1', the point is missing in "npm:node-rfc@3.0.0-rc1"

@JQ-pawelwypustek
Copy link
Author

deno:
test.ts:
import noderfc from "npm:node-rfc@3.0.0-rc.1"

deno run -A test.ts
outputs:
error: Could not resolve 'npm:node-rfc@3.0.0-rc.1'. Caused by: not found

when I try nodejs:
npm install node-rfc@3.0.0-rc.1
downloads package but .\node_modules\node-rfc\lib\binding\sapnwrfc.node is not win32-x64 (no MZ header in file)
and trying to run
node test.js

error:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'node-rfc@3.0.0-rc.1'

@bsrdjan
Copy link

bsrdjan commented Jul 4, 2023

the bug is fixed, please try 3.0.0-rc.2

@JQ-pawelwypustek
Copy link
Author

The error is not displayed now!
Although when I run this test it silently exits, it only shows "debug1":

import noderfc from "npm:node-rfc@3.0.0-rc.2"
console.log("debug1");
let client = new noderfc.Client({
"user": "",
"passwd": ""
",
"ashost": """,
"sysnr": ""
",
"client": ""*****"
});
console.log("debug2");

In nodejs this example works fine

@bsrdjan
Copy link

bsrdjan commented Jul 5, 2023

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
#16490

@bsrdjan
Copy link

bsrdjan commented Jul 17, 2023

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.

@JQ-pawelwypustek
Copy link
Author

It looks like it works great, thanks, Srdjan!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs investigation requires further investigation before determining if it is an issue or not node compat node native extension related to the node-api (.node)
Projects
None yet
Development

No branches or pull requests

4 participants