I need to embed j2v8-4.6.0 library (bindings for JavaScript engine, V8) for use in neo4j-community-3.1.0 (graph database management system) user-defined functions.
So, code of my simple plugin:
package js;
import org.neo4j.procedure.*;
import com.eclipsesource.v8.*;
public class J2V8
{
public static V8 v8 = V8.createV8Runtime();
@UserFunction("js.eval")
@Description("js.eval(code) - eval the given javascript code.")
public String eval( @Name("code") String code)
{
if (code == null) code = "";
try {
int result = v8.executeIntegerScript(code);
return result + "";
} catch (final Exception se) { return se.toString(); }
}
}
The plugin is compiled and installed correctly. And the first call of the user function js.eval
occurs without error. But a second call (as well as all of the following) gives an error:
Failed to invoke function `js.eval`: Caused by: java.lang.Error:
Invalid V8 thread access
I have read that J2V8 enforces single threaded and all access to a single runtime must be from the same thread.
This means that every time when call a user function, it is necessary to create the runtime (V8.createV8Runtime
). But this is a costly operation.
So the question is: how to avoid the need to create the V8 runtime every time when call a function, and reuse once created V8 runtime?
You can release the Locker after finish execution and acquire Locker again before execution.