既然JVM上面可以运行客体语言, 那么会不会有人在JVM上运行JavaScript? 还别说, 真有!

ringo.js

先说第一个项目,ringo,它在github上有600多的star数目.
解压缩放入path后运行ringo, 进入其REPL, 我试了一下, 下面的是可以运行的:

f = function(s){console.log(s)}
f('hello')

ringo有自己的包管理工具rp, 跟npm差不多. 不过需要安装:

ringo-admin install grob/rp

然而我在windows 10上安装却会报错:

Wrapped java.lang.UnsupportedOperationException
        at fs.js:1100 (changePermissions)
        at C:\l\tools\admin\install.js:86 (installPackage)
        at C:\l\tools\admin\install.js:156 (main)
        at C:\l\tools\admin\main.js:14 (main)
        at C:\l\tools\admin\main.js:30

哦...这就无法继续了...
一个语言的强大在于其库的强大,如果它能同时使用npm和java库,那就真的非常强大了,看来暂时是无法验证了.

java8 jjs: oracle nashorn

没错. Java8支持JavaScript, 这个运行工具就是jjs, 正式名字叫做Nashorn. Oracle官方的这篇文章 Oracle Nashorn: A Next-Generation JavaScript Engine for the JVM有一些说明, 我查了一下我的java, 还真是8:

λ java -version                                                         
java version "1.8.0_111"                                                
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)                   
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)        

根据文章说, jjs和java在同一目录, 能运行java就意味着jjs也能运行, 先看看版本:

λ jjs -v                  
nashorn 1.8.0_111         
jjs>                      

果然进来了呢! 试了一下, 居然不支持console.log...
对应的打印命令,居然是print...
对此, 文章是这样解释的: 虽然我们兼容ECMA, 但是浏览器环境下的特有变量我们是不支持的,比如window, console这些.

好处呢? 一个是在Java中调用JavaScript代码,还能用到JavaScript的库, 恩,这个感觉比较符合oracle的思路...
文中举例了在Java中调用mustache.js库的方式.

package sample2;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.FileReader;

public class Mustache {

  public static void main(String... args) throws Throwable {
    ScriptEngineManager engineManager = 
new ScriptEngineManager();
    ScriptEngine engine = 
engineManager.getEngineByName("nashorn");
    engine.eval(new FileReader("src/sample2/mustache.js"));
    Invocable invocable = (Invocable) engine;

    String template = "Email addresses of {{contact.name}}:\n" +
        "{{#contact.emails}}\n" +
        "- {{.}}\n" +
        "{{/contact.emails}}";

    String contactJson = "{" +
        "\"contact\": {" +
        "\"name\": \"Mr A\", \"emails\": [" +
        "\"contact@some.tld\", \"sales@some.tld\"" +
        "]}}";
Object json = engine.eval("JSON");
    Object data = 
invocable.invokeMethod(json, "parse", contactJson);

    Object mustache = engine.eval("Mustache");
    System.out.println(invocable.invokeMethod(
mustache, "render", template, data));
  }
} 

另一个是在JavaScript中调用Java,这个我比较关心. 哦, 直接调用就好了, 很简单的样子:

print(java.lang.System.currentTimeMillis());

Java对象也可以使用new来实体化, 这个就酷了:

var file = 
new java.io.File("sample.js");
print(file.getAbsolutePath());
print(file.absolutePath); 

java.io.File虽然没有定义absolutePath,但是定义了getAbsolutePath(), jjs会自动增加absolutePath这个属性. 对set也是一样.
这样来看,nashorn很可能可以同时使用部分npm库和java库,看上去很强大的样子.
剩下一个问题就是速度了. nashorn和v8对比速度如何? 从这篇文章来说,还是要差一些的. 对ES的支持呢? 似乎是支持到ES5.1,还没有对新特性的支持. 试了一下ES6中的箭头函数, 果然是没有支持的. 这点上就远不如node.js那么积极啦.

jjs> var a = ()=>{print()}                                                    
ECMAScript Exception: SyntaxError: <shell>:1:9 Expected an operand but found )
var a = ()=>{print()}                                                         
         ^                                                                    

nashorn项目官网

rhino.js

哦, 这个就是被java8抛弃的那个, mozilla基金会的项目, 官网, github项目地址

标签: none 阅读量: 2250

添加新评论