No. Nashorn uses wrapperless Java objects. Java objects are exposed to
scripts "as is" - no wrapping as 'script objects' as in Rhino.
It is possible to implement Java interfaces in script (just like it was
in Rhino).
-Sundar
On Tuesday 22 October 2013 09:32 PM, Rick Bullotta wrote:
In Rhino, you register custom adapters in a "wrap factory" that tells the
script engine to use these adapters for accessing instances of those classes/types.
What's the analog in Nashorn? Can custom types implement interfaces that Nashorn will
use?
From: Jim Laskey (Oracle) [mailto:james.las...@oracle.com]
Sent: Tuesday, October 22, 2013 11:52 AM
To: Rick Bullotta
Cc: nashorn-dev@openjdk.java.net
Subject: Re: Docs/examples for JSAdapter
In general the Nashorn docs start here.
https://wiki.openjdk.java.net/display/Nashorn/Nashorn+Documentation, but as you
point out, we seem to be lacking JSAdapter details. I should start an FAQ.
>From the javadoc (cd make; ant javadoc # ./dist/javadoc/index.html)
* public final class NativeJSAdapter
* extends
ScriptObject<file:///\\Volumes\Elephant\Projects\nashorn~jdk8\nashorn\dist\javadoc\jdk\nashorn\internal\runtime\ScriptObject.html>
This class is the implementation of the Nashorn-specific global object named
JSAdapter. It can be thought of as the
Proxy<http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html?is-external=true>
equivalent for JavaScript. NativeJSAdapter calls specially named JavaScript methods
on an adaptee object when property access/update/call/new/delete is attempted on it.
Example:
var y = {
__get__ : function (name) { ... }
__has__ : function (name) { ... }
__put__ : function (name, value) {...}
__call__ : function (name, arg1, arg2) {...}
__new__ : function (arg1, arg2) {...}
__delete__ : function (name) { ... }
__getIds__ : function () { ... }
};
var x = new JSAdapter(y);
x.i; // calls y.__get__
x.foo(); // calls y.__call__
new x(); // calls y.__new__
i in x; // calls y.__has__
x.p = 10; // calls y.__put__
delete x.p; // calls y.__delete__
for (i in x) { print(i); } // calls y.__getIds__
JavaScript caller of adapter object is isolated from the fact that the property
access/mutation/deletion are really calls to JavaScript methods on adaptee.
JSAdapter constructor can optionally receive an "overrides" object. Properties of
overrides object is copied to JSAdapter instance. When user accessed property is one of these, then
adaptee's methods like __get__, __put__ etc. are not called for those. This can be used to make
certain "preferred" properties that can be accessed in the usual/faster way avoiding
proxy mechanism. Example:
var x = new JSAdapter({ foo: 444, bar: 6546 }) {
__get__: function(name) { return name; }
};
x.foo; // 444 directly retrieved without __get__ call
x.bar = 'hello'; // "bar" directly set without __put__ call
x.prop // calls __get__("prop") as 'prop' is not overridden
It is possible to pass a specific prototype for JSAdapter instance by passing
three arguments to JSAdapter constructor. So exact signature of JSAdapter
constructor is as follows:
JSAdapter([proto], [overrides], adaptee);
Both proto and overrides are optional - but adaptee is not. When proto is not
passed JSAdapter.prototype is used.
*
As well as the test ./test/script/basic/jsadapter.js
var obj = new JSAdapter() {
__get__: function(name) {
print("getter called for '" + name + "'"); return name;
},
__put__: function(name, value) {
print("setter called for '" + name + "' with " + value);
},
__call__: function(name, arg1, arg2) {
print("method '" + name + "' called with " + arg1 + ", " + arg2);
},
__new__: function(arg1, arg2) {
print("new with " + arg1 + ", " + arg2);
},
__getIds__: function() {
print("__getIds__ called");
return [ "foo", "bar" ];
},
__getValues__: function() {
print("__getValues__ called");
return [ "fooval", "barval" ];
},
__has__: function(name) {
print("__has__ called with '" + name + "'");
return name == "js";
},
__delete__: function(name) {
print("__delete__ called with '" + name + "'");
return true;
}
};
// calls __get__
print(obj.foo);
// calls __put__
obj.foo = 33;
// calls __call__
obj.func("hello", "world");
// calls __new__
new obj("hey!", "it works!");
for (i in obj) {
print(i);
}
for each (i in obj) {
print(i);
}
var x = "foo" in obj;
print(x);
var y = "js" in obj;
print(y);
print(delete obj.prop);
print(obj["js"]);
obj["js"] = "javascript";
print(obj["javascript"]);
Hope that helps. Is there a specific question?
Cheers,
-- Jim
On 2013-10-22, at 11:50 AM, Rick Bullotta
<rick.bullo...@thingworx.com<mailto:rick.bullo...@thingworx.com>> wrote:
Hi, all.
I've been searching everywhere for any form of documentation or substantive
examples as to how JSAdapter works in Nashorn, as it is an essential piece of
the puzzle for many of us who will naturally be migrating from Rhino.
Can anyone provide and additional info?
Thanks,
Rick
ThingWorx