入门并且配置GraalVM来运行用Java(或者其他基于JVM的语言)、JavaScript 、 Node.js、Ruby、R、或者 Python。这篇文章引导你通过下载和安装GraalVM,并且增加对其他语言的支持,同时展示如何在GraalVM上面运行简单的程序。
下载GraalVM
GraalVM作为一个独立的Java开发工具包可以运行Java或者基于JVM的程序。并且它还可以基于它的多语言引擎运行其他的比如( JavaScript, Python, Ruby, R, )程序。当前的稳定版本是基于JDK8的,并且包含了JavaScript以及Node.js作为预安装的扩展语言。GraalVM实现的 R, Ruby和Python脚本语言可以作为额外的组成部分来安装。GraalVM提供社区和企业两个版本,可以去下载页 根据自己操作系统和需求下载。
本篇入门引导主要关注如何使用从Oracle技术网站获取的文档,也即GraalVM企业版。和社区版类似,企业版包含了JVM、Graal编译器、LLVM解释器以及支持JavaScript的Node.js运行时支持,这些都是在一个包里面的。
安装GraalVM
企业版GraalVM支持x86 64位的Linux或者Mac OS X系统。安装只需几分钟的时间。
- 下载GraalVM,选择企业版,继续点击 Oracle Technology Network,接受许可然后下载
- 解压
- 在你的PATH路径下添加GraalVM的/bin文件夹,例如在Linux下:
export PATH=/path/to/graalvm/bin:$PATH
在Mac OS下:
export PATH=/path/to/graalvm/Contents/Home/bin:$PATH
- 你可以使用echo命令(echo $PATH)证你是否正在使用GraalVM
(可选)可以将JAVA_HOME环境变量解析到GraalVM的安装目录。同时,你可以将GraalVM指定为你IDE的JRE或者JDK的安装。
GraalVM的/bin目录和标准的JDK是相似的,也包含了一些额外的功能:
- js是可以在GraalVM上运行JavaScript控制台
- node则是使用GraalVM的JavaScript引擎对Node.js的一个插入式的替代
- lli则是一个和GraalVM集成在一起的高性能的LLVM解释器
- native-image则是构建一个提前编译好的或者是共享类库的java应用程序
- gu(Graal updater)可以用来安装 Python,R以及 Ruby的语言包
值得注意的是,java命令在GraalVM中是运行JVM的默认编译器。如果需要运行 Ruby,Python以及R,则需要安装相应的语言引擎,比如,运行如下的命令则可以安装Ruby的支持
gu install ruby
更多使用gu的信息请参考文档
一旦PATH环境变量设置成功,就可以很方便查看java版本
$ java -version
java version "1.8.0_192"
Java(TM) SE Runtime Environment (build 1.8.0_192-b12)
GraalVM 1.0.0-rc10 (build build 25.192-b12-jvmci-0.53, mixed mode)
$ node -v
v10.9.0
$ lli --version
Graal llvm 6.0.0 (GraalVM EE Native 1.0.0-rc10)
假如你安装了Ruby语言,同样你可以查看Ruby的版本信息
$ ruby -v
truffleruby 1.0.0-rc10, like ruby 2.4.4, GraalVM CE Native [x86_64-darwin]
GraalVM Docker容器
官方的Docker镜像可以从Docker官网去获取:
https://hub.docker.com/r/oracle/graalvm-ce/
如果你想在GraalVM的社区版本中使用Docker,只需要执行docker pull命令:
docker pull oracle/graalvm-ce:1.0.0-rc10
该镜像是基于Oracle Linux并且已经包含了GraalVM CE,这就意味着Java,JavaScript,Node 以及LLVM解释器是开箱即用的。
可以通过以下命令启动容器
docker run -it oracle/graalvm-ce:1.0.0-rc10 bash
查看java,js命令是否可以正常执行
→ docker run -it oracle/graalvm-ce:1.0.0-rc10 bash
bash-4.2# java -version
openjdk version "1.8.0_192"
OpenJDK Runtime Environment (build 1.8.0_192-20181024121959.buildslave.jdk8u-src-tar--b12)
GraalVM 1.0.0-rc10 (build 25.192-b12-jvmci-0.53, mixed mode)
bash-4.2# node
> 1 + 1
2
> process.exit()
bash-4.2# lli --version
Graal llvm 6.0.0 (GraalVM CE Native 1.0.0-rc10)
bash-4.2#
需要注意的是,该镜像仅在GraalVM的社区版本中才可以使用。然而,GraalVM更新使用程序也将要可以使用。同时,你可以安装针对其他语言的支持(比如 Ruby, R 或者 Python),以下命令是安装Ruby的支持:
$ ruby -v
docker run -it oracle/graalvm-ce:1.0.0-rc10 bash
bash-4.2# gu install ruby
Downloading: Component catalog
Processing component archive: Component ruby
Downloading: Component ruby
[###### ]
...
如果要从主机系统安装目录让其在本地容器中可用,请使用Docker volumes
下面的命令可以将主机系统目录/absolute/path/to/dir/no/trailing/slash映射到容器目录/path/inside/container
docker run -it -v /absolute/path/to/dir/no/trailing/slash:/path/inside/container oracle/graalvm-ce:1.0.0-rc10 bash
如果你想要创建包含GraalVM Ruby, R 或者 Python实现的docker镜像,可以参考下面的docker文件
FROM oracle/graalvm-ce:1.0.0-rc10
RUN gu install ruby
WORKDIR /workdir
RUN echo 'puts "Hello from Truffleruby!\nVersion: #{RUBY_DESCRIPTION}"' > app.rb
CMD ruby app.rb
如果将上面的代码段放在当前目录的Dockerfile中,则可以使用以下命令构建并运行它。
docker build -t truffleruby-demo .
...
$ docker run -it --rm truffleruby-demo
Hello from Truffleruby!
Version: truffleruby 1.0.0-rc10, like ruby 2.4.4, GraalVM CE Native [x86_64-linux]
运行程序
由于GraalVM中所有语言运行时的可执行文件都模拟了语言默认运行时的行为,因此将GraalVM放在PATH上应足以使用GraalVM运行应用程序。
运行Java
看一下典型的helloworld类:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
运行以下的命令将此类编译成字节码,并且在GraalVM中运行:
$ javac HelloWorld.java
$ java HelloWorld
Hello World!
你可以尝试在GraalVM中运行这些示例程序
运行JavaScript程序
GraalVM能够执行JavaScript代码,包括 REPL模式和执行脚本文件
$ js
> 1 + 2
3
GraalVM同样支持运行Node.js程序。超过45000个npm模块被验证是完全兼容的,其中包括像express, react, async, request, browserify, grunt, mocha 以及 underscore。想要安装Node.js模块只需要在GraalVM的/bin文件夹下执行npm命令。npm命令等同于默认的Node.js命令,并支持所有Node.js API。
- 使用npm install 安装colors和ansispan模块:
npm install colors ansispan
安装之后,你就可以在你的应用程序中使用了
- 将以下代码段添加到名为app.js的文件中,并将其保存在安装Node.js模块的同一目录中:
const http = require("http");
const span = require("ansispan");
require("colors");
http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/html"});
response.end(span("Hello Graal.js!".green));
}).listen(8000, function() { console.log("Graal.js server running at http://127.0.0.1:8000/".red); });
- 在GraalVM中使用node命令执行:
node app.js
有关与Node.js兼容和配置GraalVM的更多信息,请阅读GraalVM中有关JavaScript的参考手册。
执行LLVM解释器
GraalVM中的LLVM解释器可以执行LLVM的二进制码,因此任何编程语言都可以编译为LLVM的二进制码。
编写一个C的helloworld文件,命名为hello.c:
#include <stdio.h>
int main() {
printf("Hello from GraalVM!\n");
return 0;
}
可以使用以下的命令将hello.c文件编译成二进制形式的hello.bc文件:
$ clang -c -O1 -emit-llvm hello.c
然后,就可以像这样在GraalVM中运行hello.bc文件:
$ lli hello.bc
Hello from GraalVM!
有关支持哪些语言和运行时的更多示例和信息,请参阅LLVM参考手册。
运行Ruby程序
Ruby执行引擎不是默认安装的,不过可以很简单的通过Graal updater安装:
gu install ruby
这使Ruby命令如ruby,gem,irb,rake,rdoc和ri变得可用:
$ ruby [options] program.rb
GraalVM中的Ruby实现与标准Ruby是相同的选项,同时也添加了一些内容。
$ gem install chunky_png
$ ruby -r chunky_png -e "puts ChunkyPNG::Color.to_hex(ChunkyPNG::Color('mintcream @ 0.5'))"
#f5fffa80
使用Bundler
目前支持的Bundler版本是1.16.x.
$ gem install bundler -v 1.16.3
$ bundle exec ...
关于GraalVM中Ruby支持,更多示例和其他信息可以在Ruby的参考手册中找到。
运行R程序
R执行引擎不是默认安装的,不过可以很简单的通过Graal updater安装:
gu install r
当R引擎安装好之后,你就可以执行R脚本以及使用R的REPL
$ R
R version 3.4.0 (FastR)
...
> 1 + 1
[1] 2
更多示例以及额外的对R的支持请参考:R的参考文档
运行Python程序
目前已经开始使用Python 3.7的GraalVM实现。 默认情况下不安装Python引擎,但可以使用Graal更新程序轻松添加它:
gu install python
一旦Python引擎安装好了,你就可以执行Python程序了:
$ graalpython
...
>>> 1 + 2
3
>>> exit()
更多示例以及额外的对Python的支持请参考:Python的参考文档
联合语言的支持
如果想要启用联合语言,可以通过使用--polyglot标志,在GraalVM上执行的脚本可以使用互操作性功能调用其他语言并与它们交换数据。
例如,运行js --jvm --polyglot example.js会在多语言上下文中执行example.js. 如果程序调用其他受支持语言中的任何代码,GraalVM将在与example.js应用程序相同的运行时中执行该代码。 有关多语言应用程序的更多信息,请参阅多语言文档。
本地镜像
GraalVM可以将Java字节码编译为本机映像,以实现更快的启动速度和更小的应用程序占用空间。
让我们使用上面的HelloWorld示例演示如何将Java字节码编译为本机映像:
// HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
运行以下命令将类编译为字节码,然后构建本机映像:
$ javac HelloWorld.java
$ native-image HelloWorld
通过上面的操作将在当前工作目录中构建名为helloworld的可执行文件。 调用它执行HelloWorld类的本机编译代码,如下所示:
$ ./helloworld
Hello, World!
本地镜像的多语言能力
native-image 工具还可以轻松使用多语言功能。 以使用JavaScript的GraalVM实现的JSON 的工整打印程序 为例:
// PrettyPrintJSON.java
import java.io.*;
import java.util.stream.*;
import org.graalvm.polyglot.*;
public class PrettyPrintJSON {
public static void main(String[] args) throws java.io.IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String input = reader.lines().collect(Collectors.joining(System.lineSeparator()));
try (Context context = Context.create("js")) {
Value parse = context.eval("js", "JSON.parse");
Value stringify = context.eval("js", "JSON.stringify");
Value result = stringify.execute(parse.execute(input));
System.out.println(result.asString());
}
}
}
--language:js参数确保JavaScript引擎在生成的本地镜像中可用:
$ javac PrettyPrintJSON.java
$ native-image --language:js PrettyPrintJSON
这个本机可执行文件现在就可以执行JSON的工整打印:
$ ./prettyprintjson <<EOF
{"GraalVM":{"description":"Language Abstraction Platform","supports":["combining languages","embedding languages","creating native images"],"languages": ["Java","JavaScript","Node.js", "Python", "Ruby","R","LLVM"]}}
EOF
以下是本机可执行文件的JSON输出:
{
"GraalVM": {
"description": "Language Abstraction Platform",
"supports": [
"combining languages",
"embedding languages",
"creating native images"
],
"languages": [
"Java",
"JavaScript",
"Node.js",
"Python",
"Ruby",
"R",
"LLVM"
]
}
}
本机映像比直接在JVM上运行相同代码要快得多:
$ time bin/java PrettyPrintJSON < test.json > /dev/null
real 0m1.101s
user 0m2.471s
sys 0m0.237s
$ time ./prettyprintjson < test.json > /dev/null
real 0m0.037s
user 0m0.015s
sys 0m0.016s
此处列出了GraalVM的提前编译存在某些限制。
接下来读什么
如果您想了解GraalVM为不同类型的团队提供的内容,请阅读Why Graal页面。 GraalVM的一些不同功能通过GraalVM前十件事中的示例进行了公开和支持。 或者,您可以通过查看示例应用程序来查看各种支持的语言。 如果您想了解以GraalVM为支持的语言启用的常用工具,请转到参考手册的工具一栏 如果您对特定语言最感兴趣,那么参考手册中也提供了更多文档。
网友评论