3年前 (2021-09-15)  jvm |   抢沙发  1291 
文章评分 0 次,平均分 0.0

GraalVm和Polyglot

大家好。在本博客中,我们将看到如何使用GraalVm实现多语言。这方面的先决条件是:

  • 对GraalVm的理解。
  • 了解GraalVm提供的功能。
  • GraalVm的本地设置。
  • 一点java和python(可选)。

让我们开始吧。

什么是GraalVm?

GraalVm是Oracle的一个开源项目,其目标是针对JVM,以便多个语言可以共存于同一个应用程序中。GraalVm不是JVM,而是一个UVM(通用虚拟机)。它支持所有具有生成字节码的编译器的语言;这意味着任何使用Java、Scala等的人都可以使用GraalVM。因此,所有这些语言共享相同的VM及其功能。在撰写本文时,GraalVm支持Java8和Java11版本。

GraalVm的另一个关键特性是能够创建基于JVM的应用程序的本机映像。这使得分发和安装Java程序更加容易,无需额外安装JRE。

此外,本机二进制文件具有启动速度更快的优势。为什么?因为,它在执行(AOT编译)之前已经转换为机器代码形式,并且不需要JIT编译器在运行时进行转换。因此,本机二进制文件的性能行为是恒定的和可预测的。为什么?因为代码在运行时不再需要JIT编译器与分析器交互进行优化。本机二进制文件也需要更少的内存,因为JIT编译器的JVM基础结构不需要运行。

在这篇文章中,让我们看看如何运行polyglot服务。

设置GraalVm

Oracle提供了两个版本的GraalVm供使用,第一个版本是community eddition,第二个版本是enterprise edition。我们将在本文中使用社区版。在本地设置GraalVm非常容易。从GraalVm官方网站安装:https://www.graalvm.org/getting-started/#install-graalvm。下载操作系统支持的zip文件。接下来,执行以下操作:

.bashrc中的JAVA_HOME设置为指向提取graalvm zip文件的位置。

PATH变量设置为指向$JAVA_HOME/bin

设置这些变量后,我们可以使用graalVm支持运行应用程序。在安装期间,将GraalVM设置为PATHJAVA_HOME环境变量应该足以使用GraalVM运行应用程序。

Polyglot与GraalVm

根据官方文件和GraalVm.org提供的polyglot参考资料,它指出:

GraalVM允许您以无缝方式编写多语言应用程序,将值从一种语言传递到另一种语言。对于GraalVM,没有必要像其他多语言系统那样进行复制或编组。这使您能够在跨越语言边界时实现高性能。大多数情况下,跨越语言边界根本不需要额外的费用。

因此,有了GraalVm对多语言功能的固有支持,开发人员可以专注于逻辑本身,而不是关注他们应该用什么语言编写它。让我们看看如何才能做到这一点。假设我们正在处理一个普通的java应用程序,突然需要一些javascrip中的随机代码。为了简单起见,让我们看看如何在java程序中获取js数组的元素。所以,这里有一个例子说明我们如何做到这一点…

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;

public class PolyglotJavaAndJs {
public static void main(String[] args) {
Context context = Context.newBuilder().allowIO(true).build();
Value array = context.eval("js", "[1,2,42,4]");
int result = array.getArrayElement(2).asInt();
System.out.println(result);
}
}

我创建了一个类PolyglotJavaAndJs,其中我们使用了GraalVm Sdk中的polyglot.contextpolyglot.vaue组件。在上下文的帮助下,我们可以选择一种不同的语言,并看到它在Java应用程序中工作。要运行和评估上述java应用程序,请使用以下命令:

Open the terminal and go to the src folder of the application and execute the following
javac PolyglotJavaAndJs.java
java PolyglotJavaAndJs

您将看到屏幕上的输出是42

让我们继续前进,看看如何使用Polyglot方法继续使用Java和Python。让我们尝试将值从Java程序传递到Python代码,以使事情变得有趣。

Polyglot Java到Python

假设我们要计算一个数的平方。然而,我们希望在Python中运行平方运算逻辑,但我们希望从Java应用程序中获取数字。

下面是一个场景,您将在同一应用程序中的两种不同语言之间传递变量。让我们看一下下面的代码片段:

import org.graalvm.polyglot.*;

import java.util.Scanner;

public class PolyglotJavaAndPython {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the number to calculate its square...");
int input = scanner.nextInt();

Context context = Context.newBuilder().allowIO(true).build();
context.eval("python", "print('Hello From Python')");
// Use the getBindings and putMember methods on the context for passing the value from Java to Python app.
context.getBindings("python").putMember("number", input);
Value result = context.eval("python", "number * number");
System.out.println(result);
}
}

下面是上述程序的输出:

Execute the statements:
$ javac PolyglotJavaAndPython.java
$ java PolyglotJavaAndPython
Enter the number to calculate its square…
10
Hello From Python
100

简单对吧?我们创建了一个小型方便的java类。在它中,我们只是请求用户输入,并用输入的平方进行响应。虽然看起来很简单,但这里有几点需要注意:

为了将动态输入从Java类传递到Python应用程序,我们需要一个启用IO操作的polyglot.Context实例。

我们需要捕获目标语言的绑定。

然后,java应用程序更新此绑定,提供来自用户的动态输入。为此,我们在绑定上使用putMember()方法。

一旦成员添加成功,我们就可以从目标语言代码块访问它们。我们通过直接使用他们的财产名称来实现。因此,使用putMember()后,这些变量将成为目标语言的环境变量。因此,它们现在可以在context中使用。

这就是这个博客的全部内容,我希望你能理解GraalVm的polyglot的概念。完整的代码可在此处获得:https://github.com/knoldus/GraalVmPolyglot. 有关如何在本地设置graalVm以及如何运行此应用程序等其他说明,请参阅repo中的readme.md文件。然而,如果你发现自己陷入困境,请在这里发表评论。我将非常乐意帮助和解决您的问题。

原文地址:https://blog.knoldus.com/going-polyglot-with-graalvm/

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/2343.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册