我的项目在 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
(我们创建此类对象的地方太多,我们使用的一些第三方代码使用相同的方法)?