Nashorn:如何在函数或对象上调用函数

时间:2019-10-09 15:27:15

标签: nashorn

推荐的一种编写javascript模块的方法如下:

var engine = (function() {
    // private stuff goes here...
    function composeGreeting() {return 'Hello';};
    return {
       composeGreeting: composeGreeting
    } // return
})(); 

但是,如果您使用nashorn评估上述文件,我将找不到一种方法来调用“ composeGreeting”

文件的评估如下:

File file = new File("my.js")
Reader reader = file.newReader();
engine.eval(reader)
Invocable invocable = (Invocable) engine;

我试图这样调用函数:

Object funcResult = invocable.invokeFunction("engine.composeGreeting");

但这不起作用。

我也在黑暗中刺了一下,并尝试了这个:

 funcResult = invocable.invokeMethod(engine.get("engine"), "composeGreeting");

但是,这会产生错误“ java.lang.NoSuchMethodException”

也尝试了此操作(无效)

funcResult = invocable.invokeFunction("engine").invokeFunction("composeGreeting");

也尝试过此操作(renderServer为空)

ScriptObjectMirror renderServer = (ScriptObjectMirror) scriptEngine.get("engine");

funcResult = renderServer.call(“ composeGreeting”);

有什么建议吗?该文档说,get只是返回一个对象-没有提及该对象实际是什么或如何使用它。

很明显,如果我的js文件中包含以下内容:

function composeGreeting() {return 'Hello';};

仅此而已,我可以这样称呼它:

Object funcResult = invocable.invokeFunction("composeGreeting");

但是,这将暴露我js文件的所有私有内部gubbins。

说实话,我不知道“引擎”的类型。

注意:我们不能使用graalVM,因为graalVM当前仅支持Java 8,并且比nashorn更少的GraalVM示例。

此帖子暗示有可能,但不包括解决方案: Nashorn: Call function inside of a namespace

1 个答案:

答案 0 :(得分:0)

我在正确的轨道上。已发布有效的答案here

关键是这一行:

buildscript {
    apply from: 'versions.gradle'
    ext.kotlin_version = '1.3.41'

    repositories {
        jcenter()
        maven { url 'https://maven.fabric.io/public' }
        maven { url "https://plugins.gradle.org/m2/" }
        google()
    }
    dependencies {
        classpath gradlePlugin.android
        classpath gradlePlugin.googleService
        classpath gradlePlugin.butterknife
        classpath gradlePlugin.fabric
        classpath gradlePlugin.firebase
        classpath gradlePlugin.kotlin
        classpath gradlePlugin.langapi
    }
}

allprojects {
    repositories {
        jcenter()
        maven {
            url "https://jitpack.io"
            credentials { username authToken }
        }
        maven { url "https://maven.google.com" }
        maven { url "https://dl.bintray.com/drummer-aidan/maven" }
        maven { url "https://oss.sonatype.org/content/repositories/snapshots" }

        google()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

不确定以前为什么对我不起作用,但现在可以起作用。