Ошибка при попытке доступа к членам класса (используя Rhino) - PullRequest
1 голос
/ 03 мая 2011

Попытка создать ссылку Java / JS с использованием Rhino с двумя очень простыми объектами, один из которых имеет в качестве одного члена экземпляр второго класса.

Запуск приведенного ниже кода приводит к следующей ошибке:

org.mozilla.javascript.EcmaError: TypeError: Невозможно найти значение по умолчанию для объекта.

Кажется, проблема связана с доступом к члену "a" из второго объекта.Я также пытался с геттером, как это:

public Object jsGet_a() {
 return Context.toObject(a, this);
}

, но я получаю ту же ошибку.

new A (). DoSmth ();работает нормально, и выводит "Я делаю что-то" new B (). a.doSmth ();поднимает ошибку

Может кто-нибудь помочь мне с возможным решением для этого?

Спасибо!


public class Test {

    public static class A extends ScriptableObject implements Scriptable {

            public A() {
            };

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

            public void jsFunction_doSmth() {
                    System.out.println("I'm doing something");
            };

    }

    public static class B extends ScriptableObject implements Scriptable {

            private A a = new A();

            public B() {
            };

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

            public void jsConstructor() {
            }

            public A jsGet_a() {
                    return a;
            }

    }

    public static void main(String[] args) {
            try {
                    Context cx = Context.enter();

                    Scriptable scope = cx.initStandardObjects(null, true);
                    ScriptableObject.defineClass(scope, A.class);
                    ScriptableObject.defineClass(scope, B.class);

                    cx.compileString("" +
                                    "new A().doSmth();" +
                                    "new B().a.doSmth();" +
                                    "", "", 1, null).exec(cx, scope);

            } catch (Exception e) {
                    e.printStackTrace();
            }
    }

} 

Ответы [ 3 ]

1 голос
/ 10 августа 2011

Это похоже на работу:

  1. Сделал контекст и глобальную область видимости закрытыми статическими переменными.
  2. Добавлен jsConstructor для класса A
  3. В jsConstructor для класса B создал объект javascript в коде.
  4. Использовал Context.toObject (a, this); с возвращаемым типом Scriptable в jsGet_a ()
  5. Наконец, назначьте cx для введенного контекста, а область действия - для глобальной области видимости.

    public class Test
    {
        private static Context cx;    
        private static ScriptableObject scope;
    
        public static class A extends ScriptableObject implements Scriptable {
    
            public A() {
            }
    
            public void jsConstructor() {
            }
    
            public String getClassName() {
                    return "A";
            }
    
            public void jsFunction_doSmth() {
                    System.out.println("I'm doing something");
            }
    
        }
    
        public static class B extends ScriptableObject implements Scriptable {
    
            private A a = new A();
    
            public B() {
            }
    
            public String getClassName() {
                return "B";
            }
    
            public void jsConstructor() {
            Scriptable scriptable = cx.newObject(scope, "A");
                this.put("a", this, scriptable);
            }
    
            public Scriptable jsGet_a() {
                return Context.toObject(a, this);
            }
    
        }
    
        public static void main(String[] args) {
            try {
                cx = Context.enter();
    
                scope = cx.initStandardObjects(null, true);
                ScriptableObject.defineClass(scope, A.class);
                ScriptableObject.defineClass(scope, B.class);
    
                cx.compileString("" +
                                "new A().doSmth();" +
                                "new B().a.doSmth();" +
                                "", "", 1, null).exec(cx, scope);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
0 голосов
/ 03 мая 2011

В соответствии с API документами, вы можете использовать метод

//  Get a named property from the object.
get(java.lang.String name, Scriptable start) 

в вашем объекте Java. Я полагаю, что вы ошиблись в преобразовании отражения в приведенном выше.

0 голосов
/ 03 мая 2011
new B().a.doSmth();

не будет работать, поскольку a является приватным.

new B().jsGet_a().jsFunction_doSmth();

похоже, что должно работать.

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