Embedding j2v8 library in neo4j and reuse of the V8 runtime

618 views Asked by At

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?

1

There are 1 answers

0
gevge On

You can release the Locker after finish execution and acquire Locker again before execution.

if(v8==null) createV8Runtime();
v8.getLocker().acquire();
// execute your js here
v8.getLocker().release();