Thanks for the tip! On Fri, Jun 2, 2017, 12:38 PM Jesse Schulman <je...@dreamtsoft.com> wrote:
> 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 <deinspan...@gmail.com> > 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 <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 >>>>>> >>>>>