Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a javascript resource and apply Rhino Script Engine to call a method from java side.

 (function( global ){

    var Result;

    (Result = function( val ) {
        this.tpl = val || '' ;
    }).prototype = {

        get: function ()
        {
            return this.tpl ;
        }

    };
} ( window ) ) ;

This is the way how i did it on java side, how can i call get method in above script ?

    @Test
    public void testCallJSMethod() throws Exception {
        String jsResource = getJSResource();

        jsEngine.put("window", "window");
        jsEngine.put("window.Result", "Result");

        jsEngine.eval(jsResource);

        Invocable inv = (Invocable) jsEngine;

        Object obj = jsEngine.get("window.Result");
        assertEquals(true, obj != null);

        //try to call get method in above script, but it doesn't work
        inv.invokeMethod(obj, "get", new Object[] {} );
    }
share|improve this question
    
What type is jsEngine? –  bkent314 Oct 22 '13 at 12:58
    
It's Rhino engine link –  Tien Nguyen Oct 23 '13 at 6:33
add comment

2 Answers

A possible workaround for this is to store the result in a script variable and read that var with jsEngine.get("myResult");

share|improve this answer
add comment

I see several issues with your code:

    jsEngine.put("window", "window");

This does not define window as a JavaScript object. You can do that as follows:

    jsEngine.eval("window={}");

In your javascript, Result is a local variable, and it will not survive the call to the outer function. You should instead assign your function to global.Result:

(function(global) {
    (global.Result = function(val) {
        this.tpl = val || '';
    }).prototype = {
        get: function()
        {
            return this.tpl;
        }

    };
})(window);

jsEngine.get(name) gets the value of a variable. If you want the value of window.Result, you must do jsEngine.eval("window.Result"), not jsEngine.get("window.Result").

But window.Result actually is a function. A constructor function actually. So to create an instance, you must do something like: jsEngine.eval("new window.Result('Hello world!!!')").

Your java function would thus become:

@Test
public void testCallJSMethod() throws Exception {
    String jsResource = getJSResource();

    jsEngine.eval("window={}");

    jsEngine.eval(jsResource);

    Invocable inv = (Invocable) jsEngine;

    Object obj = jsEngine.eval("new window.Result('Hello World!!!')");
    assertEquals(true, obj != null);

    Object res = inv.invokeMethod(obj, "get", new Object[] {} );
    assertEquals(res, "Hello World!!!");
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.