javascriptingmozillarhinojsr233

Mozilla Rhino 1_7R4 Extending Abstract Class ( JS )


I'm using Mozilla's implementation of Rhino (not the one bundled with the JDK). Having read this thread: How to subclass an inner (static) class in Rhino? -- I thought that I was on the right track, but the following implementation fails with:

Exception in thread "main" org.mozilla.javascript.EvaluatorException: Access to Java class "adapter1" is prohibited. (test#2)
at org.mozilla.javascript.DefaultErrorReporter.runtimeError(DefaultErrorReporter.java:77)
at org.mozilla.javascript.Context.reportRuntimeError(Context.java:913)
at org.mozilla.javascript.Context.reportRuntimeError(Context.java:969)
at org.mozilla.javascript.Context.reportRuntimeError1(Context.java:932)
at org.mozilla.javascript.JavaMembers.<init>(JavaMembers.java:35)
at org.mozilla.javascript.JavaMembers.lookupClass(JavaMembers.java:807)
at org.mozilla.javascript.NativeJavaObject.initMembers(NativeJavaObject.java:54)
at org.mozilla.javascript.NativeJavaObject.<init>(NativeJavaObject.java:44)
at org.mozilla.javascript.JavaAdapter.createAdapterWrapper(JavaAdapter.java:107)
at adapter1.<init>(<adapter>)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.mozilla.javascript.JavaAdapter.js_createAdapter(JavaAdapter.java:205)
at org.mozilla.javascript.JavaAdapter.execIdCall(JavaAdapter.java:86)
at org.mozilla.javascript.IdFunctionObject.call(IdFunctionObject.java:97)
at org.mozilla.javascript.BaseFunction.construct(BaseFunction.java:343)
at org.mozilla.javascript.ScriptRuntime.newObject(ScriptRuntime.java:2349)
at org.mozilla.javascript.gen.test_1._c_script_0(test:2)
at org.mozilla.javascript.gen.test_1.call(test)
at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091)
at org.mozilla.javascript.gen.test_1.call(test)
at org.mozilla.javascript.gen.test_1.exec(test)

Java:

package com.rebelstudios.scripting;

public abstract class Test
{
    public abstract void x();

public static void main(String[] _) throws Throwable
{
    Context cx = Context.enter();
    ScriptableObject prototype = cx.initStandardObjects();
    Scriptable topLevel = new ImporterTopLevel(cx);
    prototype.setParentScope(topLevel);
    Scriptable scope = cx.newObject(prototype);
    scope.setPrototype(prototype);
    Reader reader = new FileReader("test.js");
    org.mozilla.javascript.Script script = cx.compileReader(reader, "test", 0, null);
    script.exec(cx,  scope);
}

}

JS:

var derived = new JavaAdapter(
    Packages.com.rebelstudios.scripting.Test, 
    {
        x: function() { }
    }
);

It's quite late and I might be missing something obvious, but can anyone offer some tips? Thanks!

P.S. I'd also really appreciate any links to good documentation, examples, and tutorials on using Mozilla Rhino. There doesn't seem to be much coherent information out there from what I've gathered from my searches.


Solution

  • It's not required to use JavaAdaper. You may explicitly declare a class that You are going to instantiate, but this class have to able to be instantiated via reflection since Rhino doesn't make any magic like code weaving or something.

    You may read related articles about sub-classing/extending in Rhino here: example using rhino's JavaAdapter

    You may also consider to wrap your Scriptable object (created during the js-script execution) from and to the Java object in meaner like BSON.from and BSON.to in the following Rhino's adapter from MongoDB: http://code.google.com/p/mongodb-rhino/