• Uncategorised
  • 0

GraalVM Polyglot Programming with Java, JavaScript, Ruby, and Python

GraalVM is a powerful runtime that enables you to run code written in multiple languages—like JavaScript, Python, and Ruby—side by side within the same Java application. This blog shows how to perform polyglot programming using GraalVM and Java.


✨ Prerequisites

  • Java 17+ (GraalVM-based JDK recommended)
  • Maven
  • Proper GraalVM language libraries added as dependencies

🚀 Maven Dependencies

Add the following dependencies to your pom.xml:

<dependencies>
    <!-- JavaScript support -->
    <dependency>
        <groupId>org.graalvm.polyglot</groupId>
        <artifactId>js-community</artifactId>
        <version>24.2.1</version>
        <type>pom</type>
    </dependency>

    <!-- Python support -->
    <dependency>
        <groupId>org.graalvm.polyglot</groupId>
        <artifactId>python</artifactId>
        <version>24.2.0</version>
        <type>pom</type>
    </dependency>
    <dependency>
        <groupId>org.graalvm.python</groupId>
        <artifactId>python-embedding</artifactId>
        <version>24.2.0</version>
    </dependency>

    <!-- Ruby support -->
    <dependency>
        <groupId>org.graalvm.polyglot</groupId>
        <artifactId>ruby</artifactId>
        <version>24.2.0</version>
        <type>pom</type>
    </dependency>
</dependencies>

🔧 Java Polyglot Demo

package ai;

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.io.IOAccess;

public class PolyglotDemo {
    public static void main(String[] args) {
        // Ruby execution
        try (Context context = Context.create()) {
            context.eval("ruby", "require 'json';");
            String rubyScript = "puts 'Hello from Ruby!'";
            context.eval(Source.create("ruby", rubyScript));

            String rubyJson = context.eval("ruby",
                "JSON.generate({ message: 'Hello from Ruby' })").toString();
            System.out.println("Ruby JSON: " + rubyJson);
        }

        // JavaScript execution
        try (Context context = Context.create()) {
            Value result = context.eval("js", "21 + 21");
            System.out.println("Result from JavaScript: " + result.asInt());
        }

        // Python execution with restricted I/O
        try (Context context = Context.newBuilder("python")
            .allowIO(IOAccess.newBuilder()
                .allowHostFileAccess(false)
                .allowHostSocketAccess(false)
                .build())
            .allowCreateThread(false)
            .allowNativeAccess(false)
            .build()) {

            context.eval("python", "print('Hello from GraalPy!')");
        }
    }
}

💡 Key Concepts

  • Context.create(...): Bootstraps a new language runtime
  • .eval("lang", "code"): Executes code in that language
  • Polyglot contexts can be reused or isolated
  • Security: Fine-grained I/O, native access, and thread access control

📊 Use Cases

  • Embedding business rules in JS/Python
  • Running ML models in Python from Java
  • Integrating Ruby DSLs into Java platforms

⚠️ Gotchas

  • You must use the right artifacts (e.g., python-embedding) for non-Java languages
  • Not all standard library features work out-of-the-box (especially with I/O disabled)
  • Language runtimes must be on classpath/module-path

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *