CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-graalvm-polyglot--polyglot

GraalVM Polyglot API for embedding multiple programming languages in Java applications with secure language interoperability

Pending
Overview
Eval results
Files

source-management.mddocs/

Source Management

Source management provides representation and handling of source code for polyglot execution. Sources encapsulate executable code with metadata, support various input methods, and enable caching for optimal performance.

Capabilities

Source Creation

Create source objects from different input types.

public final class Source {
    // Quick creation shortcut
    public static Source create(String language, CharSequence source);
    
    // Builder pattern for various source types
    public static Source.Builder newBuilder(String language, CharSequence characters, String name);
    public static Source.Builder newBuilder(String language, ByteSequence bytes, String name);
    public static Source.Builder newBuilder(String language, File file);
    public static Source.Builder newBuilder(String language, URL url);
    public static Source.Builder newBuilder(String language, Reader source, String name);
    
    // Language and MIME type detection
    public static String findLanguage(File file) throws IOException;
    public static String findLanguage(URL url) throws IOException;
    public static String findLanguage(String mimeType);
    public static String findMimeType(File file) throws IOException;
    public static String findMimeType(URL url) throws IOException;
}

Usage:

// Quick creation from string
Source jsCode = Source.create("js", "console.log('Hello World')");

// Create from string with builder
Source namedCode = Source.newBuilder("js", "function add(a, b) { return a + b; }", "math.js")
    .buildLiteral();

// Create from file
Source fileSource = Source.newBuilder("js", new File("/path/to/script.js"))
    .build();

// Create from URL
URL scriptUrl = new URL("https://example.com/script.js");
Source urlSource = Source.newBuilder("js", scriptUrl)
    .build();

// Create from Reader
StringReader reader = new StringReader("print('Hello from Python')");
Source readerSource = Source.newBuilder("python", reader, "inline.py")
    .build();

// Create from bytes
ByteSequence scriptBytes = ByteSequence.create("console.log('From bytes')".getBytes(StandardCharsets.UTF_8));
Source bytesSource = Source.newBuilder("js", scriptBytes, "bytes.js")
    .buildLiteral();

// Auto-detect language from file
String language = Source.findLanguage(new File("script.py")); // "python"
Source autoSource = Source.newBuilder(language, new File("script.py"))
    .build();

Source Builder

Configure sources with advanced options.

public static final class Source.Builder {
    public Source.Builder name(String newName);
    public Source.Builder content(String code);
    public Source.Builder content(CharSequence characters);
    public Source.Builder content(ByteSequence bytes);
    public Source.Builder mimeType(String mimeType);
    public Source.Builder interactive(boolean interactive);
    public Source.Builder internal(boolean internal);
    public Source.Builder cached(boolean cached);
    public Source.Builder uri(URI newUri);
    public Source.Builder encoding(Charset encoding);
    public Source.Builder option(String key, String value);
    public Source.Builder options(Map<String, String> options);
    public Source build() throws IOException;
    public Source buildLiteral();
}

Usage:

Source complexSource = Source.newBuilder("js", "const result = calculate(42);", "complex-script.js")
    .cached(true)
    .interactive(false)
    .internal(false)
    .encoding(StandardCharsets.UTF_8)
    .uri(URI.create("file:///path/to/script.js"))
    .buildLiteral();

Source Properties

Access source metadata and content.

public CharSequence getCharacters();
public String getName();
public String getPath();
public boolean isInteractive();
public String getLanguage();
public String getMimeType();
public URI getURI();
public boolean hasBytes();
public ByteSequence getBytes();
public boolean hasCharacters();
public int getLength();
public boolean isCached();
public boolean isInternal();
}

Usage:

Source source = Source.newBuilder("js", "console.log('test')", "test.js").buildLiteral();

// Access content
CharSequence content = source.getCharacters();
System.out.println("Content: " + content);

// Access metadata
String name = source.getName();        // "test.js"
String language = source.getLanguage(); // "js"
int length = source.getLength();       // Content length
boolean cached = source.isCached();    // Caching enabled

// Check content type
boolean hasChars = source.hasCharacters(); // true for text sources
boolean hasBytes = source.hasBytes();      // true for binary sources

System.out.println("Source: " + name + " (" + language + ", " + length + " chars)");

Source Sections

Work with specific sections of source code.

public SourceSection createSection(int charIndex, int length);
public SourceSection createSection(int startLine, int startColumn, int endLine, int endColumn);
public SourceSection createUnavailableSection();

Usage:

Source source = Source.create("js", "function add(a, b) {\n  return a + b;\n}", "math.js");

