惊现有人把 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

Java 7 可执行的 Nashorn,取代 Rhino的更多相关文章

  1. Java 8新特性之 Nashorn(八恶人-6)

    Joe Gage 盖奇·乔 “First time in my life I made a pretty penny.And, figured I'd come home and spend time ...

  2. Java使用Optional与Stream来取代if判空逻辑(JDK8以上)

    Java使用Optional与Stream来取代if判空逻辑(JDK8以上) 通过本文你可以用非常简短的代码替代业务逻辑中的判null校验,并且很容易的在出现空指针的时候进行打日志或其他操作. 注:如 ...

  3. Java JDBC下执行SQL的不同方式、参数化预编译防御

    相关学习资料 http://zh.wikipedia.org/wiki/Java数据库连接 http://lavasoft.blog.51cto.com/62575/20588 http://blog ...

  4. 怎么优化JAVA程序的执行效率和性能?

    现在java程序已经够快的了,不过有时写出了的程序效率就不怎么样,很多细节值得我们注意,比如使用StringBuffer或者StringBuilder来拼接或者操作字符串就比直接使用String效率高 ...

  5. Java SSH远程执行Shell脚本实现(转)

    前言 此程序需要ganymed-ssh2-build210.jar包(下载地址:http://www.ganymed.ethz.ch/ssh2/) 为了调试方便,可以将\ganymed-ssh2-bu ...

  6. 捕获Java线程池执行任务抛出的异常

    捕获Java线程池执行任务抛出的异常Java中线程执行的任务接口java.lang.Runnable 要求不抛出Checked异常, public interface Runnable { publi ...

  7. JAVA 文件编译执行与虚拟机(JVM)简单介绍

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo3 java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 ...

  8. 浅析java程序的执行过程

    在研究任何一门语言时,无论是面向过程的c,c++(面向过程和面向对象),还是面向对象的.net,java等,弄清语言执行过程至关重要.  何为语言执行过程? 所谓语言执行过程,指对于任何一门语言,如j ...

  9. 通过指令码来判断Java代码的执行顺序(++问题与return和finally的问题)

    问题 在<深入理解Java虚拟机>一书中遇到了如下代码: public int method() { int i; try { i = 1; return i; } catch (Exce ...

随机推荐

  1. <form> 标签

    <form method="传送方式" action="服务器文件"> action :浏览者输入的数据被传送到的地方,比如一个PHP页面(save ...

  2. LinearLayout中间布局填充出现的问题

    线性布局如何中间填充,会挤掉他下面的布局,所以中间填充使用layout_weight属性.

  3. 【PostgreSQL-9.6.3】触发器概述(普通触发器)

    一个触发器声明了当执行一种特定类型的操作时数据库应该自动执行一个特殊的函数.触发器可以被附加到表.视图和外部表.触发器经常用于做完整性约束,或者某种业务规则的约束. 1. 触发器的创建语法如下: CR ...

  4. iOS开发中如何实现同步、异步、GET、POST等请求实操演示!

    1.同步请求可以从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作, 2.异步请求不会阻塞主线程,而会建立一个新的线程来操作,用户发出异步请求后,依然 ...

  5. (二)Python 学习第二天--爬5068动漫图库小案例

    (注:代码和网站仅仅是学习用途,非营利行为,源代码参考网上大神代码,仅仅用来学习

  6. css nth-child 的应用

    最近改视频监控页面,由于窗口比较多,以前是通过计算窗口大小位置来处理页面布局的,其实还是比较麻烦,而且偶尔会有页面位置错乱的现象,虽然只是及其偶尔的现象,但总归是不好. 计算窗口位置的代码: /*监控 ...

  7. Apache 在Linux上的安装

    1.获取源码 wget http://mirror.bit.edu.cn/apache//httpd/httpd-2.4.37.tar.gz 2.卸载centos自带的apache 3.解压apach ...

  8. ubuntu 更改终端颜色

    1.$ sudo gedit .bashrc 2.PS1="\[\033[1;36;01m\]\u\[\033[00m\]\[\033[1;34;01m\]@\[\033[00m\]\[\0 ...

  9. 批量obj格式直接转gltf

    在cesium中的模型需要的是gltf或glb格式的文件,之前的做法是用将模型从3d max中导出dae格式的文件(需要插件),然后用collada2gltf工具将dae格式转成gltf. 最近翻看c ...

  10. https webservice通讯 参考网址 http://blog.csdn.net/small____fish/article/details/8214938

    一.生成密钥库和证书可参考以下密钥生成脚本,根据实际情况做必要的修改,其中需要注意的是:服务端的密钥库参数“CN”必须与服务端的IP地址相同,否则会报错,客户端的任意. 1.生成服务器证书库keyto ...