Search code examples
javascriptjavarhinonashornjsr223

How to get the attribute of a JS object from Java?


I know I can use the Invocable class to invoke methods on a class:

import javax.script.{ScriptEngine, ScriptEngineManager, Invocable}

val engine = new ScriptEngineManager().getEngineByExtension("js")

val invoker = engine.asInstanceOf[Invocable]

val person = engine.eval(s"""
  new function () {
    this.name = "Rick";
    this.age = 28;
    this.speak = function () {
      return this.name + "-" + this.age;
    }
  };
""")

invoker.invokeMethod(person, "speak") //returns "Rick-28"

But, how do I get the name attribute of the person? I tried invoker.invokeMethod(person, "name") and I got a NoSuchMethodError.


Solution

  • You can cast person to a JSObject and then call person.getMember("name"). Full Java example:

    ScriptEngine engine = new ScriptEngineManager()
                               .getEngineByExtension("js");
    
    JSObject rick = (JSObject) engine.eval("new function () {\n" +
            "            this.name = \"Rick\";\n" +
            "            this.age = 28;\n" +
            "            this.speak = function () {\n" +
            "                return this.name + \"-\" + this.age;\n" +
            "            }\n" +
            "        };");
    
    System.out.println(rick.getMember("name"));
    

    Or, if the object is stored in the engine global scope like in the following javascript source:

    rick = function() {
      this.name= "Rick";
    };
    

    you can then call

    engine.eval("rick.name");