Yes, that is the bug. My work around isn't great, I just had to avoid using any form of custom JSObject. Instead, I do an eval('new Object()') to get a holder and put my object and functions inside it via put().
-Daniel On Thu, Jun 1, 2017, 6:30 PM Jesse Schulman <je...@dreamtsoft.com> wrote: > 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 >>>> >>>