GraalJs - 调用 java 对象的构造函数
GraalJs - call constructor of java object
我想使用 graal js 为我的应用程序提供一些脚本扩展
如何在 java 脚本端初始化一个新的 java 对象?
Context ctx = Context ctx = Context.newBuilder().allowHostAccess(HostAccess.ALL).allowAllAccess(true).build().create();
Value binding = ctx.getBindings("js");
binding.putMember("ArrayList", ArrayList.class);
ctx.eval("js","let list = new ArrayList();list.add(\"1\")");
List list = binding.getMember("list").as(List.class);
assert list.size() == 1;
以下代码抛出异常
Exception in thread "main" TypeError: instantiate on JavaClass[java.util.ArrayList] failed due to: Message not supported.
at <js> :program(Unnamed:1:13-27)
at org.graalvm.polyglot.Context.eval(Context.java:371)
运行 graalvm-ce-java11 19.3.2
您需要使用 Java.type
。
这是取自 https://www.graalvm.org/docs/reference-manual/polyglot/
的示例
var array = new (Java.type("int[]"))(4);
array[2] = 42;
console.log(array[2])
这是一个使用 GraalVM 20.0.0 测试的完全可运行的示例
import org.graalvm.polyglot.*;
class M {
public static void main(String[] args) {
try (Context context = Context.newBuilder().allowAllAccess(true).build()) {
java.util.ArrayList v = context.eval("js",
"var ArrayList = Java.type('java.util.ArrayList');" +
"var list = new ArrayList();" +
"list.add(1); list").asHostObject();
System.out.println(v.get(0));
assert v.get(0).equals(1);
}
}
}
运行 与
graalvm-ce-java8-20.0.0/bin/javac M.java
graalvm-ce-java8-20.0.0/bin/java -ea M
得到 1
作为输出。
您也可以使用 sj4js 库。在那里你可以定义无缝融入 JS 的构造函数。
// we create a new JS engine and add
// TestClass as a constructor. This constructor is added to globalThis such that it
// can be called as a costructor.
try (JScriptEngine engine = new JScriptEngine(new JsGlobalThis(),"gt")) {
engine.addConstructor(new TestClass("empty"));
/* call your js code here */
}
您的 JS 代码看起来不像您期望的那样。
// we create a new variable from the constructor
var tc = new TestClass("test");
console.log(tc.name)
// test
我想使用 graal js 为我的应用程序提供一些脚本扩展
如何在 java 脚本端初始化一个新的 java 对象?
Context ctx = Context ctx = Context.newBuilder().allowHostAccess(HostAccess.ALL).allowAllAccess(true).build().create();
Value binding = ctx.getBindings("js");
binding.putMember("ArrayList", ArrayList.class);
ctx.eval("js","let list = new ArrayList();list.add(\"1\")");
List list = binding.getMember("list").as(List.class);
assert list.size() == 1;
以下代码抛出异常
Exception in thread "main" TypeError: instantiate on JavaClass[java.util.ArrayList] failed due to: Message not supported.
at <js> :program(Unnamed:1:13-27)
at org.graalvm.polyglot.Context.eval(Context.java:371)
运行 graalvm-ce-java11 19.3.2
您需要使用 Java.type
。
这是取自 https://www.graalvm.org/docs/reference-manual/polyglot/
的示例var array = new (Java.type("int[]"))(4);
array[2] = 42;
console.log(array[2])
这是一个使用 GraalVM 20.0.0 测试的完全可运行的示例
import org.graalvm.polyglot.*;
class M {
public static void main(String[] args) {
try (Context context = Context.newBuilder().allowAllAccess(true).build()) {
java.util.ArrayList v = context.eval("js",
"var ArrayList = Java.type('java.util.ArrayList');" +
"var list = new ArrayList();" +
"list.add(1); list").asHostObject();
System.out.println(v.get(0));
assert v.get(0).equals(1);
}
}
}
运行 与
graalvm-ce-java8-20.0.0/bin/javac M.java
graalvm-ce-java8-20.0.0/bin/java -ea M
得到 1
作为输出。
您也可以使用 sj4js 库。在那里你可以定义无缝融入 JS 的构造函数。
// we create a new JS engine and add
// TestClass as a constructor. This constructor is added to globalThis such that it
// can be called as a costructor.
try (JScriptEngine engine = new JScriptEngine(new JsGlobalThis(),"gt")) {
engine.addConstructor(new TestClass("empty"));
/* call your js code here */
}
您的 JS 代码看起来不像您期望的那样。
// we create a new variable from the constructor
var tc = new TestClass("test");
console.log(tc.name)
// test