JSObject and delegation to other java classes [further adventures in building JS interfaces to Java]
Marc Downie
marc at openendedgroup.com
Mon Jul 21 17:05:44 UTC 2014
So the solution posed here:
> http://hg.openjdk.java.net/jdk9/dev/nashorn/file/
>> 34a783929a67/samples/jsobj_example.js
>
>
suffers from one flaw (for my case and taste): the factory produces objects
that delegate to a Java instance but are not actual subclasses, and thus
cannot be passed to Java methods that expect those classes. This was the
reason JSObject as an interface looked so appetizing.
So here's a hybrid that works:
public class BigBaseClass
{
// many methods, all written by some 3rd party
}
public class MyJSShim extends BigBaseClass implements JSObject
{
// much lovely JSObject customization
// a getMember and setMember that makes this feel like a map, and a call
that does interesting things
}
-- and in JavaScript --
function makeBigBaseClass()
{
var Shim = Java.extend(Java.type('somepackage.MyJSShim'))
var shim = new Shim()
{
getMember: function(name)
{
var q = shim_super["getMember"](name)
if (q) return q;
if (typeof shim_super[name] == 'function') {
return function() {
var a = arguments;
switch (a.length) {
case 0: return shim_super[name]();
case 1: return shim_super[name](a[0]);
case 2: return shim_super[name](a[0], a[1]);
// ... etc ...
}
}
}
}
}
var shim_super = Java.super(shim)
return shim
}
---
I should also note that Java.extend(Java.type('somepackage.BigBaseClass'),
Java.type('jdk.nashorn.api.scripting.JSObject')) also appears to work if
you don't need any Java-side JSObject glue. This handy multi-arg version of
Java.extend seems a little buried in docs.
But this gets me the best of all three worlds: makeBigBaseClass returns an
actual subclass of BigBaseClass, I can customize JS access to my inviolate,
3rd-party BigBaseClass to my heart's content in MyJSShim, but I can skip
over the difficult/impossible to write parts of getMember in the Java
implementation and write them in JS instead (still yielding method calls
that have automatic SAM conversion and the like).
Many thanks,
(I'm still surprised I can't simply return shim_super[name] when it's typeof
'function', or use what's returned from Java.super(this)inside getMember,
to eliminate the var shim_super altogether, but I'm getting over it. Also:
a pony).
Marc.
More information about the nashorn-dev
mailing list