{"record":{"id":"71e5bd89bbeac2a6","repo":"oracle/graal","slug":"espresso-cannot-evaluate-java-sources-directly-on","errorCode":null,"errorMessage":"Espresso cannot evaluate Java sources directly, only a few special commands are supported: <Bindings> and <ProcessReferences>\nUse the \"java\" language bindings to load guest Java classes e.g. context.getBindings(\"java\").getMember(\"java.lang.Integer\")","messagePattern":"Espresso cannot evaluate Java sources directly, only a few special commands are supported: <Bindings> and <ProcessReferences>\nUse the \"java\" language bindings to load guest Java classes e\\.g\\. context\\.getBindings\\(\"java\"\\)\\.getMember\\(\"java\\.lang\\.Integer\"\\)","errorType":"validation","errorClass":"EspressoParseError","httpStatus":null,"severity":"error","filePath":"espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java","lineNumber":523,"sourceCode":"        assert EspressoContext.get(null).isInitialized();\n        String contents = request.getSource().getCharacters().toString();\n        if (com.oracle.truffle.espresso.nodes.commands.DestroyVMNode.EVAL_NAME.equals(contents)) {\n            RootNode node = new com.oracle.truffle.espresso.nodes.commands.DestroyVMNode(this);\n            return node.getCallTarget();\n        }\n        if (ExitCodeNode.EVAL_NAME.equals(contents)) {\n            RootNode node = new ExitCodeNode(this);\n            return node.getCallTarget();\n        }\n        if (GetBindingsNode.EVAL_NAME.equals(contents)) {\n            RootNode node = new GetBindingsNode(this);\n            return node.getCallTarget();\n        }\n        if (ReferenceProcessRootNode.EVAL_NAME.equals(contents)) {\n            RootNode node = new ReferenceProcessRootNode(this);\n            return node.getCallTarget();\n        }\n        throw new EspressoParseError(\n                        \"Espresso cannot evaluate Java sources directly, only a few special commands are supported: \" + GetBindingsNode.EVAL_NAME + \" and \" + ReferenceProcessRootNode.EVAL_NAME +\n                                        \"\\n\" +\n                                        \"Use the \\\"\" + ID + \"\\\" language bindings to load guest Java classes e.g. context.getBindings(\\\"\" + ID + \"\\\").getMember(\\\"java.lang.Integer\\\")\");\n    }\n\n    @Override\n    public NameSymbols getNames() {\n        return nameSymbols;\n    }\n\n    public Utf8Symbols getUtf8Symbols() {\n        return utf8Symbols;\n    }\n\n    @Override\n    public TypeSymbols getTypes() {\n        return typeSymbols;\n    }","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoLanguage.java#L505-L541","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Load compiled guest classes via context.getBindings(\"java\").getMember(\"java.lang.Integer\") (fully-qualified class name) and call members on the returned Value object.","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.","For host-side scripting of Java syntax, use a real Java scripting engine; Espresso only executes bytecode.","If you need the exit code of the guest VM, eval the internal exit-code command constant instead of custom strings."],"exampleFix":"// before\nValue v = context.eval(\"java\", \"1 + 1\");\n\n// after\nValue math = context.getBindings(\"java\").getMember(\"java.lang.Math\");\nValue v = math.getMember(\"max\").execute(1, 1);","handlingStrategy":"validation","validationCode":"// Before eval: Espresso only accepts its internal command names\nString src = snippet.trim();\nif (!src.equals(\"<process-exit-code>\") /* ExitCodeNode.EVAL_NAME */\n        && !src.equals(\"<bindings>\") /* GetBindingsNode.EVAL_NAME */\n        && !src.equals(\"<process-references>\")) {\n    // don't eval; go through bindings instead\n    Value cls = ctx.getBindings(\"java\").getMember(fqcn);\n}","typeGuard":"static boolean isEspressoEvalSupported(String src) {\n    return src.equals(\"<process-exit-code>\")\n        || src.equals(\"<bindings>\")\n        || src.equals(\"<process-references>\");\n}","tryCatchPattern":"try {\n    Value v = ctx.eval(\"java\", snippet);\n} catch (PolyglotException e) {\n    if (e.isSyntaxError()) {\n        // fall back to class-loading via bindings\n    } else { throw e; }\n}","preventionTips":["Treat the 'java' language as class-loading-only; never eval Java source snippets.","Centralize guest access through getBindings(\"java\") in one wrapper class.","Add a smoke test asserting the eval path is never used with arbitrary strings."],"tags":["espresso","graalvm","polyglot","eval","parse-error"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}