java - 如何在 OSGi(Karaf)模块中添加 GraalVM 多语言代码(运行 Javascript 的 Java)支持
问题描述
我的目标:
我正在为 Apache Unomi 构建一个“插件”,这似乎是一套非常标准的 Karaf / OSGi 服务。作为其中的一部分,我希望能够从我的 Java 代码中执行 Javascript(最终是 Nodejs),并且向前发展的最佳选择似乎是 GraalVM(我对使用像 Nashorn/Rhino 这样的任何遗留物不感兴趣)。我目前正在进行的工作是在我的 Unomi 分支上的这个 PR 。
我的问题:
我无法让 GraalVM Polyglot 代码在 Karaf 模块中工作。添加 Maven 依赖项在运行时失败,并且手动将类(GraalVM 运行时应提供)添加到我的框架配置文件中会引发关于没有其他可用语言的错误。
到目前为止我做了什么:
我已经为 JDK 11 (OS X Catalina) 成功安装了 GraalVM
% java -version
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment GraalVM CE 20.0.0 (build 11.0.6+9-jvmci-20.0-b02)
OpenJDK 64-Bit Server VM GraalVM CE 20.0.0 (build 11.0.6+9-jvmci-20.0-b02, mixed mode, sharing)
我参考了JDK 11 上 Maven 的 GraalVM 教程,并根据示例将以下内容添加到我的插件的 pom 中:
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<version>20.0.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>20.0.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>20.0.0</version>
</dependency>
我还根据GraalVM 文档向我的插件添加了一些示例代码:
Context polyglot = Context.create();
Value array = polyglot.eval("js", "[1,2,42,4]");
int result = array.getArrayElement(2).asInt();
发生了什么(失败):
至此,我的 Maven 构建完成且没有错误。然而,当我启动 Karaf 时,我立即得到一个错误(完整输出):
Unable to resolve root: missing requirement [root] osgi.identity; osgi.identity=unomi-router-karaf-feature; type=karaf.feature; version="[1.5.0.SNAPSHOT,1.5.0.SNAPSHOT]"; filter:="(&(osgi.identity=unomi-router-karaf-feature)(type=karaf.feature)(version>=1.5.0.SNAPSHOT)(version<=1.5.0.SNAPSHOT))" [caused by: Unable to resolve unomi-router-karaf-feature/1.5.0.SNAPSHOT: missing requirement [unomi-router-karaf-feature/1.5.0.SNAPSHOT] osgi.identity; osgi.identity=org.apache.unomi.router-rest; type=osgi.bundle; version="[1.5.0.SNAPSHOT,1.5.0.SNAPSHOT]"; resolution:=mandatory [caused by: Unable to resolve org.apache.unomi.router-rest/1.5.0.SNAPSHOT: missing requirement [org.apache.unomi.router-rest/1.5.0.SNAPSHOT] osgi.service; effective:=active; filter:="(&(objectClass=org.apache.unomi.router.api.services.ImportExportConfigurationService)(configDiscriminator=IMPORT))" [caused by: Unable to resolve org.apache.unomi.router-service/1.5.0.SNAPSHOT: missing requirement [org.apache.unomi.router-service/1.5.0.SNAPSHOT] osgi.wiring.package; filter:="(&(osgi.wiring.package=org.apache.unomi.persistence.spi)(version>=1.5.0)(!(version>=2.0.0)))" [caused by: Unable to resolve org.apache.unomi.persistence-spi/1.5.0.SNAPSHOT: missing requirement [org.apache.unomi.persistence-spi/1.5.0.SNAPSHOT] osgi.identity; osgi.identity="root#unomi-kar-1.5.0.SNAPSHOT"; type=karaf.subsystem; version="[0,0.0.0]"; resolution:=mandatory [caused by: Unable to resolve root#unomi-kar-1.5.0.SNAPSHOT: missing requirement [root#unomi-kar-1.5.0.SNAPSHOT] osgi.identity; osgi.identity=unomi-kar; type=karaf.feature; version="[1.5.0.SNAPSHOT,1.5.0.SNAPSHOT]" [caused by: Unable to resolve unomi-kar/1.5.0.SNAPSHOT: missing requirement [unomi-kar/1.5.0.SNAPSHOT] osgi.identity; osgi.identity=org.apache.unomi.plugins-firstparty; type=osgi.bundle; version="[1.5.0.SNAPSHOT,1.5.0.SNAPSHOT]"; resolution:=mandatory [caused by: Unable to resolve org.apache.unomi.plugins-firstparty/1.5.0.SNAPSHOT: missing requirement [org.apache.unomi.plugins-firstparty/1.5.0.SNAPSHOT] osgi.wiring.package; filter:="(osgi.wiring.package=com.ibm.icu.impl)"]]]]]]]
如果我从插件的 pom 中删除三个依赖项并重新构建,我可以毫无问题地启动 Karaf。但是,当我尝试在我的 Unomi 插件中运行我的操作时,它立即说没有可用的 graalvm polyglot 类(预期)。
经过一番谷歌搜索,我偶然发现了一个现有的 GitHub 问题,并按照建议添加org.graalvm.polyglot
到org.osgi.framework.system.packages.extra
. 这几乎奏效了,但是现在当我尝试在我的 Unomi 插件中运行我的操作时,我得到了一个PolyglotIllegalArgumentException: A language with id 'js' is not installed. Installed languages are: [].
然后我尝试以这种方式添加我尝试的所有类,包括在上面的 pom 中,但它继续返回相同的错误。
我不确定从这里去哪里。我猜我对 Maven 的缺乏经验会指出这是一个愚蠢的问题,尽管经过大量搜索后,似乎围绕在 OSGi 上运行 GraalVM 的少量可用内容都表明它可能无法正常工作——尽管我不得不想象这是可能的。我对潜在解决方案的想法是
- 我的 Maven pom 配置很差,有一种方法可以通过正确配置的 pom 解决这个问题
- 我需要在
org.osgi.framework.system.packages.extra
single 之外指定其他系统包org.graalvm.polyglot
,但不确定如何在此处继续。
任何帮助都将不胜感激!
解决方案
推荐阅读
- python - Tkinter Entry .get 从定义
- azure-ad-b2c - 由于缺少声明信息,向 Azure AD B2C 自定义策略注册失败
- node.js - Discord.js TypeError:无法读取未定义的属性“添加”
- postgresql - Postgres Copy To CSV Array 是双引号
- html - 如何验证带有标签的 alt 文本的正确用法
- hadoop - 如何从同一网络上的另一台机器访问 Hadoop?
- reactjs - 为什么 useEffect 挂钩不触发依赖数组中的对象?
- rsync - 是否有任何操作员使用 Airflow 通过 SFTP 在不同主机之间移动文件?
- sql - ORA-30926: 在 oracle 的合并查询中无法在源表中获得一组稳定的行
- c++ - 在 C++ 中存储不同长度的子数组