简体   繁体   中英

How can I invoke a method from Nashorn with a webpack js file?

If I run following code I get output:

simple.js

Exception in thread "main" java.lang.NoSuchMethodException: No such function definition

How can I invoke the 'definition' function in my webpack js file using invokeFunction?

Java main:

public static void main(String[] args) throws ScriptException, NoSuchMethodException {
        ScriptEngine jsEngine = new ScriptEngineManager().getEngineByName("nashorn");

        Compilable jsCompilable = (Compilable) jsEngine;
        CompiledScript jsScript = jsCompilable.compile(getBasicScript());

        ScriptContext scriptCtxt = jsEngine.getContext();
        Bindings engineScope = scriptCtxt.getBindings(ScriptContext.ENGINE_SCOPE);
        jsScript.eval(engineScope);

        Invocable jsInvocable = (Invocable) jsEngine;
        jsInvocable.invokeFunction("definition", "mark");
    }    

Webpack file called in getBasicScript():

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};

/******/    // The require function
/******/    function __webpack_require__(moduleId) {

/******/        // Check if module is in cache
/******/        if(installedModules[moduleId])
/******/            return installedModules[moduleId].exports;

/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            exports: {},
/******/            id: moduleId,
/******/            loaded: false
/******/        };

/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/        // Flag the module as loaded
/******/        module.loaded = true;

/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }


/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;

/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;

/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";

/******/    // Load entry module and return exports
/******/    return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports) {

    print('simple.js'); 

    function definition(name) { 
        print('Hello: ' + name); 
    }

/***/ }
/******/ ]);

The problem seems to be that the definition function is not declared in the top level scope. It is declared inside an anonymous function (which is itself passed as argument to the "main" function). Regardless of what happens in the main function, the definition function is practically private to its enclosing function (starting at line 45).

If you want to call a function through the Invocable interface, it must be declared globally (in top-level scope) either as a function declaration or a var-statement.

Here is another way to use a webpack built module using invokeMethod instead of invokeFunction :

val root = engine.eval("root") // 'root' being your output.library
engine.invokeMethod(root, "methodName", ...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM