Back

Build a Polyglot Native Executable (Java and JavaScript)

With GraalVM Polyglot API you can embed and run code from a guest language in a Java-based host application. GraalVM makes it possible to ahead-of-time compile a Java application with embedded JavaScript and to create a polyglot native executable. See the Embedding Languages documentation for more information on how a Java host application can interact with a guest language like JavaScript.

This guide will show how to build a polyglot native executable with Java as a host language and JavaScript as a guest language.

For the demo part, you will use a simple JSON Pretty Printer Java application that prints the output in the JSON format.

  1. Make sure you have installed a GraalVM JDK. The easiest way to get started is with SDKMAN!. For other installation options, visit the Downloads section.

  2. Create a Maven project and replace the default Application.java file with a file named PrettyPrintJSON.java. Copy paste the following content into the file:

     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), null, 2);
           System.out.println(result.asString());
         }
       }
     } 
    
  3. Open your project configuration file (in this case, pom.xml) and add the following dependencies to enable interoperability with JavaScript.

    • To enable the polyglot runtime:
      <dependency>
          <groupId>org.graalvm.polyglot</groupId>
          <artifactId>polyglot</artifactId> 
          <version>${graalvm.version}</version>
      </dependency>
      
    • To enable Javascript:
      <dependency>
          <groupId>org.graalvm.polyglot</groupId>
          <artifactId>js</artifactId> 
          <version>${graalvm.version}</version>
      </dependency>
      
  4. Compile the project using the GraalVM JDK:
     ./mvnw clean package
    
  5. Build a native executable:

     native-image PrettyPrintJSON
    

    It takes several minutes as it does not just build the executable, but also pulls in the JavaScript engine. The JavaScript context will be available in the generated image.

    Note: Building a polyglot native executable requires more physical memory because the Truffle framework is included.

  6. Run the resulting executable and perform some pretty-printing:

     ./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
    

    The expected output is:

     {
     "GraalVM": {
         "description": "Language Abstraction Platform",
         "supports": [
         "combining languages",
         "embedding languages",
         "creating native images"
         ],
         "languages": [
         "Java",
         "JavaScript",
         "Node.js",
         "Python",
         "Ruby",
         "R",
         "LLVM"
         ]
     }
     }
    

The native executable version runs faster than running the same application on the JVM.

Note: JavaScript support by GraalVM Native Image is considered general availability. The remaining languages support is experimental.

Connect with us