How to properly implement JSObject to provide conversion of Gson JsonElement objects?

Daniel Einspanjer deinspanjer at gmail.com
Tue May 30 16:34:44 UTC 2017


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 <jesse at 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 <deinspanjer at 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
>>
>


More information about the nashorn-dev mailing list