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

Referencing a nuget package in dotnetcore #463

Closed
raffaeler opened this issue Jul 27, 2016 · 10 comments
Closed

Referencing a nuget package in dotnetcore #463

raffaeler opened this issue Jul 27, 2016 · 10 comments

Comments

@raffaeler
Copy link

I followed the readme.md instructions and wrote the nuget package name in the "assemblyFile" field.
When I run the node app, I get the following error:
Error: Could not load file or assembly 'file:///H:\DemoNode\ExpressApp1\Plugin2\NetCoreLibrary' or one of its dependencies. The system cannot find the file specified.

If instead I reference the dll directly, I get this other error:
Error: Could not load file or assembly 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Invalid pointer (Exception from HRESULT: 0x80004003 (E_POINTER))

Hints? Pointers?

P.S. If the dll is compiled in net46 everything works fine. I am testing on Windows.
Thank you

@lstratman
Copy link
Contributor

What's the actual command line that you're using to invoke your application? Are you using EDGE_USE_CORECLR=1 and EDGE_APP_ROOT=/path/to/dir/containing/depsjson as environment variables when doing so? Can you include the Node.js code where you use edge.func() to load the function?

@raffaeler
Copy link
Author

I am not using those env vars.
I will post the relevant code tomorrow when I am back in my office.

For sure I am doing something wrong, but I could not find any small sample to follow.
Thanks

@raffaeler
Copy link
Author

Hi @lstratman sorry for the delay.
I am still confused about the configuration.
I recompiled edge to work with the latest 6.5.0 node and everything works well with .net desktop
I now restarted from the edge func of the readme.md (hello world echoed).
The scenario is now the following:

  • a .net core library packaged in a nuget package and available locally on a shared folder
  • a nuget.config including the local share nuget folder so that dotnet restore can find the package
  • a simple node script using the hello world and invoking the clr method

Questions:

  • where do I find a sample with the complete reference of these configurations?
  • when the readme talks about the project.json, is it referred to the node project or the .net project? (from the doc it looks like both). Obviously they live in different folders
  • how do i specify the nuget package? I tried to use the env variables as you and the readme.md cited, but node still looks for a dll file and not the nuget package.

If only there was a single simple example with the steps to follow, everything would not be so frustrating...
Thanks

@lstratman
Copy link
Contributor

The documentation definitely needs some work and will be improved. If you have a pre-existing .NET Core library that you want to make use of through node, you'll need to do the following:

  1. Create a new directory and dotnet new a stub .NET Core project. By default, dotnet new will create a project.json for an application project, which is necessary to tie all of the dependencies for your .NET code together so that Edge.js knows where to load everything from. An application project will generate a .deps.json file containing these dependencies, whereas a simply library project will not (this might be the missing link you need to get everything working). The project.json for this stub will look something like this:
