1

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?

ItamarG3
  • 4,092
  • 6
  • 31
  • 44
stdob--
  • 28,222
  • 5
  • 58
  • 73

1 Answers1

0

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();
gevge
  • 399
  • 2
  • 6