javascript - 使用 Nashorn 实现模块模式

标签 javascript java groovy java-8 nashorn

我在 Java 8 上探索 Nashorn,它的功能和它赋予开发人员的力量给我留下了深刻的印象。

为了 JavaScript 代码组织的利益,我想我会尝试揭示模块模式。

this._sys = 
(function(){
    function hello() {
        print('hello world!');
    }

    return {
        hello: hello
    };

})();

_sys.hello();

将js代码保存在main.js中。当我使用 jjs 时,上面的代码可以完美运行。 但是当我尝试通过 Groovy/Java 运行相同的代码时,它失败了。有人能知道它为什么失败吗?

在 Groovy 中测试:

class Test {
    public static void main(String[] args) {
        def engine = new ScriptEngineManager().getEngineByName("nashorn")
        engine.eval(new FileReader("E:/main.js"));
        println engine.context.getAttribute("_sys")
        def invocable = engine as Invocable

        def x = invocable.invokeFunction("this._sys.hello",null)
        println x
    }
}

错误:

Exception in thread "main" java.lang.NoSuchMethodException: No such function this._sys.hello
at jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:184)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:508)
at jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:229)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSite.invoke(PojoMetaMethodSite.java:189)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
at Test.main(Test.groovy:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

最佳答案

问题来自于 sys 实际上是 JavaScript 引擎类的一个实例。 hello 不再是一个函数,而是那个类的一个方法,所以你需要使用 Invocable.invokeMethod ,通过传递由 context.getAttribute("_sys") 返回的类的实例和方法的名称。

这是一个工作代码:

class Test {
    public static void main(String[] args) {
        def engine = new ScriptEngineManager().getEngineByName("nashorn")
        engine.eval(new FileReader("E:/main.js"));
        def sys = engine.context.getAttribute("_sys")
        println sys
        def invocable = engine as Invocable

        def x = invocable.invokeMethod(sys, "hello")
        println x
    }
}

例如,您可以阅读以下 Oracle 文章中的 mustache.js 示例:Oracle Nashorn: A Next-Generation JavaScript Engine for the JVM

关于javascript - 使用 Nashorn 实现模块模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32638407/

相关文章:

javascript - Mongoose pre save 没有运行鉴别器

Javascript 在 Internet Explorer 上只运行一次,当开发者工具打开时运行正常

ant - Groovy 2.3的Gradle构建由于缺少依赖关系org/apache/tools/ant/BuildLogger而引发NoClassDefFoundError

groovy - 如何禁用 Groovy 访问器的生成?

grails - g :paginate unknown tag in Grails 2. 4.4

javascript - 异步调用

javascript - 如何使用纯 Reactjs 制作折叠 TextView ?

java - getClass().getResource() 指向什么?

java - 访问具有 log4j 支持的 jar 时未生成日志文件

java - 如何通过 getAttribute() 或executeScript() 方法提取输入字段的值?