首页 > 解决方案 > 如何在 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.polyglotorg.osgi.framework.system.packages.extra. 这几乎奏效了,但是现在当我尝试在我的 Unomi 插件中运行我的操作时,我得到了一个PolyglotIllegalArgumentException: A language with id 'js' is not installed. Installed languages are: [].然后我尝试以这种方式添加我尝试的所有类,包括在上面的 pom 中,但它继续返回相同的错误。

我不确定从这里去哪里。我猜我对 Maven 的缺乏经验会指出这是一个愚蠢的问题,尽管经过大量搜索后,似乎围绕在 OSGi 上运行 GraalVM 的少量可用内容都表明它可能无法正常工作——尽管我不得不想象这是可能的。我对潜在解决方案的想法是

  1. 我的 Maven pom 配置很差,有一种方法可以通过正确配置的 pom 解决这个问题
  2. 我需要在org.osgi.framework.system.packages.extrasingle 之外指定其他系统包org.graalvm.polyglot,但不确定如何在此处继续。

任何帮助都将不胜感激!

标签: javamavenapache-karafgraalvm

解决方案


推荐阅读