Search code examples
javajavascriptembedrhino

Embedded Rhino and anonymous js object


I'm embedding a Rhino script engine into a Java application. I tried to wrap the Rhino Function interface in order to stay independant from the ScriptEngine in my program.

As stated in the sample below, in case of an explicit declaration, the sent object is correctly wrapped, but in case of an anonymous object, a com.sun.proxy.$Proxy is sent.

// 1 - Explicit declaration of the callback
// Recognise the type of 'event'
// The object passed to setCallback is a custom Function wrapper.
var obj = function(event) {
  print(event.value());
};
javaObj.setCallback(obj);

// 2 - Anonymous callback declaration
// Convert 'event' to a dummy Object (=> event.value() not found)
// The object passed to setCallback is of class com.sun.proxy.$Proxy.
javaObj.setCallback(function(event) {
  print(event.value());
});

The callback method is defined as follow:

public class JavaObj {
  public void setCallback(final ScriptFunction callback) {
    callback.call(event);
  }
}

public interface ScriptFunction {
  Object call(Object... args);
}

Currently, the wrapping of Function is done in a custom scope based on the implementation of sun: ExternalScriptable - but there may be better ways?

My problem is that I cannot found where the transformation from javascript to Java is done in case of an anonymous object declaration.


Solution

  • For those who may come over here looking for an answer:

    The Proxy is a feature of Rhino which tries to identify an interface from a given json object. for example:

    // Java
    public interface ScriptFunction {
      Object method(Object arg1);
    }
    
    public class JavaObj {
      public void setCallback(final ScriptFunction callback) {
        callback.method("this will work");
      }
    }
    
    // JavaScript
    javaObj.setCallback({
      'method': function(oneArg){...} 
    });
    

    And it seems that this feature is only used when declaring the variable inside the method call.