• Java 7 可执行的 Nashorn,取代 Rhino


    惊现有人把 OpenJDK 上的 Nashorn dump 下来,使得 Java 7 都能够使用。源代码在 https://bitbucket.org/ramonza/nashorn-backport/

    原本 Nashorn 是 Java 8 才有的。如今有人作了向后兼容。好事!

    编译源代码

    仅仅有源代码没有 jar。要自己编译。没关系非常easy:ant -f make/build.xml。详细步骤先把源代码拖进 Eclipse 项目。然后打开 Ant 视图:

     

    点击 + 图标加入 make/build.xml


    然后“运行”就可以编译 jar 包,完毕后保存在 dist 文件夹下。

    假设大家不能成功编译,给大家一个直接下载地址:http://download.csdn.net/detail/zhangxin09/9398572

    測试

    測试是否可用:

    import javax.script.*;
     
    public class NashornTest {
    	public static void main(String args[]) {
    		ScriptEngineManager manager = new ScriptEngineManager();
    		for (ScriptEngineFactory f : manager.getEngineFactories()) {
    			printBasicInfo(f);
    			System.out.println();
    		}
     
    		ScriptEngine nashorn = manager.getEngineByName("nashorn");
    		if(nashorn != null) {
    			System.out.println("Nashorn is present.");
    		}
    		else {
    			System.out.println("Nashorn is not present.");
    		}
    	}
     
    	public static void printBasicInfo(ScriptEngineFactory factory) {
    		System.out.println("engine name=" + factory.getEngineName());
    		System.out.println("engine version=" + factory.getEngineVersion());
    		System.out.println("language name=" + factory.getLanguageName());
    		System.out.println("extensions=" + factory.getExtensions());
    		System.out.println("language version=" + factory.getLanguageVersion());
    		System.out.println("names=" + factory.getNames());
    		System.out.println("mime types=" + factory.getMimeTypes());
    	}
    }

    检測是否可用的另外一个方法:try{final Class<?> cls = Class.forName("jdk.nashorn.api.scripting.ScriptObjectMirror");} ..

    比較 Rhino

    创建一个已经封装过的 JS VM

    		Nashorn n = new Nashorn();
    		Object s = n.eval("g={a:1};");
    		Map ss = (Map)s;
    		ss.get("a");
    		System.out.println(ss.get("a").getClass().getName());
    		System.out.println(s.getClass().getName());

    我封装的 api 自己感觉比較顺手,比如:

    Map s = n.eval("g={a:1};", Map.class); // js 对象转换为 java map

    	        Nashorn n = new Nashorn();
    		Object obj = n.eval("g=[1, 2, 3];");
    		System.out.println(obj.getClass().getName());
    		
    		ScriptObjectMirror so = (ScriptObjectMirror)obj;
    		
    		System.out.println(so.get(0).getClass().getName());
    測试观察发现:

    js 的 {} 哈希类型会自己主动转为 jdk.nashorn.api.scripting.ScriptObjectMirror。而不是 Rhino 的 NativeObject。但两者都能够转为 Map

    js 的 [] 数组类型会自己主动转为 jdk.nashorn.api.scripting.ScriptObjectMirror,而不是 Rhino 的 NativeArray,但能够用 isArray() : boolean 推断是否数组

    js 的 Number 类型会自己主动转为 java.lang.Integer。而不是 Rhino 的 Double,这样在处理数字类型时比較方便。

    只是这是早期版本号。缺了正式版才有的功能。比如:

    if(so.isArray()) {
      int[] iarr = (int[])ScriptUtils.convert(so, int[].class); // 转换为 java 数组保存。由于还没有 convert()
    }

    除了将就还能怎么办涅?想想办法呗(其实也就是谷歌一下)。

    public static void main(String[] args) throws ScriptException, IOException {
    	Nashorn n = new Nashorn();
    	n.load("C:/project/spring-test/src/com/ajaxjs/framework/config.js");
    	Object obj = n.eval("g=[1, 2, 3];");
    	System.out.println(obj.getClass().getName());
    
    	ScriptObjectMirror so = (ScriptObjectMirror) obj;
    	System.out.println(so.get(0).getClass().getName());
    	if (so.isArray()) {
    		System.out.println(so);
    //			int[] iarr = (int[]) ScriptUtils.convert(so, int[].class);
    	}
    
    }
    
    /**
     * js arr2 java arr
     * @param scriptObjectMirror
     * @return
     */
    public static Object[] toArray(ScriptObjectMirror scriptObjectMirror) {
    	if (!scriptObjectMirror.isArray()) {
    		throw new IllegalArgumentException("ScriptObjectMirror is no array");
    	}
    
    	if (scriptObjectMirror.isEmpty()) {
    		return new Object[0];
    	}
    
    	Object[] array = new Object[scriptObjectMirror.size()];
    
    	int i = 0;
    	for (Map.Entry<String, Object> entry : scriptObjectMirror.entrySet()) {
    		Object result = entry.getValue();
    
    		if (result instanceof ScriptObjectMirror && scriptObjectMirror.isArray()) {
    			array[i] = toArray((ScriptObjectMirror) result);
    		} else {
    			array[i] = result;
    		}
    
    		i++;
    	}
    
    	return array;
    }

    其实,假设你不是强迫症。数组 get(0)/get(1)/... 一样可用,无须转换一次。

    单測代码(非常重要!

    http://code.taobao.org/p/bigfoot_v2/src/java_v3/test/javascript/TestJS.java

    Nashorn 文档:http://cr.openjdk.java.net/~sundar/jdk.nashorn.api/8u20/javadoc/jdk/nashorn/api/scripting/AbstractJSObject.html

  • 相关阅读:
    手动配置linux(centos)的IP地址
    linux(centos)上配置nginx、mysql、phpfpm开机启动
    visual studio 2022 下载地址
    自己动手开发编译器(五)miniSharp语言的词法分析器
    自己动手开发编译器(一)编译器的模块化工程
    自己动手开发编译器(二)正则语言和正则表达式
    趣味问题:你能用Reflection.Emit生成这段代码吗?
    自己动手开发编译器(零)序言
    自己动手开发编译器特别篇——用词法分析器解决背诵圣经问题
    自己动手开发编译器(三)有穷自动机
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7103128.html
Copyright © 2020-2023  润新知