当前位置: 首页 > 工具软件 > Nashorn > 使用案例 >

Nashorn指南

笪俊迈
2023-12-01

Nashorn介绍:

是由Oracle用Java编程语言开发的JavaScript引擎。它基于Da Vinci Machine(JSR 292),并随Java 8一起发布。它的前身是 基于Mozilla Foundation发布的Rhino开源修改的发布在jdk6上的Rhino。通过它可以轻松的访问java的资源。

相关资料:

Nashorn(wiki)
Rhino(wiki)

如何使用:

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager..getEngineByName("nashorn");
ScriptContext scriptContext = engine.getContext();
Bindings bindings = engine.createBindings();
scriptContext.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
Map<String, Object> contextMap = new HashMap<>(1);
contextMap.put("data", data);
bindings.put("Context", contextMap);
Object result = engine.eval("java.lang.Runtime.getRuntime().exec('calc');1", getScriptContext(engine, originData));
System.out.println(result);

ScriptEngine 的高级使用:
Java 脚本语言
介绍 Nashorn —— Java 8 JavaScript 引擎

安全问题:

nashorn实现可以允许脚本直接调用java库函数。如果需要屏蔽特定的类需要使用如下:

NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(scriptClassFilter);
ScriptContext scriptContext = engine.getContext();
Bindings bindings = engine.createBindings();
scriptContext.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
Map<String, Object> contextMap = new HashMap<>(1);
contextMap.put("data", data);
bindings.put("Context", contextMap);
Object result = engine.eval("java.lang.Runtime.getRuntime().exec('calc');1", getScriptContext(engine, originData));
System.out.println(result);
public class ScriptClassFilter implements ClassFilter {


    private final List<String> securityClasses = Arrays.asList("java.lang.String", "java.lang.StringBuffer", "java.lang.StringBuilder", "java.lang.Long", "java.lang.Double");

    private final List<String> securityPackages = Arrays.asList("java.util","java.time","java.math");

    private final List<String> dangerousClasses = Arrays.asList("java.io.File", "java.io.RandomAccessFile", "java.io.FileInputStream", "java.io.FileOutputStream",
            "java.lang.Class", "java.lang.ClassLoader", "java.lang.Runtime", "java.lang.System",
            "java.lang.Thread", "java.lang.ThreadGroup", "java.lang.ProcessBuilder");

    private final List<String> dangerousPackages = Arrays.asList("java.io","java.net","java.security", "java.text.spi", "java.util.zip", "java.util.logging", "java.util.spi", "java.util.jar", "java.lang.reflect");

    @Override
    public boolean exposeToScripts(String s) {
        if(securityClasses.stream().anyMatch((s1) -> StringUtils.equals(s, s1)) ){
            return true;
        }
        if(dangerousClasses.stream().anyMatch((s1) -> StringUtils.equals(s, s1))){
            return false;
        }
        return securityPackages.stream().anyMatch(s::startsWith)
                && dangerousPackages.stream().noneMatch(s::startsWith);
    }
}

jdk15之后使用方法:

<dependency>
  <groupId>org.openjdk.nashorn</groupId>
  <artifactId>nashorn-core</artifactId>
  <version>15.0</version>
</dependency>
相关资料:

https://stackoverflow.com/questions/65265629/how-to-use-nashorn-in-java-15-and-later

 类似资料: