TypeError in Rhino: migration from Java 6 to Java 7

余生颓废 提交于 2019-12-24 13:26:18

问题


My project perfectly works on Java 6 (different updates and OS). It uses Rhino as script engine. Now we need to migrate to Java 7 and I found one issue that prevent us to do it. We have code like this:

Context.enter();
try {
    ScriptEngine js = new ScriptEngineManager().getEngineByName("js");
    final ScriptContext context = new SimpleScriptContext();
    context.setAttribute("console", new Object() {
        public void log(String out) {
            logger.info(out);
        }
    }, ScriptContext.ENGINE_SCOPE);
    js.setContext(context);
    js.eval("console.log('test')");
} catch (ScriptException e) {
    logger.error(e);
    e.printStackTrace();
} finally {
    Context.exit();
}

It works good in Java 6 but Java 7 throws exception

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: TypeError: Cannot find function log in object JSDebugTest$1@4631f1f8. (<Unknown source>#1) in <Unknown source> at line number 1
at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:224)
at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:240)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at JSDebugTest.testJS1(JSDebugTest.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at  com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: sun.org.mozilla.javascript.internal.EcmaError: TypeError: Cannot find function log in object JSDebugTest$1@4631f1f8. (<Unknown source>#1)
at sun.org.mozilla.javascript.internal.ScriptRuntime.constructError(ScriptRuntime.java:3771)
at sun.org.mozilla.javascript.internal.ScriptRuntime.constructError(ScriptRuntime.java:3749)
at sun.org.mozilla.javascript.internal.ScriptRuntime.typeError(ScriptRuntime.java:3777)
at sun.org.mozilla.javascript.internal.ScriptRuntime.typeError2(ScriptRuntime.java:3796)
at sun.org.mozilla.javascript.internal.ScriptRuntime.notFunctionError(ScriptRuntime.java:3867)
at sun.org.mozilla.javascript.internal.ScriptRuntime.getPropFunctionAndThisHelper(ScriptRuntime.java:2343)
at sun.org.mozilla.javascript.internal.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2310)
at sun.org.mozilla.javascript.internal.gen._Unknown_source__2._c_script_0(<Unknown source>:1)
at sun.org.mozilla.javascript.internal.gen._Unknown_source__2.call(<Unknown source>)
at sun.org.mozilla.javascript.internal.ContextFactory.doTopCall(ContextFactory.java:433)
at sun.org.mozilla.javascript.internal.ScriptRuntime.doTopCall(ScriptRuntime.java:3161)
at sun.org.mozilla.javascript.internal.gen._Unknown_source__2.call(<Unknown source>)
at sun.org.mozilla.javascript.internal.gen._Unknown_source__2.exec(<Unknown source>)
at sun.org.mozilla.javascript.internal.Context.evaluateReader(Context.java:1159)
at com.sun.script.javascript.RhinoScriptEngine.eval(RhinoScriptEngine.java:214)
... 30 more

Problem disappear if I extract anonymous Object to inner class. Any idea how to fix it without ScriptableObject.get (there are too many places where we create such object and some third party code we use, uses same approach)?


回答1:


I had exactly the same error, and after your comment "Problem disappear if I extract anonymous Object to inner class." I found that generated inner class will have default access modifier (sometimes called 'package' access modifier). Apparently, scripting API in JDK7 doesn't handle these definitions!

I use put a "static public" definition instead.




回答2:


Had a similar problem. I was passing in a private inner class and it was failing. I changed it from a private inner object to a public class and it worked just fine after the Java 7 upgrade.




回答3:


I also got TypeError when migrating from Java 6 to 7: my JavaScript was calling a method on a Java class which had default (package-private) visibility. Had to make the class public for it to work.




回答4:


Had the same problem. In my case it was not an inner class, but the top level class had a default (package level) protection. Switching to public fixed my issues ... shame it took me a couple hours to figure it out.



来源:https://stackoverflow.com/questions/18634585/typeerror-in-rhino-migration-from-java-6-to-java-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!