Как создать объект ScriptableObject в java-скриптах .....? - PullRequest
1 голос
/ 27 сентября 2011

, когда я пытаюсь создать объект класса в файле java-скрипта, который расширяется ScriptableObject ... Возникнет следующая ошибка.

js: uncaught JavaScript runtime exception: TypeError: Cannot find default value for object.”

файл классаis

package sumit2;
import org.mozilla.javascript.ScriptableObject;
public class Sumit extends ScriptableObject {
public String getClassName(){
    return "Sumit";
}   
public void foo() {
    System.out.println("Sumit!!!!!!!");
}
}

Файл Java-Script: -

importPackage(Packages.sumit2);
var vv=new Sumit();
print(vv.foo());

Ответы [ 3 ]

9 голосов
/ 30 сентября 2011

Во-первых, вы должны переопределить getDefaultValue в Sumit. Это необходимо для преобразования объекта в строку из JavaScript.

package sumit2;

import org.mozilla.javascript.ScriptableObject;
public class Sumit extends ScriptableObject {
    public String getClassName(){
        return "Sumit";
    }   
    public void foo() {
        System.out.println("Sumit!!!!!!!");
    }
    @Override
    public Object getDefaultValue(Class<?> typeHint) {
        return toString();
    }

}

И тогда вы получите следующее сообщение об ошибке:

js: uncaught JavaScript runtime exception: TypeError: Cannot find function foo in object sumit2.Sumit@1bf6770.

** ПРИМЕЧАНИЕ. Исключение «Не удается найти значение по умолчанию для объекта». Было вызвано при отображении исключения выше. Строковое значение «sumit2.Sumit@1bf6770» создается путем вызова getDefaultValue

Во-вторых, javascript не может вызывать java-методы объектов, расширенных из ScriptableObject. Если вы хотите вызвать foo из javascript, переопределите get (String, Scriptable) следующим образом:

package sumit2;

import jp.tonyu.js.BuiltinFunc;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
public class Sumit extends ScriptableObject {
    public String getClassName(){
        return "Sumit";
    }   
    public void foo() {
        System.out.println("Sumit!!!!!!!");
    }
    @Override
    public Object getDefaultValue(Class<?> typeHint) {
        return toString();
    }

    @Override
    public Object get(String name, Scriptable start) {
        if ("foo".equals(name)) {
            return new Function() {

                @Override
                public Object call(Context cx, Scriptable scope, Scriptable thisObj,
                        Object[] args) {
                    foo();
                    return "Return value of foo";
                }
                /** ...Implement all methods of Function other than call **/

            };
        }
        return super.get(name, start);
    }


}

И вы получите:

Sumit!!!!!!!
Return value of foo

Я думаю, что часть

/** ...Implement all methods of Function other than call **/

раздражает. Я рекомендую создать класс адаптера, который реализует функцию и переопределяет все методы функции с помощью пустых операторов.

0 голосов
/ 09 мая 2013

Я пытался использовать концепцию кода, опубликованную @ hoge1e3, но, к сожалению, у меня не получилось с последней сборкой Rhino (1_7R5pre). Однако я смог создать класс Java с методами, которые можно было вызывать в JavaScript, используя аннотации, предоставляемые средой Rhino. В конце концов, все было очень просто и понятно.

В качестве ссылки, пожалуйста, смотрите примеры, включенные в источник Rhino, предоставленный Mozilla: https://github.com/mozilla/rhino/tree/master/examples

Пример определения класса:

//this gives you access to the annotations needed to expose your Java methods and properties to JavaScript
import org.mozilla.javascript.annotations.JSFunction; 

public class Sumit extends ScriptableObject {

    public String getClassName(){
        return "Sumit";
    }   

    @JSFunction
    public void foo() {
        //add in the above annotation and your Java method 'foo' will now be available in JavaScript
        System.out.println("Sumit!!!!!!!");
    }
}

Пример преобразования указанного выше класса из Java в JavaScript:

//Make sure to define your Context and Scope beforehand
ScriptableObject.defineClass(scope, Sumit.class);
0 голосов
/ 28 сентября 2011

В коде есть логическая ошибка: вы пытаетесь напечатать значение void: возвращаемое значение vv.foo().

Если вы измените код с print(vv.foo()) на: vv.foo(), или, в качестве альтернативы, измените Java, чтобы вернуть String "Sumit!!!!!!!" и напечатайте это, я думаю, что у вас будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...