JSON.stringify does not support Java class that extends AbstractJSObject

Bill Reed billreed63 at gmail.com
Fri Jun 10 17:03:28 UTC 2016


I have a Java class ExampleTuple2  that extends AbstractJSObject. My
ExampleTuple2 has a toJSON method. I instantiate the object in JavaScript
(nashorn) if I do a JSON.stringify(tuple2Instance) the result "undefined"

The API documentation for AbstractJSObject
https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/AbstractJSObject.html
states *"This is the base class for nashorn ScriptObjectMirror class. This
class can also be subclassed by an arbitrary Java class. Nashorn will treat
objects of such classes just like nashorn script objects. Usual nashorn
operations like obj[i], obj.foo, obj.func(), delete obj.foo will be glued
to appropriate method call of this class." *

Should my toJSON method be calls when using JSON.stringify for this type of
object?

Example of the Java code.

package org.eclairjs.nashorn.wrap;

import jdk.nashorn.api.scripting.AbstractJSObject;

import org.eclairjs.nashorn.Utils;

public class ExampleTuple2 extends AbstractJSObject {

    public abstract class WrappedFunction  extends AbstractJSObject {

        @Override

        public boolean isFunction() {

            return true;

        }

    }

    Object _1;

    Object _2;

    public ExampleTuple2(scala.Tuple2 tuple2) {

        _1=Utils.javaToJs(tuple2._1(),null);

        _2=Utils.javaToJs(tuple2._2(),null);

    }

    public ExampleTuple2(Object _1, Object _2)  {

        this._1=_1;

        this._2=_2;

    }

    WrappedFunction  F_toJSON = new WrappedFunction () {

        @Override

        public Object call(Object thiz, Object... args) {

            return "{\"0\":" + _1 + ",\"1\":" + _2 + "}" ;

        }

    };

    WrappedFunction  F_toString = new WrappedFunction () {

        @Override

        public Object call(Object thiz, Object... args) {

            return "(" + _1 + "," + _2 + ")" ;

        }

    };

    WrappedFunction  F_valueOf = new WrappedFunction () {

        @Override

        public Object call(Object thiz, Object... args) {

            return "(" + _1 + "," + _2 + ")";

        }

    };

    WrappedFunction  F_1 = new WrappedFunction () {

        @Override

        public Object call(Object thiz, Object... args) {

            return _1;

        }

    };

    WrappedFunction F_2  = new  WrappedFunction () {

        @Override

        public Object call(Object thiz, Object... args) {

            return _2;

        }

    };

    // get the value of that named property

    @Override

    public Object getMember(String name) {

        switch (name) {

            case "_1": return F_1;

            case "_2": return F_2;

            case "valueOf": return F_valueOf;

            case "toJSON": return F_toJSON;

            case "toString": return F_toString;

        }

        throw new RuntimeException("Tuple2."+name+" is not defined");

    }

    @Override

    public boolean hasMember(String name) {

        switch (name) {

            case "_1":

            case "_2":

            case "valueOf":

            case "toJSON":

            case "toString":

                return true;

        }

       return super.hasMember(name);

    }

}


Example of the JavaScript code.

var Tuple2 = Java.type('org.eclairjs.nashorn.wrap.ExampleTuple2');

var t = new Tuple2("value1", "value2");

print("t1 " + t._1());

print("t " + t);

print(JSON.stringify(t));


More information about the nashorn-dev mailing list