Skip to content

DevTools and VS Code DAP cannot inspect ProxyObject members — makes interop debugging very difficult #955

@roms751

Description

@roms751

Hello,

I am building a framework that exposes Java objects to JavaScript running on GraalVM via ProxyObject.
This use-case is similar to what frameworks like Odoo do: business objects manipulated dynamically from TypeScript/JavaScript.

Everything works functionally, but debugging becomes extremely difficult, because:

  • Chrome DevTools
  • VS Code (DAP or Inspector mode)
    cannot inspect the fields of a ProxyObject, even when those fields are successfully readable from JavaScript through normal property access (obj.field).

This makes ProxyObject-based interop essentially opaque to developers.

Minimal reproducible example

  • Java side
    public class Record implements ProxyObject {
    private final Map<String, Object> fields = Map.of(
    "counter", 42,
    "name", "Test"
    );

    @OverRide
    public Object getMember(String key) {
    return fields.get(key);
    }

    @OverRide
    public Object getMemberKeys() {
    return fields.keySet().toArray(String[]::new);
    }

    @OverRide
    public boolean hasMember(String key) {
    return fields.containsKey(key);
    }
    }

  • Host setup
    Context c = Context.newBuilder("js")
    .allowAllAccess(true)
    .option("inspect", "9229")
    .option("inspect.Secure", "false")
    .option("inspect.Suspend", "true")
    .build();

c.getBindings("js").putMember("rec", new Record());
c.eval("js", "debugger; rec.counter;");

  • Observed behavior

In Chrome DevTools:

  • The Scope pane shows:
    rec: DefaultProxyObject { }
  • No expandable properties
  • No members visible
  • Hovering rec shows nothing
    VS Code behaves the same (DAP or Inspector)

Yet, entering in the console:
rec.counter
→ 42

This demonstrates that GraalVM correctly implements interop access, but the debugger does not request or does not receive the corresponding member list.

Expected behavior

When a ProxyObject implements:

  • getMember
  • getMemberKeys
  • hasMember
    DevTools (or DAP) should ideally allow:
  • expanding the object in the variable inspector,
  • listing its members (similar to a JavaScript object),
  • inspecting nested values.

This would make ProxyObject usable for real-world polyglot development.

Why this matters:

ProxyObject is currently the only way to expose a live Java object to JavaScript with full interop semantics.

But without the ability to inspect members in the debugger, it becomes extremely hard to build frameworks or systems such as:

  • business models / ERP-like systems,
  • embedded scripting,
  • game engines,
  • DSLs backed by Java semantics,
  • dynamic configuration or automation systems.

The only workaround is manually calling:
Polyglot.getMembers(obj)
or implementing a manual “debug snapshot” method.
These solutions work but are cumbersome and reduce developer productivity.

Feature request:

It would be extremely helpful if:

  1. DevTools and DAP could query getMemberKeys() when inspecting a ProxyObject
  2. and display the members in the debugger variables tree,
  3. possibly also enabling write access via putMember, if implemented.

This would make ProxyObject-based interop a first-class experience for debugging.

Environment

  • GraalVM 24.x / 25.x
  • Java ProxyObject interop
  • Chrome DevTools inspector
  • VS Code “Attach to GraalVM” (DAP)
  • JavaScript guest language

Thank you
This improvement would unlock many real applications of GraalVM’s polyglot engine, especially frameworks that expose rich Java objects to JavaScript.

Happy to provide more examples, debug sessions, or a runnable demo if needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions