How can I add methods from a Java class as global functions in Javascript using Rhino?

java, javascript, rhino

Solution

I'm not real familiar with Rhino, but something like this should work:

for(var fn in utils) {
  if(typeof utils[fn] === 'function') {
    this[fn] = (function() {
      var method = utils[fn];
      return function() {
         return method.apply(utils,arguments);
      };
    })();
  }
}

Just loop over the properties of `utils`,and for each one that is a function, create a global function that calls it.

EDIT: I got this working in a Groovy script, but I had to set utils in the bindings, not on the engine like in your code:

import javax.script.*

class Utils {
   void foo(String bar) {
      println bar
   }   
}

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");

engine.eval("""
for(var fn in utils) {
  if(typeof utils[fn] === 'function') {
    this[fn] = (function() {
      var method = utils[fn];
      return function() {
         return method.apply(utils,arguments);
      };
    })();
  }
}

foo('foo'); // prints foo, sure enough
""",new SimpleBindings("utils":new Utils()))

Problem

I have a simple Java class that has some methods: ``` public class Utils { public void deal(String price, int amount) { // .... } public void bid(String price, int amount) { // .... } public void offer(String price, int amount) { // .... } } ``` I would like to create an instance of this class and allow the Javascript code to call the methods directly, like so: ``` deal("1.3736", 100000); bid("1.3735", 500000); ``` The only way I could figure out for now was to use ``` ScriptEngine engine = new ScriptEngineManager().getEngineByName("js"); engine.put("utils", new Utils()); ``` and then use `utils.deal(...)` in the Javascript code. I can also write wrapper functions in Javascript for each method, but there should be a simpler way to do this automatically for all the public methods of a class.

Original source

Related problems