问题标签 [graaljs]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
70 浏览

javascript - 使用 GraalJS/GraalVM 在 Java 中实现 Firestore

目前我正在尝试使用 GraalJS 让 Firestore Web 实现在 Java 中工作。不幸的是,在我的用例中,我无法直接使用 Java 实现。

我已经用 OpenJDK15,16 和 GraalVM21.1 Java 16 试过了

一旦我在 firefox 的 devtools 中运行我的 JavaScript 代码,一切正常,我得到的承诺得到履行,并且数据被设置在 firestore 中:

但是当我用 GraalJS 运行代码时,我只是被 System.out.println(result); 返回 并且数据未在 Firestore 中成功设置

这是我的 Java 代码:

这是我的 script.js 文件,用 Java 调用:

0 投票
0 回答
85 浏览

java - 未找到模块 org.graalvm.sdk,com.oracle.truffle.regex 需要

我在 OpenJDK VM 上运行 java 16 应用程序。

在运行时我需要从 jar 二进制文件中加载 Graal JS。

请注意,我无法访问应用程序的启动标志,无法更改默认类加载器,无法将 graal 二进制文件隐藏到我的 jar 中,也无法将 OpenJDK 更改为 GraalVM。

根据https://docs.oracle.com/en/graalvm/enterprise/20/docs/reference-manual/js/RunOnJDK/

我将需要以下 jar 以进行最少的设置

这些 jars 从 maven Central 下载到本地文件系统。现在我需要在运行时将类添加到类路径中。

在 java 16 之前,我们可以使用 URLClassloader#addUrl 方法。但是现在有了 java 16,生态系统对模块封装更加严格,这不再是一种选择。

我试图利用 java 模块 api。

ModuleFinder 在目录中找到所有 jars/modules,但是在尝试解析配置 jvm 时会抛出

未找到模块 org.graalvm.sdk,com.oracle.truffle.regex 需要

0 投票
0 回答
525 浏览

java - org.graalvm.polyglot.PolyglotException:ReferenceError:文档未定义

我正在使用 Spring boot 2.4.4、JDK 1.8,并创建了 ScriptEngine,如图所示。页面第一次加载完美,但第二次抛出下面提到的异常。

0 投票
1 回答
234 浏览

java - 如何在java / graalvm中加载具有多个函数(每个文件同名)的js文件并通过文件名调用函数

我有一个服务器应用程序,它在启动时加载几个脚本文件(用于处理特定的数据集字段)。应该解析脚本并且脚本的“表达式”数据应该存储在映射中(按列名),以便以后可以从那里访问和执行它们。

有两种类型的脚本。“简单”的仅包含一个process函数,复杂的当前具有类似于以下示例的结构(可能具有更多私有函数/字段):

process并且selfTest是服务器应用程序将使用的“公共”功能。selfTest将在文件加载/评估后执行一次,并process在需要时为传入的数据执行。


我从旧的 JSR 223 方式开始:

这种方法的问题是函数数据存储在 javascript 引擎实例中,因此我的地图中不能有多个“处理”方法。
我可以继续这种方式并根据列名动态生成函数和全局变量的名称前缀......但那是......“丑陋”......


我已经尝试过 graalvm-context-way (在 SO 和 Oleg 的帮助下,如何从 ScriptManager 存储函数句柄以供以后使用?):

这适用于“简单”功能。但是对于复杂的脚本,上面的函数表达式方式不起作用。


编辑(解决方案):

稍微修改了奥列格的答案,这似乎可以完成工作......

0 投票
1 回答
82 浏览

javascript - 如何访问传递给 scriptEngine 的 Java 对象的属性?

我正在使用 engine.put() 方法将对象传递给 scriptEngine,并尝试使用 engine.eval() 方法检索所述对象的属性。但是我似乎无法访问它们,因为对象在放入引擎时似乎失去了它的方法,而且我通常在 Javascript 中使用的 get() 方法似乎也失败了。

我读过 scriptEngine 只从公共类中导入公共方法。在这种情况下,虽然 TransformContext 和它的所有方法一样都是公共的,所以应该没问题吗?

任何帮助理解这一点或解决方案将不胜感激。

0 投票
1 回答
58 浏览

java - 无法访问传递给 ScriptEngine 的 Java 对象的属性

我将一个对象“transformContext”从 Java 传递到 Graal.js scriptEngine。该对象包含一个名为“dataRecordsByName”的 Hashmap,在 Java 中我通常可以使用以下行访问它:

transformContext.get("dataRecordsByName")

我正在尝试从引擎中检索哈希图。我认为要做到这一点,我需要将上面的行替换为:

engine.eval("transformContext.dataRecordsByName")

然而,这只是返回未定义。

这是我完成此任务的完整代码:

这是控制台的输出:

TransformContext(dataRecordsByName={$=[], CONVERSION=[{"From_Currency":"AUD","To_Currency":"AUD","Conversion_Rate":1.0,"historical_date":"31/05/2021","organisation_id ":"ParentId","organisation_currency":"GBP","organisation_name":"Parent Id"}],...}, objectMapper=com.fasterxml.jackson.databind.ObjectMapper@21dfdc26)

不明确的

有谁知道为什么引擎无法检索 dataRecordsByName 属性?

0 投票
2 回答
60 浏览

javascript - 在 Java 中使用(最终用户定义的)JavaScript 代码时的安全注意事项

我正在开发一个 Java 项目。在其中,我们希望最终用户能够定义基于一组给定的原始类型或字符串变量计算的变量。在某些时候,所有给定的变量都设置为特定的值,然后应该进行计算。然后必须将所有生成的计算变量发送到 Java。

我正在评估最终用户定义其计算的方法。(当前)想法是让他编写 JavaScript 并让该代码在 Java 程序中解释/执行。我知道有两种方法可以做到这一点:使用 javax.scripting API 或 GraalVM/Truffle。在这两种情况下,我们都会这样做:

  1. 给定的变量被赋予到脚本中。在 javax.scripting 中ScriptEngine.put,在 Graal/Truffle 中,通过Value.putMember.
  2. 最终用户可以在全局上下文中定义变量(其名称不得与来自 Java 的名称冲突)。他如何设置它们的值取决于他 - 他可以直接设置它们(到一个常数,到给定变量之一,到其中一些的总和......)或定义对象和函数并通过调用这些来设置值.
  3. 当给定变量具有固定值时,将执行脚本。
  4. 脚本在全局上下文中定义的所有变量都将发送到 Java。在 javax.scripting 中ScriptEngine.get,在 Graal/Truffle 中,通过Value.getMember.

注意:我们不会授予脚本访问任何 Java 类或方法的权限。在 javax.scripting 中通过检查脚本是否包含字符串Java.type(并禁止这样的脚本),在 Graal/Truffle 中通过使用默认值Context(具有allowAllAccess=false)。

互联网上充满了关于 JavaScript 安全问题以及如何避免它们的提示和技巧。一方面,我觉得它们都不适用于这里(解释如下)。另一方面,我不太了解 JavaScript——除了纯粹的、无副作用的计算,我从未将它用于其他任何事情。

所以我在这里寻找一些指导:在这种情况下可能会出现什么样的安全问题?


为什么在这种情况下我看不到任何安全问题:

这是纯 JavaScript。它甚至不允许创建可用于例如在磁盘上创建文件的 Blob(它是 WebAPI 的一部分,而不是 JavaScript)。我知道 JavaScript 不包含任何逃避其沙箱的功能(如文件访问、线程、流......),它仅能够操纵提供给其沙箱的数据。请参阅https://262.ecma-international.org/11.0/#sec-overview的这一部分:

ECMAScript 是一种面向对象的编程语言,用于在主机环境中执行计算和操作计算对象。此处定义的 ECMAScript 并非旨在实现计算自给自足;实际上,本规范中没有规定外部数据的输入或计算结果的输出。相反,预计 ECMAScript 程序的计算环境将不仅提供本规范中描述的对象和其他设施,还提供某些特定于环境的对象,其描述和行为超出了本规范的范围,除非指出它们可以提供可以访问的某些属性和可以从 ECMAScript 程序调用的某些函数。

我们场景中的沙箱只放入了一些无害的玩具(即给定的原始类型或字符串的变量),在孩子玩过它们(脚本已运行)后,生成的建筑物(用户定义的变量)被拿走出来保存它们(在Java程序中使用)。

0 投票
1 回答
219 浏览

java - GraalSDK 值作为 JSON 结构

我试图让 JavaScript 调用的结果类似于 Map<String,Object> 的 JSON 结构,其中值可能是数字、字符串、布尔值、对象(地图)或数组(列表),类似于杰克逊所做的如果将值转换为地图。

使用Value.as(Map.class) 调用时,我希望 Map 中的值遵循这些规则

如果使用原始 Map.class 或 Object 组件类型,则列表的返回类型递归地服从 Object 目标类型映射规则。

进一步了解文档(对象映射规则 8)

如果该值具有数组元素并且其数组大小小于或等于 Integer.MAX_VALUE,则结果值将实现 List。

然而这个测试失败了

出现以下错误。

我错过了什么?

0 投票
1 回答
89 浏览

javascript - 在 Java GraalVM 中访问复杂的 Javascript 对象

我有一个用例,我有一个 java Map,我将它转换为 ProxyMap,使用 context.eval 在 javascript 中使用该映射,然后在 js(嵌套 json)中创建一个新对象。现在我想在 java 中使用在 javascript 中创建的对象,最好是 Map。

现在我的 js 创建的对象是动态的,我不知道所有字段可能存在什么。

所以基本上我正在做的是:

  1. context.getBindings("js").putMember("input", ProxyObject.fromMap(map));
  2. Value js = context.eval("js", "var obj = {'a':input['type']};");
  3. 现在我需要将它obj作为 Java 中的 Map 来获取。

据我所知,我可以使用objjava访问字段,getMemberobj可以是动态的,也可以是相当复杂的,我希望可能有另一种出路?

0 投票
0 回答
31 浏览

javascript - 在通过 graalvm 从 Java 程序调用的 javascript 中使用 import

我正在为一个用例尝试 Graalvm,我想知道是否可以在从 java 调用的 javascript 中使用 import 语句。我都试过了:

这给出了错误 Expected an operand but found import import v4 from 'uuid';var o = v4();

创建一个单独的脚本,包含

然后通过运行脚本

返回相同的错误:Expected an operand but found import import v4 from 'uuid';

我浏览了文档,似乎有可能。有人可以指导我采取正确的方法吗?