GraalVM Polyglot API for embedding multiple programming languages in Java applications with secure language interoperability
—
Context management provides the foundational execution environment for polyglot programming. Contexts are isolated environments where guest language code executes with configurable security policies, resource limits, and access controls.
Create polyglot contexts for executing guest language code.
public final class Context implements AutoCloseable {
public static Context create(String... permittedLanguages);
public static Context getCurrent();
}Usage:
// Create context for specific languages
Context jsContext = Context.create("js");
Context pythonContext = Context.create("python");
Context multiContext = Context.create("js", "python", "R");
// Get currently active context (from within guest code execution)
Context current = Context.getCurrent();Configure contexts with advanced options before creation.
public static final class Context.Builder {
// Access control configuration
public Context.Builder allowHostAccess(HostAccess config);
public Context.Builder extendHostAccess(HostAccess defaultInitialValue, Consumer<HostAccess.Builder> setup);
public Context.Builder allowPolyglotAccess(PolyglotAccess config);
public Context.Builder allowCreateThread(boolean enabled);
public Context.Builder allowNativeAccess(boolean enabled);
public Context.Builder allowAllAccess(boolean enabled);
public Context.Builder allowHostClassLookup(Predicate<String> classFilter);
public Context.Builder allowHostClassLoading(boolean enabled);
public Context.Builder allowValueSharing(boolean enabled);
public Context.Builder allowInnerContextOptions(boolean enabled);
public Context.Builder allowCreateProcess(boolean enabled);
// I/O and environment configuration
public Context.Builder allowIO(IOAccess ioAccess);
public Context.Builder extendIO(IOAccess defaultInitialValue, Consumer<IOAccess.Builder> setup);
public Context.Builder allowEnvironmentAccess(EnvironmentAccess accessPolicy);
public Context.Builder environment(String name, String value);
public Context.Builder environment(Map<String, String> env);
public Context.Builder currentWorkingDirectory(Path workingDirectory);
// Stream configuration
public Context.Builder in(InputStream in);
public Context.Builder out(OutputStream out);
public Context.Builder err(OutputStream err);
// Engine and options
public Context.Builder engine(Engine engine);
public Context.Builder allowExperimentalOptions(boolean enabled);
public Context.Builder option(String key, String value);
public Context.Builder options(Map<String, String> options);
public Context.Builder arguments(String language, String[] args);
// Security and sandbox
public Context.Builder sandbox(SandboxPolicy policy);
public Context.Builder resourceLimits(ResourceLimits limits);
public Context.Builder useSystemExit(boolean enabled);
// Additional configuration
public Context.Builder hostClassLoader(ClassLoader classLoader);
public Context.Builder timeZone(ZoneId zone);
public Context.Builder logHandler(Handler logHandler);
public Context.Builder logHandler(OutputStream logOut);
public Context.Builder serverTransport(MessageTransport serverTransport);
public Context.Builder processHandler(ProcessHandler handler);
// Builder utilities
public Context.Builder apply(Consumer<Builder> action);
public Context build();
// Deprecated methods (for completeness)
@Deprecated public Context.Builder allowHostAccess(boolean enabled);
@Deprecated public Context.Builder hostClassFilter(Predicate<String> classFilter);
@Deprecated public Context.Builder allowIO(boolean enabled);
@Deprecated public Context.Builder fileSystem(FileSystem fileSystem);
}Usage:
Context context = Context.newBuilder("js")
.allowHostAccess(HostAccess.ALL)
.allowPolyglotAccess(PolyglotAccess.ALL)
.allowIO(IOAccess.ALL)
.sandbox(SandboxPolicy.CONSTRAINED)
.resourceLimits(ResourceLimits.newBuilder()
.statementLimit(10000, null)
.build())
.build();Execute and parse source code within contexts.
public Value eval(String languageId, CharSequence source);
public Value eval(Source source);
public Value parse(String languageId, CharSequence source);
public Value parse(Source source);Usage:
try (Context context = Context.create("js")) {
// Direct execution
Value result = context.eval("js", "Math.sqrt(16)");
System.out.println(result.asDouble()); // 4.0
// Parse without execution
Value function = context.parse("js", "(x) => x * x");
Value squared = function.execute(5);
System.out.println(squared.asInt()); // 25
// Execute from Source
Source source = Source.create("js", "console.log('Hello from JS')");
context.eval(source);
}Access and manipulate language-specific global bindings.
public Value getBindings(String languageId);Usage:
try (Context context = Context.create("js")) {
Value bindings = context.getBindings("js");
// Set global variables
bindings.putMember("myVar", 42);
bindings.putMember("myFunction", new MyJavaFunction());
// Access global variables
context.eval("js", "myVar = myVar * 2");
Value result = bindings.getMember("myVar");
System.out.println(result.asInt()); // 84
}Convert host values to polyglot values.
public Value asValue(Object hostValue);Usage:
try (Context context = Context.create("js")) {
// Convert Java objects to polyglot values
List<String> javaList = Arrays.asList("a", "b", "c");
Value polyglotArray = context.asValue(javaList);
Map<String, Integer> javaMap = Map.of("x", 1, "y", 2);
Value polyglotObject = context.asValue(javaMap);
// Use in guest language
context.getBindings("js").putMember("data", polyglotArray);
context.eval("js", "console.log(data[0])"); // "a"
}Control context execution and lifecycle.
public void enter();
public void leave();
public boolean interrupt(Duration timeout);
public void resetLimits();
public void safepoint();
public void close();
public boolean isClosed();
public Engine getEngine();Usage:
Context context = Context.create("js");
// Manual context entering (advanced usage)
context.enter();
try {
// Context is active on current thread
Value result = context.eval("js", "42");
} finally {
context.leave();
}
// Interrupt long-running execution
CompletableFuture.runAsync(() -> {
context.eval("js", "while(true) {}"); // Infinite loop
});
// Interrupt after 5 seconds
boolean interrupted = context.interrupt(Duration.ofSeconds(5));
System.out.println("Interrupted: " + interrupted);
// Reset resource limits
context.resetLimits();
// Force a safepoint check
context.safepoint();
// Close context
context.close();Contexts throw PolyglotException for guest language errors:
try (Context context = Context.create("js")) {
context.eval("js", "throw new Error('Something went wrong')");
} catch (PolyglotException e) {
if (e.isGuestException()) {
System.out.println("Guest error: " + e.getMessage());
System.out.println("Location: " + e.getSourceLocation());
}
}Contexts implement AutoCloseable and should be used with try-with-resources:
// Recommended pattern
try (Context context = Context.create("js")) {
// Use context
} // Automatically closed
// Or explicit closing
Context context = Context.create("js");
try {
// Use context
} finally {
context.close();
}Contexts are not thread-safe. Each context should be used by only one thread at a time, or proper synchronization must be implemented. For multi-threaded usage, create separate contexts or use proper locking mechanisms.
Install with Tessl CLI
npx tessl i tessl/maven-org-graalvm-polyglot--polyglot