使用 Nashorn 实现模块模式
Implementing the module pattern with Nashorn
我在 Java 8 上探索 Nashorn,它的功能和它赋予开发人员的力量给我留下了深刻的印象。
出于对Java脚本代码组织的兴趣,我想我会尝试揭示模块模式。
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
实际上是 class 到 JavaScript 引擎的一个实例。 hello
不再是一个函数,而是 class 的一个方法,因此您需要使用 Invocable.invokeMethod
,通过传递 class 的实例,由 [=14] 返回=],以及方法的名称。
这是一个工作代码:
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
我在 Java 8 上探索 Nashorn,它的功能和它赋予开发人员的力量给我留下了深刻的印象。
出于对Java脚本代码组织的兴趣,我想我会尝试揭示模块模式。
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
实际上是 class 到 JavaScript 引擎的一个实例。 hello
不再是一个函数,而是 class 的一个方法,因此您需要使用 Invocable.invokeMethod
,通过传递 class 的实例,由 [=14] 返回=],以及方法的名称。
这是一个工作代码:
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