oracle / graaljs

A ECMAScript 2023 compliant JavaScript implementation built on GraalVM. With polyglot language interoperability support. Running Node.js applications!
Universal Permissive License v1.0
1.7k stars 185 forks source link

passing nodejs function type as an argument #248

Open RoySRose opened 4 years ago

RoySRose commented 4 years ago

Is there anyway to invoke node js method 'on' from java side. which have argument 'function'?

Below is Java code. result variable is ClientRequest object in nodejs. lib.invokeMember(result, "on", "response", listenerFunction);

I can invoke on function but causes error. Caused by: com.oracle.truffle.js.runtime.JSException: TypeError:

I understand this behavior since type of listenerFunction is not supported in JavaScript. Is there a way to take care of this? I need a way to add an event to ClientRequest object from java side.

Anyone tried this before?

I've tried to get the function with jsContext and putting it to the place of listenerFunction. getting Caused by: com.oracle.truffle.js.runtime.JSException: TypeError: type Value not supported in JavaScript This is also same with what I'm trying to do above. Just sharing to help the readers understand my intention

Value function = jsContext.eval("js", "res => {\n" +
                    "            res.on('end', () => {\n" +
                    "                console.log('does this work?');\n" +
                    "            })\n" +
                    "        }");
lib.invokeMember(result, "on", "response", function);
iamstolis commented 4 years ago

You are not supposed to use org.graalvm.polyglot API in instruments. I would try to create listenerFunction using TruffleInstrument.Env.parse().call().

RoySRose commented 4 years ago

@iamstolis Thank you for your reply.

Even if I create listenerFunction using TruffleInstrument.Env.parse().call() Shouldn't it be still cause problem while passing function type from java to Nodejs?

If you can share any simple example, it will be a great help to me. Thank you in advance.

iamstolis commented 4 years ago

Even if I create listenerFunction using TruffleInstrument.Env.parse().call() Shouldn't it be still cause problem while passing function type from java to Nodejs?

The error that you see does not complain about passing of functions. It complains about passing of an instance of Value i.e. a type from org.graalvm.polyglot API that is not supposed to be used by instruments (where the direct usage of truffle API is expected).

If you can share any simple example, it will be a great help to me.

I am sorry, I am not going to provide you a simple example as I don't understand what you are trying to achieve. Maybe you can elaborate on that a bit. I am not sure if you are using the right tool for your task. Personally, I find the creation and registration of a HTTP response handler rather high-level task for a truffle instrument.

RoySRose commented 4 years ago

Hello, @iamstolis. My bad. I only gave you so little info on what I'm trying to achieve.

I'm one of the maintainers of Project Pinpoint, which is an open source APM project.

For the recent few months, I've been working on a graal-agent(temporary name) which will make polyglot applications on GRAALVM monitorable with Pinpoint. Currently Pinpoint uses bytecode instrumentation for java applications. So no need for changing the application's code to monitor. With truffle instrumentation, I think it's also possible to trace polyglot applications without changing any code.

So far(with so much help from the GRAAL team), I'm working/testing on NODE.js server/client. I've managed to alter HTTP request and response with truffle instrumentation(such as adding/reading headers and so). Recently, I thought it would be best to add an event with eventEmitter.on() for the request listener.

  1. So I'm trying to find a way to add an event with eventEmitter.on() to ClientRequest (with truffle instrumentation) which is accessible with VirtualFrame from com.oracle.truffle.api.instrumentation.ExecutionEventNode.onEnter(VirtualFrame)
  2. Hoping this is possible so that polyglot applications can be traceable without changing a single line of code.

It's only been a few months since I've been playing around with Graalvm. I'm still learning it. Thank you for reading :)