Java和GraalJs ScriptEngine如何与变量交互

lmyy7pcs  于 2023-06-04  发布在  Java
关注(0)|答案(1)|浏览(243)

现在,我正在尝试通过GraalJS在Java应用程序中执行Javascript。下面是我的代码:

import javax.script.*;
import java.util.List;
import java.util.Map;

public class ScriptExec {

    public static void main(String[] args) throws ScriptException {
        System.setProperty("polyglot.engine.WarnInterpreterOnly", "false");

        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("js");
        Bindings bindings = engine.createBindings();

        // variables
        int num = 9;
        String hello = "bye";
        String[] strings = new String[]{"a", "string", "array"};
        List<String> stringList = List.of("a", "string", "list");
        Map<String, Object> kvs = Map.of("a", "b", "object", "...", "map", "container");

        bindings.put("num", num); 
        bindings.put("hello", hello);
        bindings.put("strings", strings);
        bindings.put("stringList", stringList);
        bindings.put("kvs", kvs);

        engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
        String js = """
                console.log(num)
                console.log(hello)
                console.log(JSON.stringify(strings))
                console.log(JSON.stringify(stringList))
                console.log(JSON.stringify(kvs))
                for(let str in strings) {
                    console.log('str: ' + str)
                }
                for(let k in kvs) {
                    console.log('key: ' + k)
                }
                """;
        engine.eval(js);
    }
}
  • 控制台输出为:
9
bye
{}
{}
{}

如您所见,只有整型和String变量绑定成功。

  • JDK版本:17
  • GraalJS依赖项:
<dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js</artifactId>
    <version>22.3.2</version>
</dependency>
<dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js-scriptengine</artifactId>
    <version>22.3.2</version>
</dependency>

1.数组、列表和Map类型变量是怎么回事?2.如何解决这个问题?

luaexgnf

luaexgnf1#

好的,我从here找到答案

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;

import javax.script.ScriptException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ScriptExec {

    public static void main(String[] args) throws ScriptException {
        System.setProperty("polyglot.engine.WarnInterpreterOnly", "false");

        // Get a polyglot context for Graal guest languages(here is JavaScript)
        Context context = Context.newBuilder("js")
                .allowAllAccess(true) // if not allow, you still cannot access the array/list/object members
                .build();

        // Variables
        var num = 9;
        var hello = "bye";
        var strings = new String[]{"a", "string", "array"};
        var stringList = List.of("a", "string", "list");
        var kvs = new HashMap<>(Map.of("a", "ok", "object", 1, "container", "..."));

        // Pass java variable to GraalJS polyglot context
        Value bindings = context.getBindings("js");

        bindings.putMember("num", num);
        bindings.putMember("hello", hello);
        bindings.putMember("strings", strings);
        bindings.putMember("stringList", stringList);
        bindings.putMember("kvs", kvs);

        // JavaScript code
        var script = """
                console.log(num)
                console.log(hello)
                console.log(JSON.stringify(strings))
                console.log(JSON.stringify(stringList))
                console.log(JSON.stringify(kvs.toString()))
                for(let index in strings) {
                    console.log("index:", index, ", value:", strings[index])
                }
                for(let k in kvs) {
                    console.log(k)
                }
                """;

        // Evaluate the code
        context.eval("js", script);

        // Release resources
        context.close();
    }
}

上面代码,没有显式创建ScriptEngine。Graal的多语言环境起了作用。
也可以先创建ScriptEngine,然后将特定的多语言上下文传递给它。special表示主机资源访问控制配置(allowXXX...)。
如果有新内容,请稍后发布

相关问题