1

我的项目在 Java 6 上完美运行(不同的更新和操作系统)。它使用 Rhino 作为脚本引擎。现在我们需要迁移到 Java 7,我发现了一个阻碍我们迁移的问题。我们有这样的代码:

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

它在 Java 6 中运行良好,但 Java 7 抛出异常

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

如果我将匿名对象提取到内部类,问题就会消失。知道如何在没有的情况下修复它ScriptableObject.get(我们创建此类对象的地方太多,我们使用的一些第三方代码使用相同的方法)?

4

4 回答 4

1

我遇到了完全相同的错误,在您发表评论“如果我将匿名对象提取到内部类,问题就会消失”之后。我发现生成的内部类将具有默认的访问修饰符(有时称为“包”访问修饰符)。显然,JDK7 中的脚本 API 不处理这些定义!

我改为使用“静态公共”定义。

于 2014-01-29T15:37:10.020 回答
0

从 Java 6 迁移到 7 时,我也遇到了 TypeError:我的 JavaScript 正在调用具有默认(包私有)可见性的 Java 类的方法。必须公开课程才能使其正常工作。

于 2014-04-02T09:46:57.397 回答
0

有类似的问题。我正在通过一个私人内部课程,但它失败了。我将它从私有内部对象更改为公共类,并且在 Java 7 升级后它工作得很好。

于 2014-02-13T21:43:23.573 回答
0

有同样的问题。就我而言,它不是内部类,但顶级类具有默认(包级别)保护。切换到public解决我的问题......可惜我花了几个小时才弄清楚。

于 2015-04-09T06:58:33.290 回答