Ironically, I'm hitting a similar issue with a library doing an Object.keys() call against a custom JSObject, can you share the solution you've taken?
Also, I'm guessing this is the RFE you created: https://bugs.openjdk.java.net/browse/JDK-8181203?jql=text%20~%20%22Object.keys%20nashorn%22 Thanks! Jesse On Tue, May 30, 2017 at 9:34 AM Daniel Einspanjer <deinspan...@gmail.com> wrote: > Thank you, yes that is very similar to the approach I went down. > Ultimately I hit another roadblock that forced me to approach the entire > issue differently. The JS library I am interacting with uses Object.keys() > and currently, Nashorn doesn't support Object.keys() calls with custom > JSObjects. I filed an RFE for that, but due to the issue, I'm having to > avoid using JSObject entirely. > > Thanks again for your reply. > > -Daniel > > On Tue, May 30, 2017 at 12:29 PM Jesse Schulman <je...@dreamtsoft.com> > wrote: > >> If you haven't got this working yet, one possible solution is to return >> anonymous inner AbstractJSObject that returns true for isFunction calls: >> >> public Object getMember(String name) { >> if ("map".equals(name)) { >> return new AbstractJSObject() { >> @Override >> public Object call(Object thiz, Object... args) { >> // delegate to your JsonArray.map method from this >> annonymous inner class >> // in your example nashorn should pass you a single >> instance of ScriptObjectMirror for args that returns true for isFunction() >> call >> } >> >> @Override >> public boolean isFunction() { >> return true; >> } >> }; >> } >> >> return null; >> } >> >> >> Hope that helps! >> Jesse >> >> On Thu, May 25, 2017 at 1:11 PM Daniel Einspanjer <deinspan...@gmail.com> >> wrote: >> >>> I have a project that makes extensive use of the Google Gson library. >>> >>> In this particular case, I have a JsonArray object (which implements >>> iterable) containing a collection of objects. In pure JSON it would look >>> like this: >>> >>> [ 1, true, {"a": "b"}, [1,2] ] >>> >>> In Gson JsonElements, it looks like this: >>> >>> arr = new JsonArray(); >>> arr.add(1); >>> arr.add(true); >>> >>> obj = new JsonObject(); >>> obj.addProperty("a", "b"); >>> >>> arr.add(obj); >>> >>> innerArr = new JsonArray(); >>> innerArr.add(1); >>> innerArr.add(2); >>> >>> arr.add(innerArr); >>> >>> I am calling a Javascript function in Nashorn that is trying to do a map >>> over this array: >>> >>> nash.eval("function doIt(arr) { print(arr.map(function(item) { return >>> (typeof item); })); }"); >>> >>> So, in order for this to work with my own arbitrary object (JsonArray), I >>> believe I need to implement JSObject. >>> >>> I created the wrapper class that implements it, using the underlying >>> JsonArray object as a delegate. things like isArray() and such are >>> trivial, but I'm having trouble with the map. >>> I have a map method that takes a functional interface which is available >>> for the JsonArray object. >>> >>> Nashorn calls getMember("map") when the doIt function is executed. I >>> cannot figure out how to give it an appropriate function reference to my >>> JsonArray.map method. >>> I was able to handle getMember("toString") easily enough, but the problem >>> is that method doesn't take any arguments, so returning a simple >>> Callable<Object> is fine for it, but map is going to take arguments that >>> I >>> don't know about ahead of time. >>> >>> I would really appreciate some assistance here. Thanks. >>> >>> -Daniel >>> >>