"frameworks": {
  "netcoreapp1.0": {
    "dependencies": {
      "Microsoft.NETCore.App": {
        "type": "platform",
        "version": "1.0.0"
     },
    "Edge.js": "6.5.0",
    "Your.NuGet.Library": "1.2.3"
  }
}
  1. Run dotnet restore and dotnet build to restore and build the stub project. In the bin/Debug/netcoreapp1.0 folder, you should see a .deps.json file containing all of the dependencies for your application, including the Edge.js runtime library and your NuGet package.

  2. In your Node.js code, load your .NET functions like:

    var func = edge.func({
      assemblyFile: 'Your.NuGet.Library',
      typeName: 'MyClass',
      methodName: 'MyMethod'
    });

    Note how you're not specifying a full assembly path in the assemblyFile property; all you need to do is reference the NuGet package name and Edge.js can figure out where to load it from.

  3. When running your application, invoke it like: EDGE_USE_CORECLR=1 EDGE_APP_ROOT=/dir/from/step1/bin/Debug/netcoreapp1.0 node application.js. When you point EDGE_APP_ROOT to the directory containing the .deps.json, the Edge.js runtime knows where to load all of the necessary assemblies from and can resolve methods like those in step 3 properly.

I hope this helps. Again, we will be improving the documentation so that this is easier to pick up going forward, but this should get you started.

@raffaeler
Copy link
Author

Great explanation, thank you @lstratman
I will put all together in the weekend and eventually post here other details to help others.
Thanks

@raffaeler
Copy link
Author

raffaeler commented Sep 17, 2016

Hi @lstratman I still can't make it work.
I've done all the described steps ... dotnet restore, build and all the rest with no errors.
It is still looking for the file on the current folder instead of the package referenced by the 'bridge' app.
Using Process Monitor I can see the failed attempt to open "H:\dev.node\HelloEdge\NetCoreLibrary"

When I run the node app (the plain hello world) the result is:

H:\dev.node\HelloEdge>node Edge3.js
Load edge native library from: H:\Samples\NodeEdge2\edge\lib\native\win32\x64\6.5.0\edge_nativeclr.node
edge::init
V8SynchronizationContext::Initialize
V8SynchronizationContext::Unref
ClrFunc::Initialize MethodInfo wrapper
ClrFunc::MarshalCLRExceptionToV8
ClrFunc::MarshalCLRObjectToV8
ClrFunc::MarshalCLRObjectToV8

H:\dev.node\HelloEdge\node_modules\edge\lib\edge.js:170
    return edge.initializeClrFunc(options);
                ^
Error: Could not load file or assembly 'file:///H:\dev.node\HelloEdge\NetCoreLibrary' or one of its dependencies. The system cannot find the file specified.
    at Error (native)
    at Object.exports.func (H:\dev.node\HelloEdge\node_modules\edge\lib\edge.js:170:17)
    at Object.<anonymous> (H:\dev.node\HelloEdge\Edge3.js:6:23)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.runMain (module.js:590:10)
    at run (bootstrap_node.js:394:7)
about:blank

The env vars of the cmd are:
H:\dev.node\HelloEdge>set | find "EDGE"

EDGE_APP_ROOT=H:\dev.node\HelloEdge\bridge\bin\Debug\netcoreapp1.0
EDGE_DEBUG=1
EDGE_NATIVE=H:\Samples\NodeEdge2\edge\lib\native\win32\x64\6.5.0\edge_nativeclr.node
EDGE_USE_CORECLR=1

and the deps.json is there:

 Directory of H:\dev.node\HelloEdge\bridge\bin\Debug\netcoreapp1.0
17-Sep-16  11:09    <DIR>          .
17-Sep-16  11:09    <DIR>          ..
17-Sep-16  11:42             4,891 bridge.deps.json
17-Sep-16  11:42             4,608 bridge.dll
17-Sep-16  11:42               416 bridge.pdb
17-Sep-16  11:42               120 bridge.runtimeconfig.dev.json
17-Sep-16  11:42               125 bridge.runtimeconfig.json
               5 File(s)         10,160 bytes

This is the bridge\project.json:

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0"
        },

        "Edge.js": "6.5.0",
        "NetCoreLibrary": "1.0.0"

      },
      "imports": "dnxcore50"
    }
  }
}

And this is the app:

var edge = require('edge');

var helloWorld = edge.func({
    assemblyFile: 'NetCoreLibrary',
    typeName: 'NetCoreLibrary.NetDemo',
    methodName: 'Greet'
});

helloWorld('JavaScript', function (error, result) {
    if (error) throw error;
    console.log(result);
});

@lstratman
Copy link
Contributor

Raf, the problem is that you have the EDGE_NATIVE environment variable set explicitly and you have it pointing to the non-.NET core Node.js native extension for Edge. This causes Edge to use the desktop CLR instead of .NET Core.  Once you take out that environment variable, Edge will then load the proper native extension based on the EDGE_USE_CORECLR environment variable and you should be good to go.

From: Raf

Sent: Saturday, September 17, 6:05 AM

Subject: Re: [tjanczuk/edge] Referencing a nuget package in dotnetcore (#463)

To: tjanczuk/edge

Cc: Luke Stratman, Mention

Hi @lstratman I still can't make it work.

I've done all the described steps ... dotnet restore, build and all the rest with no errors.

It is still looking for the file on the current folder instead of the package referenced by the 'bridge' app.

Using Process Monitor I can see the failed attempt to open "H:\dev.node\HelloEdge\NetCoreLibrary"

When I run the node app (the plain hello world) the result is:

H:\dev.node\HelloEdge>node Edge3.js Load edge native library from: H:\Samples\NodeEdge2\edge\lib
ative\win32\x64\6.5.0\edge_nativeclr.node edge::init V8SynchronizationContext::Initialize V8SynchronizationContext::Unref ClrFunc::Initialize MethodInfo wrapper ClrFunc::MarshalCLRExceptionToV8 ClrFunc::MarshalCLRObjectToV8 ClrFunc::MarshalCLRObjectToV8 H:\dev.node\HelloEdge
ode_modules\edge\lib\edge.js:170 return edge.initializeClrFunc(options); ^ Error: Could not load file or assembly 'file:///H:\dev.node\HelloEdge\NetCoreLibrary' or one of its dependencies. The system cannot find the file specified. at Error (native) at Object.exports.func (H:\dev.node\HelloEdge
ode_modules\edge\lib\edge.js:170:17) at Object. (H:\dev.node\HelloEdge\Edge3.js:6:23) at Module._compile (module.js:556:32) at Object.Module._extensions..js (module.js:565:10) at Module.load (module.js:473:32) at tryModuleLoad (module.js:432:12) at Function.Module._load (module.js:424:3) at Module.runMain (module.js:590:10) at run (bootstrap_node.js:394:7) about:blank

The env vars of the cmd are:

H:\dev.node\HelloEdge>set | find "EDGE"

EDGE_APP_ROOT=H:\dev.node\HelloEdge\bridge\bin\Debug
etcoreapp1.0 EDGE_DEBUG=1 EDGE_NATIVE=H:\Samples\NodeEdge2\edge\lib
ative\win32\x64\6.5.0\edge_nativeclr.node EDGE_USE_CORECLR=1

and the deps.json is there:

Directory of H:\dev.node\HelloEdge\bridge\bin\Debug
etcoreapp1.0 17-Sep-16 11:09

. 17-Sep-16 11:09 .. 17-Sep-16 11:42 4,891 bridge.deps.json 17-Sep-16 11:42 4,608 bridge.dll 17-Sep-16 11:42 416 bridge.pdb 17-Sep-16 11:42 120 bridge.runtimeconfig.dev.json 17-Sep-16 11:42 125 bridge.runtimeconfig.json 5 File(s) 10,160 bytes

This is the bridge\project.json:

{ "version": "1.0.0-*", "buildOptions": { "debugType": "portable", "emitEntryPoint": true }, "dependencies": {}, "frameworks": { "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { "type": "platform", "version": "1.0.0" }, "Edge.js": "6.5.0", "NetCoreLibrary": "1.0.0" }, "imports": "dnxcore50" } } }

And this is the app:

var edge = require('edge');

var helloWorld = edge.func({ assemblyFile: 'NetCoreLibrary', typeName: 'NetCoreLibrary.NetDemo', methodName: 'Greet' }); helloWorld('JavaScript', function (error, result) { if (error) throw error; console.log(result); });

You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub, or mute the thread.

@raffaeler
Copy link
Author

Thank you again @lstratman
I used the EDGE_NATIVE because I recompiled edge to get advantage of node 6 (I need this on Windows because of the MAX_PATH issue).
I've seen that a newer release of edge supporting node6 has been released in the meanwhile, so I'll upgrade all the stuff and retry.

But out of my curiosity, how can I use netcore when I have to rebuild edge locally? It may happen in the future whenever I need to use edge with a node release that is not supported yet ...

@lstratman
Copy link
Contributor

If you need to use EDGE_NATIVE with .NET Core, just make sure that the path
in that variable points to edge_coreclr.node instead of edge_nativeclr.node.

On Sat, Sep 17, 2016 at 11:02 AM, Raf notifications@github.com wrote:

Thank you again @lstratman https://github.com/lstratman
I used the EDGE_NATIVE because I recompiled edge to get advantage of node
6 (I need this on Windows because of the MAX_PATH issue).
I've seen that a newer release of edge supporting node6 has been released
in the meanwhile, so I'll upgrade all the stuff and retry.

But out of my curiosity, how can I use netcore when I have to rebuild edge
locally? It may happen in the future whenever I need to use edge with a
node release that is not supported yet ...


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#463 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AABgDHor_SXmXb91233MxxDDK6cyvq1bks5qrAEEgaJpZM4JWE-j
.

@raffaeler
Copy link
Author

@lstratman yes, it finally worked, thank you very much.

I believe all these "details" are worth the docs with some deep-dive for people willing to experiment.
Last question: should I call a C++ library (no .net), what is the best way to interop with node? Should I go with gyp/nan or what else?
Thank you

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