问题
I've found a few questions about shuffling class definitions between Javascript and Java using Mozilla's Rhino. I've gotten far enough that this works:
Javascript:
new JavaAdapter(MyClass, {foo: function(){return 'Hello!';}});
Java
String script = // the above stuff
Object o = context.evaluateString(scope, script, "UserScript", 1, null);
MyClass mc = (MyClass) Context.jsToJava(o, MyClass.class);
mc.foo(); // returns "Hello!"
That blew me away, but I'd like to move the JavaAdapter construction from the Javascript to the Java side. I'm writing a framework where users will define logic in Javascript, and the less boilerplate they have to paste in the happier they'll be.
Ideally, I could do this:
Javascript:
{foo: function(){return 'Hello!';}};
Java
String script = // the above stuff
Object o = context.evaluateString(scope, script, "UserScript", 1, null);
MyClass mc = new JavaAdapter(MyClass.class, o);
mc.foo(); // returns "Hello!"
but as far as I can tell the JavaAdapter constructor doesn't take any parameters, there's no documentation for the class anywhere (for example, it's not here), and I haven't found any static methods (e.g. on Context
or ScriptableObject
) that create such a class. I also tried Context.jsToJava(o, MyClass.class)
, but that threw an exception.
回答1:
I've been beating my head on this one also. I finally got this to work:
Change your JavaScript to:
var xyz = {foo: function() {return 'Hello!';}};
Now replace your single line of code creating the JavaAdapter with this:
String stub = "new JavaAdapter(Packages.MyClass, xyz);";
Object o = context.evaluateString(scope, stub, "stub", 1, null);
MyClass mc = (MyClass) Context.jsToJava(o, MyClass.class);
I'm not an expert in this but it does seem that you can't use JavaAdapter directly from Java code (unfortunate), but we can run a piece of stub code to invoke it from JavaScript.
Beware of typo's in my example, I'm translating it from my working code.
Calling into the MyClass mc instance seems to work correctly. Calling from JavaScript (i.e. calling Java from foo) to access MyClass's super methods and fields seems to always require the 'this' keyword. I'm still trying to figure that out. Methods and fields in MyClass also have to be public instead of protected (also unfortunate).
来源:https://stackoverflow.com/questions/11672500/can-i-build-a-rhino-javaadapter-in-java-using-a-scriptableobject