Search code examples
javajavascriptrhino

Rhino Javascript: How to convert Object to a Javascript primitive?


I am utilizing the javax.scripting with Rhino in this project.

I have a Java method that returns a Java Object (Double, Long, Integer, etc). I want to call that method from javascript and reference the result as a Javascript primitive type. However, javacript recognizes the return type as an Object.

How do I force it to convert to a javascript primitive?

This question is very similar to http://groups.google.com/group/mozilla.dev.tech.js-engine.rhino/browse_thread/thread/2f3d43bb49d5288a/dde79e1aa72e1301

The problem with that is how do I get a reference to the context and the WrapFactory?

Sample Code:

public class data 
{ 
   Double value = 1.0d; 
   public Number get()  {  return value; } 
} 


  public static void main(String[] args) 
    { 
            ScriptEngine engine = new ScriptEngineManager().getEngineByName ("rhino"); 
            data data = new data(); 
            try 
            { 
                    engine.eval("function test(data) { return data.getD('value1') + 5;};"); 
                    System.out.println("Result:" + ((Invocable)engine).invokeFunction("test", data)); 
            } 
            catch (Exception e) 
            { 
                    e.printStackTrace(); 
            } 
    } 

Output: Result: 15


Solution

  • Try the following

     public static void main(String [] args) throws Exception {
            ScriptEngine engine = new ScriptEngineManager().getEngineByName ("rhino"); 
            data data = new data();
            Context.enter().getWrapFactory().setJavaPrimitiveWrap(false);
    
            try 
            { 
                    engine.eval("function test(data) { return data.get('value1') + 5;};"); 
                    System.out.println("Result:" + ((Invocable)engine).invokeFunction("test", data)); 
            } 
            catch (Exception e) 
            { 
                    e.printStackTrace(); 
            } 
        }
    
        public static class data 
        { 
           Double value = 1.0d; 
           public Number get(String arg)  {  return value; } 
        } 
    

    Alternatively, you could modify the javascript function to explicitly cast the value to a number:

    function test(data) { return parseInt(data.get('value1'), 10) + 5;}