Can I build a Rhino JavaAdapter in Java, using a ScriptableObject?

这一生的挚爱 提交于 2019-12-11 09:35:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!