oracle/graal · error · EspressoParseError

Espresso cannot evaluate Java sources directly, only a few s

Error message

Espresso cannot evaluate Java sources directly, only a few special commands are supported: <Bindings> and <ProcessReferences>
Use the "java" language bindings to load guest Java classes e.g. context.getBindings("java").getMember("java.lang.Integer")

What it means

EspressoLanguage.parse() implements the Polyglot 'java' language's eval entry point, but Espresso deliberately has no Java parser/interpreter for snippets. Only three magic strings are recognized as eval 'sources': the exit-code command (ExitCodeNode.EVAL_NAME), the bindings command (GetBindingsNode.EVAL_NAME), and the process-references command (ReferenceProcessRootNode.EVAL_NAME). Any other string passed to context.eval("java", ...) throws EspressoParseError with this message.

Source

Thrown at espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java:523

        assert EspressoContext.get(null).isInitialized();
        String contents = request.getSource().getCharacters().toString();
        if (com.oracle.truffle.espresso.nodes.commands.DestroyVMNode.EVAL_NAME.equals(contents)) {
            RootNode node = new com.oracle.truffle.espresso.nodes.commands.DestroyVMNode(this);
            return node.getCallTarget();
        }
        if (ExitCodeNode.EVAL_NAME.equals(contents)) {
            RootNode node = new ExitCodeNode(this);
            return node.getCallTarget();
        }
        if (GetBindingsNode.EVAL_NAME.equals(contents)) {
            RootNode node = new GetBindingsNode(this);
            return node.getCallTarget();
        }
        if (ReferenceProcessRootNode.EVAL_NAME.equals(contents)) {
            RootNode node = new ReferenceProcessRootNode(this);
            return node.getCallTarget();
        }
        throw new EspressoParseError(
                        "Espresso cannot evaluate Java sources directly, only a few special commands are supported: " + GetBindingsNode.EVAL_NAME + " and " + ReferenceProcessRootNode.EVAL_NAME +
                                        "\n" +
                                        "Use the \"" + ID + "\" language bindings to load guest Java classes e.g. context.getBindings(\"" + ID + "\").getMember(\"java.lang.Integer\")");
    }

    @Override
    public NameSymbols getNames() {
        return nameSymbols;
    }

    public Utf8Symbols getUtf8Symbols() {
        return utf8Symbols;
    }

    @Override
    public TypeSymbols getTypes() {
        return typeSymbols;
    }

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Load compiled guest classes via context.getBindings("java").getMember("java.lang.Integer") (fully-qualified class name) and call members on the returned Value object.
  2. Put the guest code on the classpath (Context option 'java.Classpath' or host classpath) and access it through the bindings, not by evaluating source text.
  3. For host-side scripting of Java syntax, use a real Java scripting engine; Espresso only executes bytecode.
  4. If you need the exit code of the guest VM, eval the internal exit-code command constant instead of custom strings.

Example fix

// before
Value v = context.eval("java", "1 + 1");

// after
Value math = context.getBindings("java").getMember("java.lang.Math");
Value v = math.getMember("max").execute(1, 1);
Defensive patterns

Strategy: validation

Validate before calling

// Before eval: Espresso only accepts its internal command names
String src = snippet.trim();
if (!src.equals("<process-exit-code>") /* ExitCodeNode.EVAL_NAME */
        && !src.equals("<bindings>") /* GetBindingsNode.EVAL_NAME */
        && !src.equals("<process-references>")) {
    // don't eval; go through bindings instead
    Value cls = ctx.getBindings("java").getMember(fqcn);
}

Type guard

static boolean isEspressoEvalSupported(String src) {
    return src.equals("<process-exit-code>")
        || src.equals("<bindings>")
        || src.equals("<process-references>");
}

Try / catch

try {
    Value v = ctx.eval("java", snippet);
} catch (PolyglotException e) {
    if (e.isSyntaxError()) {
        // fall back to class-loading via bindings
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling context.eval("java", "System.out.println(1)") or any Java source/expression snippet from a Polyglot Context. Only exact matches of the internal EVAL_NAME constants (used by Espresso's own launcher machinery to fetch exit codes and bindings) succeed.

Common situations: Developers porting Polyglot code from JS/Python (where eval works) to Java-on-Espresso; trying to run a guest class by evaluating its source; REPL-style experiments with the 'java' language id.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/71e5bd89bbeac2a6. Report an issue: GitHub.