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