📜 ⬆️ ⬇️

Ten things you can do with GraalVM


From the translator: GraalVM is a new, interesting technology, but on Habré there are not many articles on it that could show examples of the features of Graal. The article below is not just a listing of what GraalVM can do, but also a small workshop similar to the one that Chris Seaton and Oleg Shelayev performed on Oracle CodeOne 2018. Following the author, I urge you - try to make examples from the article, this is really interesting.


GraalVM has a lot of different things, and if you have heard this name before, or even seen reports, there are still a lot of things that you probably don’t know yet, but which GraalVM can do. In this article we will look at the various possibilities that GraalVM provides and show what can be done with their help.


  1. Fast java execution
  2. Reduced start time and memory consumption for Java
  3. Combining JavaScript, Java, Ruby and R
  4. Execution of programs written in platform-specific languages
  5. Common tools for all programming languages
  6. JVM application extension
  7. Platform-specific application add-on
  8. Java code as a platform-dependent library
  9. Support for multiple programming languages ​​in the database
  10. Creating programming languages ​​for GraalVM

You can do everything that is shown in this article using GraalVM 1.0.0 RC1, which is available at the link from the GraalVM website . I used the Enterprise Edition on MacOS, but the code that is written here will work on Linux and on GraalVM Community Edition.


When you read the article, run the programs that are described in it! The code can be downloaded from GitHub .


Installation


After downloading from http://graalvm.org/downloads, I added the path to the GraalVM executables in $PATH . By default, this adds support for running Java and JavaScript.


 $ git clone https://github.com/chrisseaton/graalvm-ten-things.git $ cd foo $ tar -zxf graalvm-ee-1.0.0-rc1-macos-amd64.tar.gz # or graalvm-ee-1.0.0-rc1-linux-amd64.tar.gz on Linux $ export PATH=graalvm-1.0.0-rc1/Contents/Home/bin:$PATH # or PATH=graalvm-1.0.0-rc1/bin:$PATH on Linux 

GraalVM comes with built-in support for JavaScript and contains a package manager called gu , which adds the ability to install support for languages ​​other than Java and JavaScript. I additionally installed Ruby, Python and R, they are downloaded from GitHub.


 $ gu install -c org.graalvm.ruby $ gu install -c org.graalvm.python $ gu install -c org.graalvm.R 

Now, if you run the java or js command, you will see the GraalVM versions of these engines.


 $ java -version java version "1.8.0_161" Java(TM) SE Runtime Environment (build 1.8.0_161-b12) GraalVM 1.0.0-rc1 (build 25.71-b01-internal-jvmci-0.42, mixed mode) $ js --version Graal JavaScript 1.0 (GraalVM 1.0.0-rc1) 

1. Fast java execution


“Graal” in GraalVM is the name of the compiler. He alone is created to rule by all ! This means that this is a single compiler implementation written in the form of a library that can be used for a large number of different things. For example, we use Graal to compile both ahead-of-time and just-in-time to compile code written in various programming languages, including for different processor architectures.


The first and easiest way to use Graal is to use it as a Java JIT compiler.


As an example, we will use a program that gives out 10 of the most frequently encountered words in a document. The program uses the capabilities of the modern Java language, such as Streams and collections.


 import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; public class TopTen { public static void main(String[] args) { Arrays.stream(args) .flatMap(TopTen::fileLines) .flatMap(line -> Arrays.stream(line.split("\\b"))) .map(word -> word.replaceAll("[^a-zA-Z]", "")) .filter(word -> word.length() > 0) .map(word -> word.toLowerCase()) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .entrySet().stream() .sorted((a, b) -> -a.getValue().compareTo(b.getValue())) .limit(10) .forEach(e -> System.out.format("%s = %d%n", e.getKey(), e.getValue())); } private static Stream<String> fileLines(String path) { try { return Files.lines(Paths.get(path)); } catch (IOException e) { throw new RuntimeException(e); } } } 

GraalVM includes the javac compiler, but for this demo there is no difference, use it or the standard compiler. Therefore, you can use the standard javac compiler if you want.


 $ javac TopTen.java 

If we run the java command, which is included in GraalVM, then the Graal JIT compiler will be used automatically - no need to take any additional steps. I will use the time command in order to get real data about the time that was spent on executing the program from beginning to end, instead of deploying a complex microbenchmark. There will also be used a large amount of input data so that there are no insinuations about the saved couple of seconds here or there. File large.txt - 150 MB.


 $ make large.txt $ time java TopTen large.txt sed = 502701 ut = 392657 in = 377651 et = 352641 id = 317627 eu = 317627 eget = 302621 vel = 300120 a = 287615 sit = 282613 real 0m17.367s user 0m32.355s sys 0m1.456s 

Graal is written in Java, not C ++, like most other JIT compilers for Java. We think that this allows us to improve it faster than existing compilers, complementing new powerful optimizations (such as partial escape analysis, for example) that are not available in the standard JIT compiler for HotSpot.
And it can make your java programs much faster.


For comparison purposes, in order to run programs without the Graal JIT compiler, I will use the -XX:-UseJVMCICompiler . JVMCI is the interface between Graal and JVM. You can also run an example on a standard JVM and compare the results.


 $ time java -XX:-UseJVMCICompiler TopTen large.txt sed = 502701 ut = 392657 in = 377651 et = 352641 id = 317627 eu = 317627 eget = 302621 vel = 300120 a = 287615 sit = 282613 real 0m23.511s user 0m24.293s sys 0m0.579s 

This test shows that Graal runs our Java program in about three-quarters of the time it takes to run it with a standard HotSpot compiler. Where we believe that a few percent improvement in productivity is a significant achievement, 25% is a big deal.


Twitter is the only company that currently uses Graal on “combat” servers , and they say that this is justified for them, in terms of saving real money. Twitter uses Graal to execute applications written in Scala - Graal runs at the JVM bytecode level, i.e. applicable to any JVM language.


This is the first use of GraalVM — simply replacing the JIT compiler with a better version for your existing Java applications.


2. Reduce start time and memory consumption for Java


The strengths of the Java platform are particularly evident when dealing with long-running processes and peak loads. In contrast, short-lived processes suffer from a long start-up time and relatively large memory usage.


For example, if we run the application from the previous section, submitting to it a much smaller amount of input data — about 1 KB instead of 150 MB — then it seems to take an unreasonably long time and quite a lot of memory — about 60 MB, in order to process such a small file. . Use the -l option to print out the amount of memory used in addition to the execution time.


 $ make small.txt $ /usr/bin/time -l java TopTen small.txt # -v on Linux instead of -l sed = 6 sit = 6 amet = 6 mauris = 3 volutpat = 3 vitae = 3 dolor = 3 libero = 3 tempor = 2 suscipit = 2 0.32 real 0.49 user 0.05 sys 59846656 maximum resident set size 

GraalVM gives us a tool that solves this problem. We said that Graal is a compiler library and it can be used in many different ways. One of them is compiling ahead-of-time into a platform -dependent executable image, instead of just-in-time compiling at runtime. This is similar to how a regular compiler works, such as gcc .


 $ native-image --no-server TopTen classlist: 1,513.82 ms (cap): 2,333.95 ms setup: 3,584.09 ms (typeflow): 4,642.13 ms (objects): 3,073.58 ms (features): 156.34 ms analysis: 8,059.94 ms universe: 353.02 ms (parse): 1,277.02 ms (inline): 1,412.08 ms (compile): 10,337.76 ms compile: 13,776.23 ms image: 2,526.63 ms write: 1,525.03 ms [total]: 31,439.47 ms 

This command creates a platform- topten executable file called topten . This file does not launch the JVM, it is not linked to the JVM and it generally does not include the JVM in any way. The native-image command truly compiles your Java code and the Java libraries you use into fully-fledged machine code. For runtime components, such as the garbage collector, we run our own new VM, called SubstrateVM, which, like Graal, is also written in Java.


If you look at the dependencies that topten uses, you will see that these are only standard system libraries. We can only transfer this one file to a system on which the JVM has never been installed and run it there to verify that it does not use the JVM or any other files. Topten also quite small - the executable code takes up less than 6 MB.


 $ otool -L topten # ldd topten on Linux topten: .../CoreFoundation.framework ... .../libz.1.dylib ... .../libSystem.B.dylib ... $ du -h topten 5.7M topten 

If we run this executable file, we will see that it runs about an order of magnitude faster and uses about an order of magnitude less memory than the same program running under the JVM. The launch is so fast that you won't notice how long it took. If you use the command line, you will not feel the pause that is usually present when you run a small, short-lived program under the JVM


 $ /usr/bin/time -l ./topten small.txt sed = 6 sit = 6 amet = 6 mauris = 3 volutpat = 3 vitae = 3 dolor = 3 libero = 3 tempor = 2 suscipit = 2 0.02 real 0.00 user 0.00 sys 4702208 maximum resident set size 

There are some limitations to the native-image utility. So, at compile time you should have all the classes, there are also limitations in using the Reflection API. But there are some additional advantages over basic compilation, such as running static initializers at compile time. In this way, the amount of work performed each time an application is loaded is reduced.


This is the second application of GraalVM - the distribution and execution of existing Java programs, with a quick start and less memory consumption. This method eliminates configuration problems such as finding the right jar at runtime, and also allows you to create smaller Docker images.


3. Combining JavaScript, Java, Ruby and R


Along with Java, GraalVM includes new implementations of JavaScript, Ruby, R, and Python engines. They are written using a new framework called Truffle . This framework makes it possible to create interpreters of languages ​​that are both simple and high-performance. When you write an interpreter of a language using Truffle, it will automatically use Graal to provide JIT compilation for your language. Thus, Graal is not only a JIT compiler and an AOT compiler for Java, it can also be a JIT compiler for JavaScript, Ruby, R and Python.


Support for third-party languages ​​in GraalVM aims to be a transparent replacement for existing engines of different languages. For example, we can install the “color” module for Node.js:


 $ npm install --global color ... + color@3.0.0 added 6 packages in 14.156s 

Then write a program using this module to convert RGB HTML colors to HSL:


 var Color = require('color'); process.argv.slice(2).forEach(function (val) { print(Color(val).hsl().string()); }); 

And run it in the usual way:


 $ node color.js '#42aaf4' hsl(204.89999999999998, 89%, 60.8%) 

The performance engines of different languages ​​in GraalVM work together - there is an API that allows you to run code from one language in a program written in another language. And it allows you to write multilingual programs - programs written in more than one programming language.


This may be necessary if you write most of your program in one language, but would like to use a library written in another programming language. For example, imagine that we need to write an application to convert the color name from CSS into its numeric representation in Node.js, but we want to use the Ruby color library instead of writing the conversion ourselves.


 var express = require('express'); var app = express(); color_rgb = Polyglot.eval('ruby', ` require 'color' Color::RGB `); app.get('/css/:name', function (req, res) { color = color_rgb.by_name(req.params.name).html() res.send('<h1 style="color: ' + color + '" >' + color + '</h1>'); }); app.listen(8080, function () { console.log('serving at http://localhost:8080') }); 

In this code, we wrote that we had to execute Ruby code as a string, but note that we didn’t do much here - we just connected the libraries and then returned the Ruby object. In Ruby, we would use it like this: Color::RGB.by_name (name).html . If you look at how color_rgb used further in JavaScript, you will see that we actually call the same methods from JavaScript, although these are Ruby objects and methods. And we pass them as JavaScript strings and connect the result, which is a Ruby string, with a JavaScript string.


Install both dependencies - Ruby and JavaScript.


 $ gem install color Fetching: color-1.8.gem (100%) Successfully installed color-1.8 1 gem installed $ npm install express + express@4.16.2 updated 1 package in 10.393s 

Then you need to run node with a couple of additional options: --polyglot to say that we need access to other languages ​​and --jvm , because the executable node image by default does not include anything other than JavaScript.


 $ node --polyglot --jvm color-server.js serving at http://localhost:8080 

And then go to the URL http: // localhost: 8080 / css / orange (or some other color), as usual, in your browser.

Let's try to make a more serious example that uses more languages ​​and modules.


JavaScript does not support very large integers. I found several modules like big-integer , but they are all ineffective, because store the components of the number as javascript floating point numbers. The BigInteger class in Java is more efficient; let's use it to do several arithmetic operations with large integers.


There is also no built-in support for drawing graphs in JavaScript, while R perfectly draws graphics. Let's use the svg module from R to draw a scatter plot of a trigonometric function in 3D space.


In both cases, we will use the API to support multilingualism from GraalVM (hereinafter referred to as Polyglot API) and we can simply insert the results of executing programs in other languages ​​in JavaScript.


 const express = require('express') const app = express() const BigInteger = Java.type('java.math.BigInteger') app.get('/', function (req, res) { var text = 'Hello World from Graal.js!<br> ' // Using Java standard library classes text += BigInteger.valueOf(10).pow(100) .add(BigInteger.valueOf(43)).toString() + '<br>' // Using R interoperability to create graphs text += Polyglot.eval('R', `svg(); require(lattice); x <- 1:100 y <- sin(x/10) z <- cos(x^1.3/(runif(1)*5+10)) print(cloud(x~y*z, main="cloud plot")) grDevices:::svg.off() `); res.send(text) }) app.listen(3000, function () { console.log('Example app listening on port 3000!') }) 

Open http: // localhost: 3000 / in your browser to see the result:

This is the third thing we can do with GraalVM — run programs written in several languages ​​and use the modules from these languages ​​together in one program. We present this as a way to unify runtime environments and libraries — you can use the programming language that you think is best suited for solving the current problem and any library you want, regardless of what programming language it is written in.


4. Execution of programs written in platform-specific languages


Another language that GraalVM supports is C. GraalVM can execute C code in the same way that it executes programs written in JavaScript and Ruby.


What GraalVM actually supports is the launch of code resulting from the execution of the LLVM utilities, i.e. bitcode, not direct C support. This means that you can use existing tools for C and other languages ​​that support LLVM, such as C ++, Fortran, and potentially more languages ​​in the future. For ease of demonstration, I run a special version of gzip , which is compiled into a single file (this version is supported by Stephen McCamant ). This is just the gzip source code and autoconf configuration combined into one file for simplicity. I had to patch a couple of things to make it work on macOS and with clang, but I didn't do anything specifically to support GraalVM.


We compile gzip using the standard clang (LLVM compiler for C) and want it to make us an LLVM bitcode, not a platform-specific build, because GraalVM will not launch it. I am using clang 4.0.1.


 $ clang -c -emit-llvm gzip.c 

And then run the result, directly using the lli command (interpreter of the LLVM bitcode) from GraalVM. Let's try to compress the file using my gzip system archiver, and then unzip it using gzip running under GraalVM.


 $ cat small.txt Lorem ipsum dolor sit amet... $ gzip small.txt $ lli gzip.bc -d small.txt.gz $ cat small.txt Lorem ipsum dolor sit amet... 

Implementations of Ruby and Python in GraalVM use the same technique to run extensions written in C for these languages. This means that you can run these extensions inside a VM and this allows us to maintain high execution speed, even if we use outdated platform-specific extension interfaces.


This is the fourth way to use GraalVM — launch programs written in platform-specific languages, such as C or C ++, as well as launching extensions to languages ​​such as Python or Ruby that the JVM implementations of these languages, such as JRuby, are not able to do.


5. Common tools for all programming languages


If you are programming in Java, then you probably use very high-quality tools such as IDE, debuggers, and profilers. Not all languages ​​have such a set of tools, but you can get such a set if you use languages ​​that are supported by GraalVM.


Support for all languages ​​in GraalVM (except Java, currently) is implemented using a common framework - Truffle. This allows us to make functionality, for example, a debugger, once and use it for all languages.


To try this, we will write the simplest program - FizzBuzz , because it is visual (prints something on the screen) and there are clear branches in it that are used only in some iterations. Thus, it will be easier for us to set breakpoints. Let's start with javascript implementation.


 function fizzbuzz(n) { if ((n % 3 == 0) && (n % 5 == 0)) { return 'FizzBuzz'; } else if (n % 3 == 0) { return 'Fizz'; } else if (n % 5 == 0) { return 'Buzz'; } else { return n; } } for (var n = 1; n <= 20; n++) { print(fizzbuzz(n)); } 

Run the program as usual, using the js utility, under GraalVM.


 $ js fizzbuzz.js 1 2 Fizz 4 Buzz Fizz 

We can also run a program with the - --inspect flag. This will give us a link that you can open in Chrome and stop the program in the debugger.


 $ js --inspect fizzbuzz.js Debugger listening on port 9229. To start debugging, open the following URL in Chrome: chrome-devtools://devtools/bundled/inspector.html?ws=127.0.0.1:9229/6c478d4e-1350b196b409 

You can put a breakpoint in the FizzBuzz code and then continue execution. When the program interrupts execution, we will see the value of the variable n in the debugger and we can continue the execution of the program or study the debugger interface.

The Chrome debugger is usually used for JavaScript, but for GraalVM in JavaScript there is nothing different from other languages. The --inspect flag --inspect also available and works in the implementation of Python, Ruby and R. I will not show you the source code of each program, but they run the same way and you get the same debugger in Chrome for each of them.


 $ graalpython --jvm --inspect fizzbuzz.py 


 $ ruby --inspect fizzbuzz.rb 


 $ Rscript --inspect fizzbuzz.r 


Another tool that you probably know from Java is VisualVM. It provides a user interface, using which you can join a running JVM on your local machine or via the network to inspect various aspects of program execution, such as memory usage or execution threads.


GraalVM includes VisualVM as a standard jvisualvm utility.


 $ jvisualvm &> /dev/null & 

If we run VisualVM while Java is running TopTen Java, we can observe the memory usage or, for example, take a snapshot of the memory contents and see what types of objects we use memory on the heap.


 $ java TopTen large.txt 


I wrote this Ruby program to generate some garbage in memory at runtime.


 require 'erb' x = 42 template = ERB.new <<-EOF The value of x is: <%= x %> EOF loop do puts template.result(binding) end 

If you run the standard Ruby implementation on JVM - JRuby, then you will be disappointed with VisualVM, because you will see only internal Java objects instead of objects of your language.


If you are using the version of Ruby for GraalVM, then VisualVM recognizes Ruby objects. We need to use the - --jvm option to use VisualVM, since it does not support native versions of Ruby.


 $ ruby --jvm render.rb 

, , Java , , , Summary, Ruby Heap Ruby .

Truffle — - Nexus . Truffle , , API Truffle' , , Truffle, .


, GraalVM — , . Truffle GraalVM , VisualVM.


6. JVM


, , , Java . API org.graalvm.polyglot , .


 import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; public class ExtendJava { public static void main(String[] args) { String language = "js"; try (Context context = Context.newBuilder().allowNativeAccess(true).build()) { for (String arg: args) { if (arg.startsWith("-")) { language = arg.substring(1); } else { Value v = context.eval(language, arg); System.out.println(v); } } } } } 

javac java GraalVM, org.graalvm.* classpath , .. .


 $ javac ExtendJava.java $ java ExtendJava '14 + 2' 16 $ java ExtendJava -js 'Math.sqrt(14)' 3.7416573867739413 $ java ExtendJava -python '[2**n for n in range(0, 8)]' [1, 2, 4, 8, 16, 32, 64, 128] $ java ExtendJava -ruby '[4, 2, 3].sort' [2, 3, 4] 

, — , node ruby , GraalVM.


GraalVM — Java . Polyglot API “” Java , .


7. -


GraalVM , , — , , GraalVM, - . , JavaScript , V8, Python — CPython , .. . GraalVM — Polyglot .


GraalVM, , JavaScript. Polyglot , , :


 $ graalvm-1.0.0-rc1/Contents/Home/jre/lib/svm/bin/rebuild-images libpolyglot 

C, , , GraalVM, . ExtendJava , , .


 #include <stdlib.h> #include <stdio.h> #include <polyglot_api.h> int main(int argc, char **argv) { graal_isolate_t *isolate = NULL; graal_isolatethread_t *thread = NULL; if (graal_create_isolate(NULL, &isolate) != 0 || (thread = graal_current_thread(isolate)) == NULL) { fprintf(stderr, "initialization error\n"); return 1; } poly_context context = NULL; if (poly_create_context(thread, NULL, 0, &context) != poly_ok) { fprintf(stderr, "initialization error\n"); return 1; } char* language = "js"; for (int n = 1; n < argc; n++) { if (argv[n][0] == '-') { language = &argv[n][1]; } else { poly_value result = NULL; if (poly_context_eval(thread, context, language, "unicalc", argv[n], &result) != poly_ok) { fprintf(stderr, "eval error\n"); return 1; } char buffer[1024]; size_t length; if (poly_value_to_string_utf8(thread, result, buffer, sizeof(buffer), &length) != poly_ok) { fprintf(stderr, "to string error\n"); return 1; } buffer[length] = '\0'; printf("%s\n", buffer); poly_destroy_handle(thread, result); } } return 0; } 

, polyglot GraalVM. , , JVM.


 $ clang -Igraalvm-1.0.0-rc1/Contents/Home/jre/lib/polyglot / -rpath graalvm-1.0.0-rc1/Contents/Home / -Lgraalvm-1.0.0-rc1/Contents/Home/jre/lib/polyglot / -lpolyglot extendc.c -o extendc $ otool -L extendc extendc: .../libpolyglot.dylib ... .../libSystem.B.dylib ... 

 $ ./extendc '14 + 2' 16 $ ./extendc -js 'Math.sqrt(14)' 3.7416573867739413 $ ./extendc -python '[2**n for n in range(0, 8)]' [1, 2, 4, 8, 16, 32, 64, 128] 

, GraalVM — - , , GraalVM.


8. Java -


Java , , , , - , . Java - , JVM , .


GraalVM Java , , - , . , , Java JVM.


, Apache SIS , ( ) . SIS 0.8, http://sis.apache.org/ jar.


 import org.apache.sis.distance.DistanceUtils; public class Distance { public static void main(String[] args) { final double aLat = Double.parseDouble(args[0]); final double aLong = Double.parseDouble(args[1]); final double bLat = Double.parseDouble(args[2]); final double bLong = Double.parseDouble(args[3]); System.out.printf("%.2f km%n", DistanceUtils.getHaversineDistance(aLat, aLong, bLat, bLong)); } public static double distance(IsolateThread thread, double aLat, double aLong, double bLat, double bLong) { return DistanceUtils.getHaversineDistance(aLat, aLong, bLat, bLong); } } 

, -


 $ javac -cp sis.jar -parameters Distance.java $ java -cp sis.jar:. Distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km 

, topten .


 $ native-image --no-server -cp sis.jar:. Distance ... $ ./distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km 

, . , @CEntryPoint


 ... import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.c.function.CEntryPoint; public class Distance { ... @CEntryPoint(name = "distance") public static double distance(IsolateThread thread, double a_lat, double a_long, double b_lat, double b_long) { return DistanceUtils.getHaversineDistance(a_lat, a_long, b_lat, b_long); } ... } 

javac , GraalVM API classpath . C .


 $ native-image --no-server -cp sis.jar:. -H:Kind=SHARED_LIBRARY \ -H:Name=libdistance $ otool -L libdistance.dylib # .so on Linux libdistance.dylib: .../libdistance.dylib ... .../CoreFoundation.framework ... .../libz.1.dylib ... .../libSystem.B.dylib ... $ du -h libdistance.dylib 4.8M libdistance.dylib 

, . , : VM , , .


 #include <stdlib.h> #include <stdio.h> #include <libdistance.h> int main(int argc, char **argv) { graal_isolate_t *isolate = NULL; graal_isolatethread_t *thread = NULL; if (graal_create_isolate(NULL, &isolate) != 0 || (thread = graal_current_thread(isolate)) == NULL) { fprintf(stderr, "initialization error\n"); return 1; } double a_lat = strtod(argv[1], NULL); double a_long = strtod(argv[2], NULL); double b_lat = strtod(argv[3], NULL); double b_long = strtod(argv[4], NULL); printf("%.2f km\n", distance(thread, a_lat, a_long, b_lat, b_long)); return 0; } 

, ( LD_LIBRARY_PARTH=. Linux)


 $ clang -I. -L. -ldistance distance.c -o distance $ otool -L distance distance: .../libdistance.dylib ... .../libSystem.B.dylib ... $ ./distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km 

GraalVM — java - , JVM


9.


Polyglot — Oracle. Oracle Database Multilingual Engine (MLE), GraalVM SQL.


, front-end, JavaScript email , JavaScript validator . - , SQL PL/SQL. , .


MLE Docker :


https://oracle.imtqy.com/oracle-db-mle/releases/0.2.7/docker/


Docker Daemon.


 $ docker load --input mle-docker-0.2.7.tar.gz 

, Docker, , ( ), Bash .


 $ docker run mle-docker-0.2.7 $ docker ps $ docker exec -ti <container_id> bash -li 

sqlplus ( SQL ), Bash, , , .


 $ sqlplus scott/tiger@localhost:1521/ORCLCDB 

, sqlplus . , Bash Docker, dbjs , . sqlplus .


 $ npm install validator $ npm install @types/validator $ dbjs deploy -u scott -p tiger -c localhost:1521/ORCLCDB validator $ sqlplus scott/tiger@localhost:1521/ORCLCDB 

validator SQL .


 SQL> select validator.isEmail('hello.world@oracle.com') from dual; VALIDATOR.ISEMAIL('HELLO.WORLD@ORACLE.COM') ------------------------------------------- 1 SQL> select validator.isEmail('hello.world') from dual; VALIDATOR.ISEMAIL('HELLO.WORLD') -------------------------------- 0 

, GraalVM — , GraalVM, Oracle. , front-end back-end, , , .


10. GraalVM


Oracle Labs JavaScript, R, Ruby, Python C , Truffle, GraalVM.


Truffle — java , (AST). AST — , , , , , . , , Truffle Graal JIT , AST .


Truffle, GraalVM , , DSL. Truffle Graal , , Truffle — GraalVM. , , , , . , , . Oracle labs Ruby , , .


, , , SimpleLanguage — Truffle, JavaScript. , , , , , if .


, Truffle Oracle Labs, SmallTalk , Newspeak Lisp . Lisp , .


Conclusion


GraalVM — , , . , , , , .


GraalVM, http://www.graalvm.org/ . , , .


, , . , GraalVM @ChrisGSeaton @shelajev .


: Oleg Šelajev , Olya Gupalo Doug Simon


')

Source: https://habr.com/ru/post/433432/


All Articles