下面是另一个不需要修改nashorn jar的解决方案:
-
捆
nashorn.jar
-
使用子第一个/父最后一个类装入器,例如
this one
-
通过该类加载器加载发动机
实现上述方法的示例servlet,然后尝试使用JRE的Nashorn和捆绑的Nashorn评估脚本:
@WebServlet("/nashorn")
public class NashornDemoServlet extends HttpServlet {
private static final ClassLoader CL;
static {
// In my case nashorn.jar is under WEB-INF/classes (resources root)
URL nashornURL = NashornDemoServlet.class.getClassLoader().getResource("nashorn.jar");
CL = new ParentLastURLClassLoader(Collections.singletonList(nashornURL));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String script = "var c = JSON.parse(\"{\\\"123\\\": \\\"a\\\", \\\"456\\\": \\\"b\\\"}\"); c[\"123\"]";
ScriptEngine nashorn = new ScriptEngineManager(getClass().getClassLoader()).getEngineByName("nashorn");
try {
Object result = nashorn.eval(script);
out.println("### JRE Nashorn result: " + result);
} catch (Exception e) {
out.println("### JRE Nashorn failed!");
e.printStackTrace(out);
}
try {
Class<?> clazz = CL.loadClass("jdk.nashorn.api.scripting.NashornScriptEngineFactory");
Object factory = clazz.newInstance();
ScriptEngine engine = (ScriptEngine) clazz.getMethod("getScriptEngine").invoke(factory);
Object result = engine.eval(script);
out.println("\n### Bundled Nashorn result: " + result);
} catch (Exception e) {
out.println("### Bundled Nashorn failed!");
e.printStackTrace(out);
}
}
}
### JRE Nashorn failed!
java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 7
at java.util.Arrays.rangeCheck(Arrays.java:120)
at java.util.Arrays.fill(Arrays.java:2868)
at jdk.nashorn.internal.runtime.BitVector.setRange(BitVector.java:273)
...
at java.lang.Thread.run(Thread.java:745)
### Bundled Nashorn result: a
Web应用项目树:
在此之前,我也尝试过简单的捆绑
纳肖恩。罐子
WEB-INF/lib
作为Java EE产品一部分的Servlet容器不应允许应用程序重写Java SE或Java EE平台类,例如
java.*
javax.*
名称空间,Java SE或Java EE都不允许修改。
"
“,似乎如此
jdk.*
也属于这一类(无论如何,Tomcat似乎不包括Nashorn)。是的,带上你自己的类加载器
不
包括您自己,但提供将文件添加到您分发的war中的说明(它只是一个zip文件),等等。