// Create section by character index
SourceSection functionName = source.createSection(9, 3); // "add"

// Create section by line/column
SourceSection functionBody = source.createSection(1, 21, 2, 1); // "return a + b;"

// Create unavailable section (for error handling)
SourceSection unavailable = source.createUnavailableSection();

System.out.println("Function name: " + functionName.getCharacters());
System.out.println("Function body: " + functionBody.getCharacters());

Advanced Usage

MIME Type Detection

Sources can be created with automatic MIME type detection:

// Explicit MIME type
Source explicitMime = Source.newBuilder("js")
    .mimeType("application/javascript")
    .content("console.log('test')")
    .build();

// Auto-detected from file extension
String detectedLanguage = Source.findLanguage(new File("script.py")); // "python"
Source autoMime = Source.newBuilder(detectedLanguage, new File("script.py")).build();

System.out.println("MIME type: " + autoMime.getMimeType());

Interactive Sources

Mark sources as interactive for REPL-style execution:

Source interactiveSource = Source.newBuilder("js")
    .content("2 + 2")
    .interactive(true)
    .build();

// Interactive sources may have different evaluation behavior
try (Context context = Context.create("js")) {
    Value result = context.eval(interactiveSource);
    System.out.println("Interactive result: " + result);
}

Internal Sources

Mark sources as internal (not visible in stack traces):

Source internalSource = Source.newBuilder("js")
    .content("function internal() { throw new Error('internal error'); }")
    .internal(true)
    .build();

Cached Sources

Enable caching for frequently used sources:

Source cachedSource = Source.newBuilder("js")
    .content("function expensive() { /* complex computation */ }")
    .cached(true)
    .build();

// Cached sources are stored in the engine's compilation cache
try (Engine engine = Engine.create()) {
    Context context = Context.newBuilder("js").engine(engine).build();
    
    // First execution - compiled and cached
    context.eval(cachedSource);
    
    // Subsequent executions use cached compilation
    context.eval(cachedSource); // Faster
}

Binary Sources

Work with binary source content:

// Read binary file
byte[] binaryContent = Files.readAllBytes(Paths.get("script.wasm"));
ByteSequence byteSeq = ByteSequence.create(binaryContent);
Source binarySource = Source.newBuilder("wasm", byteSeq, "module.wasm").buildLiteral();

// Access binary content
if (binarySource.hasBytes()) {
    ByteSequence bytes = binarySource.getBytes();
    System.out.println("Binary size: " + bytes.length());
}

URI-based Sources

Create sources with custom URIs for debugging and tooling:

Source uriSource = Source.newBuilder("js")
    .content("console.log('URI source')")
    .uri(URI.create("custom-scheme://my-app/dynamic-script"))
    .build();

// URI appears in stack traces and debugging tools
System.out.println("Source URI: " + uriSource.getURI());

Source Validation

Validate sources before execution:

try {
    Source source = Source.create("js", "invalid javascript syntax +++");
    
    try (Context context = Context.create("js")) {
        // Parse without executing to check syntax
        Value parsed = context.parse(source);
        System.out.println("Source is valid");
    }
} catch (PolyglotException e) {
    if (e.isSyntaxError()) {
        System.out.println("Syntax error: " + e.getMessage());
        System.out.println("Location: " + e.getSourceLocation());
    }
}

Performance Considerations

  • Caching: Enable caching for frequently executed sources to improve performance
  • Source Reuse: Reuse Source objects instead of creating new ones for the same content
  • Content Size: Large sources may impact memory usage; consider streaming for very large files
  • Binary vs Text: Use appropriate content type (binary/text) for optimal handling
  • URI Overhead: Custom URIs add minimal overhead but improve debugging experience

Error Handling

Sources can produce various exceptions during creation and execution:

try {
    // File not found
    Source fileSource = Source.newBuilder("js", new File("nonexistent.js")).build();
} catch (IOException e) {
    System.out.println("File error: " + e.getMessage());
}

try {
    // Invalid URL
    Source urlSource = Source.newBuilder("js", new URL("invalid://url")).build();
} catch (IOException e) {
    System.out.println("URL error: " + e.getMessage());
}

try (Context context = Context.create("js")) {
    Source source = Source.create("js", "syntax error +++");
    context.eval(source);
} catch (PolyglotException e) {
    if (e.isSyntaxError()) {
        System.out.println("Syntax error in source: " + e.getMessage());
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-graalvm-polyglot--polyglot

docs

context-management.md

engine-management.md

execution-monitoring.md

index.md

io-abstractions.md

proxy-system.md

security-configuration.md

source-management.md

value-operations.md

tile.json