尝试访问类成员时出错(使用Rhino)

发布于 2024-11-04 20:05:38 字数 1862 浏览 1 评论 0原文

尝试使用 Rhino 与两个非常简单的对象创建 Java/JS 链接,其中一个对象具有第二个类的实例作为一个成员。

运行下面的代码会出现以下错误:

org.mozilla.javascript.EcmaError: TypeError: Cannot find default value 对于对象。

问题似乎是从第二个对象中访问成员“a”。我也尝试过这样的吸气剂:

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

但我得到了同样的错误。

new A().doSmth();工作正常,并输出“我正在做某事” 新 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();
            }
    }

} 

Trying to create a Java/JS link using Rhino with two very simple objects, one having as one member an instance of the second class.

Running the code below gives the following error:

org.mozilla.javascript.EcmaError: TypeError: Cannot find default value
for object.

The problem seems to be accessing the member "a" from within second object. I've also tried with a getter like this:

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

but i get the same error.

new A().doSmth(); is working fine, and outputs "I'm doing something"
new B().a.doSmth(); raises the error

Can anyone help me with a possible solution for this?

Thank you!


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();
            }
    }

} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半步萧音过轻尘 2024-11-11 20:05:38

这似乎有效:

  1. 将上下文和全局范围设为私有静态变量。
  2. 为A类添加了jsConstructor
  3. 在B类的jsConstructor中,在代码中创建了一个javascript对象。
  4. 使用 Context.toObject(a, this); jsGet_a() 中返回类型为 Scriptable
  5. 最后,将 cx 分配给输入的 Context,并将范围分配给全局范围。

    公共类测试
    {
        私有静态上下文cx;    
        私有静态 ScriptableObject 范围;
    
        公共静态类 A 扩展 ScriptableObject 实现 Scriptable {
    
            公共 A() {
            }
    
            公共无效jsConstructor(){
            }
    
            公共字符串 getClassName() {
                    返回“A”;
            }
    
            公共无效jsFunction_doSmth(){
                    System.out.println("我正在做某事");
            }
    
        }
    
        公共静态类 B 扩展 ScriptableObject 实现 Scriptable {
    
            私有 A a = new A();
    
            公共 B() {
            }
    
            公共字符串 getClassName() {
                返回“B”;
            }
    
            公共无效jsConstructor(){
            可编写脚本 = cx.newObject(scope, "A");
                this.put("a", this, 可编写脚本);
            }
    
            公共可编写脚本的 jsGet_a() {
                返回 Context.toObject(a, this);
            }
    
        }
    
        公共静态无效主(字符串[] args){
            尝试 {
                cx = Context.enter();
    
                范围 = cx.initStandardObjects(null, true);
                ScriptableObject.defineClass(范围, A.class);
                ScriptableObject.defineClass(范围,B.class);
    
                cx.compileString("" +
                                “新A().doSmth();” +
                                “新 B().a.doSmth();” +
                                "", "", 1, null).exec(cx, 范围);
    
            } catch (异常 e) {
                e.printStackTrace();
            }
        }
    }
    

This seems to work:

  1. Made the context and the global scope private static variables.
  2. Added jsConstructor for the A class
  3. In the jsConstructor for the B class, created a javascript object in code.
  4. Used the Context.toObject(a, this); with return type of Scriptable in jsGet_a()
  5. Finally, assigned the cx to the Context that was entered and scope to the global scope.

    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();
            }
        }
    }
    
森罗 2024-11-11 20:05:38
new B().a.doSmth();

将无法工作,因为 a 是私有的。

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

似乎应该有效。

new B().a.doSmth();

will not work as a is private.

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

seems like it should work.

泪意 2024-11-11 20:05:38

根据

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

“ rel="nofollow">API 文档,您可以在 java 对象中 。我的猜测是你在上面的反射转换是错误的。

According to the API docs, you could use the method

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

in your java object. My guess is that you got the reflection conversion wrong in the above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文