在GraalVM CE上跑步。
openjdk version "11.0.5" 2019-10-15
OpenJDK Runtime Environment (build 11.0.5+10-jvmci-19.3-b05-LTS)
OpenJDK 64-Bit GraalVM CE 19.3.0 (build 11.0.5+10-jvmci-19.3-b05-LTS, mixed mode, sharing)
案例一:
import org.graalvm.polyglot.Context;
public class Test {
static class Data {
public String name = "HelloWorld";
public String getName() {
return this.name;
}
}
public static void main(String[] args) {
Context context = Context.newBuilder("js").allowHostAccess(true).build();
context.getBindings("js").putMember("d", new Data());
context.eval("js", "var x = d.name");
System.out.println(
context.getBindings("js").getMember("x").asString()
);
}
}
结果:
null
为什么?
据我所知,d
正确通过:
((Data) context.getBindings("js").getMember("d").as(Data.class)).name
返回"HelloWorld"
。
案例2:
context.eval("js", "d.getName()");
例外情况
Exception in thread "main" TypeError: invokeMember (getName)
on JavaObject[task.Test$Data@35a3d49f (task.Test$Data)] failed due to:
Unknown identifier: getName
但是getName
是公共的。。。发生了什么?
GraalVM JavaScript默认强制执行严格的沙箱规则,其中之一是JavaScript代码不能访问主机Java对象,除非用户明确允许。允许代码访问context.eval(“js”、“d.getName()”)的最简单方法是传递选项polyglot.js.allowAllAccess=true,如下链接所述:
GraalVM JavaScript脚本引擎实现
请看一下示例:
import org.graalvm.polyglot.Context;
public class Test {
static class Data {
public String name = "HelloWorld";
public String getName() {
return this.name;
}
}
public static void main(String[] args) {
Context context = Context.newBuilder("js").allowHostAccess(true).build();
context.getBindings("js").putMember("d", new Data());
context.eval("js", "var x = d.getName()");
System.out.println(
context.getBindings("js").getMember("d").as(Data.class)).name
);
}
}
当您使用上下文并向其中添加Java对象时,在场景后面,TruffleApp内部的IntropLibrary会创建一个HostObject并将其与该对象关联。这意味着您不使用对象本身,而是使用包装器对象。
调用getMember()方法时,IntropLibrary只能访问托管对象中公开可用的字段和方法。由于内部类具有默认访问权限(无访问修饰符),因此API无法找到其成员,即使它们是公共的。(类的成员不能拥有比其类本身更广泛的访问权限)。
要解决这个问题,你所要做的就是公开你的内心世界
import org.graalvm.polyglot.Context;
public class Test {
public static class Data {
public String name = "HelloWorld";
public String getName() {
return this.name;
}
}
public static void main(String[] args) {
Context context = Context.newBuilder("js").allowHostAccess(true).build();
context.getBindings("js").putMember("d", new Data());
context.eval("js", "var x = d.name;");
System.out.println(
context.getBindings("js").getMember("x").asString()
);
}
}
您需要用@HostAccess注释类字段和方法。出口
默认情况下,只有使用@HostAccess注释的公共类、方法和字段。可以使用来宾语言进行导出。可以使用上下文自定义此策略。建设者构造上下文时允许访问(主机访问)。
使用JavaScript中的Java对象的示例:
public class JavaRecord {
@HostAccess.Export public int x;
@HostAccess.Export
public String name() {
return "foo";
}
}
或者,您可以使用GraalVM JSR-223 ScriptEngine
GraalVM JavaScript提供了符合JSR-223的javax。剧本脚本引擎实现。请注意,这是出于遗留原因而提供的功能,以便为当前基于ScriptEngine的实现提供更轻松的迁移。我们强烈鼓励用户使用该组织。格拉尔文。通晓多种语言。上下文接口
要通过绑定设置选项,请使用绑定。在初始化引擎的脚本上下文之前放置(,true)。请注意,即使是对Bindings#get(String)的调用也可能导致上下文初始化。下面的代码显示了如何启用polyglot。js。允许通过绑定访问:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("polyglot.js.allowHostAccess", true);
bindings.put("polyglot.js.allowHostClassLookup", (Predicate<String>) s -> true);
bindings.put("javaObj", new Object());
engine.eval("(javaObj instanceof Java.type('java.lang.Object'));"); // would not work
如果没有allowHostAccess和allowHostClassLookup,如果用户调用例如engine,该示例将不起作用。评估(“var x=1;”)在调用绑定之前。put(“polyglot.js.allowostaccess”,true);,因为对eval的任何调用都会强制进行上下文初始化。
问题内容: 问题答案: 你不能 JavaScript中没有向上关系。 举个例子: 现在,单个数组对象具有两个“父级”。 您可以做的是:
问题内容: 有没有可以让我在Firefox中操纵文件下载对话框的API?(我想访问用户做某事时显示的内容,而不是自己发起)。 我想做的是从Selenium访问此对话框(我不确定Selenium的“特权模式”是否足以访问chrome接口)。 问题答案: 从来没听说过。但是您可以将Firefox配置为自动开始下载并将文件保存在特定位置。然后,您的测试可以检查文件是否实际到达。
问题内容: 就像是 这是我想象的格式,但事实并非如此。什么会退回到对象的父级? 问题答案: JavaScript本身不提供此功能。而且我怀疑您是否可以创建这种类型的功能。例如: 鲍比属于谁?
我有一些测试(我没有编写它们,我正在维护它们)使用spring ContextConfiguration注释来提供应用程序上下文: 总之,有几个问题。我不太熟悉spring自定义上下文位置,这些位置不指定file:/或classpath:/。这是什么意思?这个测试类路径上有很多同名的资源。都上膛了吗?如果不是,Spring如何知道要加载哪个? 第二,有没有一种方法可以通过编程方式访问以这种方式连接
问题内容: 我试图将一些Scala代码注入到现有的Java应用程序中。(所以,话说回来,我想要更多的乐趣)。 我在Scala中创建一个单例的东西 现在,在OldJava.java中 我应该填写什么以便Java调用showMyPower方法?我尝试了两者 ,但没有任何效果。 (使用Jad反编译类文件,除了胡说八道之外,什么都没给我显示。) 编辑 我删除了声明,scala产生了预期的静态方法。(呼吁工