That's the approach I took too, however I avoided the eval by doing
bindings.get("Object").newObject() but you should be able to do the same
thing against the engine if you don't use different bindings.On Thu, Jun 1, 2017 at 5:32 PM Daniel Einspanjer <[email protected]> wrote: > 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 <[email protected]> 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 <[email protected]> >> 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 <[email protected]> >>> 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 < >>>> [email protected]> 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 >>>>> >>>>
