JSObject and delegation to other java classes

A. Sundararajan sundararajan.athijegannathan at oracle.com
Mon Jul 21 11:11:48 UTC 2014


Will this sample of any help to you?

http://hg.openjdk.java.net/jdk9/dev/nashorn/file/34a783929a67/samples/jsobj_example.js

PS. JSObject is meant for very lightweight script-like objects - says 
remote objects (where net latency is much more than proxying calls etc.) 
or expose database records as script-friendly objects and so on. If you 
want to mix-n-match Java objects + JSObjects, doing it scripts is better.

Thanks,
-Sundar

On Sunday 20 July 2014 09:09 PM, Marc Downie wrote:
> Dear Nashorn-dev,
>
> I'm building a JSObject-implementation-based to a fairly complex Java class
> --- in order to present a more JavaScript-flavored façade to some Java and
> I'm finding that I have to build a tremendous amount of boilerplate to call
> existing Java methods in a JSObject. You can see where this is heading in
> your own example code (
> https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions):
>
> ...
> public Object getMember(String name) {
>         switch (name) {
>            case "length":
>                return buf.capacity();
>            case "buf":
>                // return a 'function' value for this property
>                return new AbstractJSObject() {
>                    @Override
>                    public Object call(Object thiz, Object... args) {
>                        return BufferArray.this.buf;
>                    }
>                    // yes, I'm a function !
>                    @Override
>                    public boolean isFunction() {
>                        return true;
>                    }
>                };
>         }
>         return null;
>      }
> ...
> Imagine this code copied and pasted out to 50-odd methods & fields.
>
> Question 1: have I missed something?
>
> My main use case is actually less general:
>
> public class ClassWithBigAPI
> {
>      .... many methods and fields ...
> }
>
> public class JSMassageLayer extends ClassWithBigAPI implements JSObject
> {
>      ...
>      public void getMember(String n)
>      {
>          // how to lookup and return all methods and fields in super?
>      }
> }
>
> Question 2: is there something better that I can return than a whole new
> AbstractJSObject? I've gotten some distance by returning
> (SomeFunctionalInterface)this::someMethod, but I can't build those
> automatically. In my case all I want is the standard method / field lookup
> that I would have gotten before I implemented JSObject if that would
> succeed. As far as I can tell, not only is this cumbersome to write and
> maintain (even building these AbstractJSObject's based on reflection of the
> class I'm delegating too), but it seems non-performant and loses
> functionality that's hard to restore (for example magic SAM conversion on
> calling). For example, is there a sane (and api-legal) way of building
> SimpleDynamicMethod/OverloadedDynamicMethod instances?
>
> Question 3: is this a real design problem? In other languages / interfaces
> to languages there's a distinction made between a "getMember" that's called
> for all member lookup and a "getMember" that's called when other, standard
> member lookups fail (for example __getattr__ / __getattribute__ in
> python/jython, groovy invokeMethod / methodMissing). Other languages /
> runtimes privilege the second case (Ruby methodMissing, Scala's
> selectDynamic). I've found Jython's functionality here, in particular,
> vital to creating Pythonic interfaces to already-existing Java things, but
> I was hoping to move my whole operation over to Nashorn.
>
> Finally, I've also tried, in JS, new JSAdaptor(new ClassWithBigAPI()){ ...
> }, but that doesn't seem to get me anywhere --- unexpectedly, __get__ is
> still called for things that are in ClassWithBigAPI. Of course, being in JS
> gives me more options, so I'm pursuing that route for now.
>
> many thanks,
>
> Marc



More information about the nashorn-dev mailing list