来自 Nashorn 的 IllegalArgumentException 异常 - 它是 Java 8 中的一个错误吗?
我正在使用Nashorn javascript引擎来评估Java应用程序中编写的所有服务器端javascript代码。为了提高性能,我在启动时使用spring来初始化JsEngine,并评估和缓存所有核心工具,如Mustache和一些常见的JS工具。然后,每次当屏幕呈现时,这个预先评估的JsEngine将用于评估页面特定的JavaScript代码。它在一段时间内工作正常,这意味着它按预期呈现页面,但是当我不断点击相同的URL时,它会开始抛出以下异常
我无法找到问题的根本原因。
@Component
public class JsEngine {
private ScriptEngine scriptEngine;
@PostConstruct
public void init() throws ScriptException, IOException{
scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
this.cacheAllCoreEngines();
for(String key: defaultEngineSource.keySet()){
scriptEngine.eval(defaultEngineSource.get(key));
}
}
private void cacheAllCoreEngines()throws IOException{
//read all core files such as mustache, etc.
defaultEngineSource.put("mustache", FileUtil.readFileFromDisk("<actual path..>/mustache.js"));
}
public Object eval(String source) throws ScriptException{
.... code to handle exceptions
return scriptEngine.eval (source);
}
}
JsEngine使用如下,
public class AppRendererImpl implements AppRenderer {
@Autowired
JsEngine jsEngine;
public String render(){
....
.... //Read source from disk or cache
jsEngine.eval(source);....
}
}
几个渲染周期后的异常,
异常:
java.lang.IllegalArgumentException: target and filter types not match: (ScriptObject)Object, (Object)Object
at java.lang.invoke.MethodHandleStatics.newIllegalArgumentException(MethodHandleStatics.java:115)
at java.lang.invoke.MethodHandles.filterArgument(MethodHandles.java:2416)
at java.lang.invoke.MethodHandles.filterArguments(MethodHandles.java:2403)
at jdk.nashorn.internal.lookup.MethodHandleFactory$StandardMethodHandleFunctionality.filterArguments(MethodHandleFactory.java:277)
at jdk.nashorn.internal.runtime.WithObject.filter(WithObject.java:270)
at jdk.nashorn.internal.runtime.WithObject.fixExpressionCallSite(WithObject.java:249)
at jdk.nashorn.internal.runtime.WithObject.lookup(WithObject.java:169)
atjdk.nashorn.internal.runtime.linker.NashornLinker.getGuardedInvocation(NashornLinker.java:96)
at jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker.getGuardedInvocation(CompositeTypeBasedGuardingDynamicLinker.java:176)
at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124)
at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:144)
at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:232)
at jdk.nashorn.internal.scripts.Script$\^eval_._L6$_L8(:21)
at jdk.nashorn.internal.scripts.Script$\^eval_._L6$_L40(:41)
at jdk.nashorn.internal.scripts.Script$\^eval_.runScript(:1)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:498)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:206)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:378)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:546)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:528)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:524)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:194)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at com.nube.portal.engines.js.JsEngine.eval(JsEngine.java:111)
at com.nube.portal.engines.html.tags.HtmlTagScript.eval(HtmlTagScript.java:66)
........
我添加了一些自定义代码,将所有全局对象复制到另一个映射。这是为了方便我必须以“nube”的形式访问所有全局对象的其他要求。我不知道此代码是否会为频繁运行带来任何问题。请记住,我不会从上下文中删除任何对象。
public void movePublicObjects(String prefix) throws NubeException{
Bindings b1 = scriptEngine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
Map<String, Object> nubeObjects = new HashMap<String, Object>();
for(Entry<String, Object> entry: b1.entrySet()){
if(!entry.getKey().equals("nube")){
nubeObjects.put(entry.getKey(), entry.getValue());
}
}
b1.put("nube", nubeObjects);
return;
}
当我将JsEngine定义为原型时,这段代码可以完美地工作,但性能并不好。你认为这是纳斯霍恩的一个错误吗?