【问题标题】:How to get Graal SDK packages to work without Maven?如何让 Graal SDK 包在没有 Maven 的情况下工作?
【发布时间】:2018-09-03 20:55:51
【问题描述】:

我正在开发一个需要执行的 Java 应用程序 JavaScript。 Nashorn JS 引擎即将被弃用 替换的是 Graal SDK 提供的 API 集 它利用了 GraalVM。本质上是虚拟机 执行多种语言。

至少我是这么认为的。 所以我花了一天时间试图让它工作。我下载了使用 JDK 8 的 GraalVM rc6。我使用 IntelliJ IDEA 并将 GraalVM 添加为新的 JDK。我觉得很奇怪我应该添加一个虚拟机作为开发工具包,但我知道它是基于 JDK 8 的,所以我没问题。

而且问题与其他问题不同,我无法让新软件包工作。我的 IDE 告诉我它无法解决它们。

实际上,org.graalvm 包都无法解析。

所以我下载了 JDK 11 build 28,因为据我所知,自 build 20 起 JDK 11 就带有 GraalVM。

实际上,在这种情况下,可以找到一些包,但远远少于预期:例如 org.graalvm.polyglot 仍然无法解析。

最后,我尝试从 Maven 添加 Graal SDK 并解决了这些包。现在运行时出现异常:

Context ctx = Context.create(“js”);

在类路径中未找到任何语言和多语言实现。确保 truffle-api.jar 在类路径中。

我以为前两种情况的问题实际上是没有获取GraalVM JDK,但即使这样也抛出异常。

有经验的能解释一下吗?

【问题讨论】:

    标签: java java-8 java-11 graalvm


    【解决方案1】:

    GraalVM

    GraalVM 是目前一款高性能的可嵌入式多语言虚拟机 支持多种编程语言:Java(和 JVM 语言), JavaScript(包括 node.js)、Ruby、R、Python 和 C/C++ 等语言 使用 LLVM 后端。

    您可以在此处下载 GraalVM 的预构建发行版: https://www.graalvm.org/downloads。 其中包括 java 运行时、节点运行时、称为 Graal.js 的 JavaScript 引擎等。

    Graal SDK 是多语言 API,允许 GraalVM 使用它可以运行的所有语言实现。 这个多语言 API 被打包为一个 jar 文件:$GRAALVM_HOME/jre/lib/boot/graal-sdk.jar

    将该文件作为外部库添加到您的 IDEA 项目/模块中,将允许 IDE 找到以下类: org.graalvm.polyglot.Contextorg.graalvm.polyglot.Value 是与语言互操作所必需的,包括 JavaScript 实现。

    如果您的项目使用 Maven,您可以在该文件上添加系统依赖项,Maven 将在任何系统上找到它 $JAVA_HOME 设置为指向 GraalVM 发行版。

    <dependency>
        <groupId>org.graalvm</groupId>
        <artifactId>graal-sdk</artifactId>
        <version>1.0.0-rc</version>
        <scope>system</scope>
        <systemPath>${java.home}/lib/boot/graal-sdk.jar</systemPath>
    </dependency>
    

    现在,当您从 GraalVM 发行版运行 java 命令时,必要的文件将自动添加到类路径中。 因此,无需在 IDE 中运行类似以下内容:

    import org.graalvm.polyglot.*;
    public class Main {
        public static void main(String[] args) {
            Context polyglot = Context.create();
            Value array = polyglot.eval("js", "[1,2,42,4]");
            System.out.println(array.getArrayElement(2).asInt());
        }
    }
    

    现在这是因为 GraalVM 默认启用了 Graal.js JavaScript 引擎。

    如果你想在普通的 JDK 上运行它,你需要在类路径中添加更多的东西。

    在普通 JDK 上运行 Graal.js**

    有一个关于如何在股票 JDK 上运行 Graal.js 的问题:How to use graaljs ? Is there a place where to get a .jar file/files?。 接受的答案更详细地说明了在哪里可以找到必要的 jar 文件以使其在 Java 8 上运行。

    简而言之,您需要将以下 jar 文件添加到类路径以使其实际运行:

    • graal-sdk.jar - GraalVM polyglot API
    • truffle-api.jar - 用于语言实现的 API。
    • graaljs.jar - 这是 GraalVM 的 JavaScript 引擎的实现
    • graaljs-scriptengine.jar -- 允许通过 Java 脚本引擎 API 使用 Graal.js。
    • graaljs-launcher.jar
    • tregex.jar -- 正则表达式库
    • truffle-profiler.jar - 用于 Truffle 语言实现的分析器
    • chromeinspector.jar - 调试器集成
    • launcher-common.jar

    您可以在 downloaded 的 GraalVM 发行版中找到它们,这两个版本都可以正常工作。

    现在如果没有 Graal 编译器,JavaScript 引擎的性能将无法达到最佳。 正如您自己提到的,JDK 11 附带了 Graal 编译器 的快照(不是 GraalVM,它是 GraalVM 项目的完整发行版,包括 JS 引擎、LLVM 位码解释器、节点实现、JVM 等)。您可以通过传递启用 Graal 编译器 --XX:+UnlockExperimentalVMOptions --XX:+UseJVMCICompilerjava 命令。

    现在在 JDK 11 上运行它可能不起作用,因为 JDK 11 与 JDK 8 有很大不同,并且模块系统可能存在问题或缺少某些东西(如 jax-b),但它也可能工作。它可以在 JDK 8 上运行。

    【讨论】:

    • 感谢您提供如此详细的信息!这绝对是我想知道的!
    【解决方案2】:

    所以我发现了问题。 IntelliJ IDEA 非常习惯于 它没有加载的标准 JDK Home 结构 Graal SDK 和其他 api。

    让我更接近结果的 Maven jar 文件是 与 GraalVM 捆绑的文件完全相同。

    【讨论】:

      【解决方案3】:

      IntelliJ 不会将 Graal SDK 中的所有 Jars 添加到您的类路径中。

      您可以通过导航到

      将 Jars 添加到 IntelliJ 内的类路径中
      File > Project Structure > SDKs > Choose your Graal SDK
      

      然后点击底部的+按钮添加Jar文件。添加 graal-sdk.jar 将解决查找 org.graalvm 包的问题。

      这将避免必须修改您的 pom.xml 文件来修复 IDE 的问题。

      【讨论】:

        【解决方案4】:

        具有下一个特征:

        • IntelliJ 理念
        • SDKMan
        • GraalVM CE 19.0.0

        我通过以下步骤解决了这个问题:

        1. 在 intelliJ 中转到:文件 -> 项目结构 -> SDK
        2. 添加一个名为 GraalVM 的新 SDK(或选择一个描述性名称),然后在 JDK 主路径中选择 GraalVM 安装路径(在我的例子中)/Users/cjeronimo/.sdkman/candidates/java/19.0.0-grl

        1. 最后非常重要的是添加 graal-sdk.jar

        【讨论】:

          【解决方案5】:

          同时使用 IntelliJ (2020.2) 和 GraalVM (graalvm-ce-java11-20.3.0) 我能够使以下代码工作:

          public static void main(String[] a0rgs) {
              System.out.println("Hello World!");
              Context context = Context.create();
              context.eval("js", "console.log('hello from javascript');");
          }
          

          只需将此依赖项添加到maven

          <dependency>
              <groupId>org.graalvm.sdk</groupId>
              <artifactId>graal-sdk</artifactId>
              <version>20.3.0</version>
          </dependency>
          

          【讨论】:

            猜你喜欢
            • 2013-01-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-06-02
            相关资源
            最近更新 更多