Try to run a JavaScript file with Nashorn, failing due to problems with import/const/require

275 Views Asked by At

I need to add a new feature to my Java-8-based application (can't upgrade Java) where it takes an encoded string and decodes it to a JSON. The issue is that that decoding library is written in JavaScript, and the effort to convert the JavaScript code to Java could be consequential.

Looking into alternative solutions, I came across Nashorn, which supposedly is able to run Javascript code from Java. And so I tried to make it work.

First, I created a project with my `index.js" file containing an import statement and a function:

import codec from "some-package"

function decode(a, b) {
   ...
}

I then installed the necessary packages through npm -i and ran my JavaScript code to verify that it worked by itself. Both node index.js and running the code through the right click action of VisualStudio ("Run Code") worked.

Then, I tried to make it work with Java. I moved all the files from my front project into the resources folder of Java, I created a test project with a main() function, and I wrote the following code:

NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine("--language=es6");

try (Reader reader = new InputStreamReader(Objects.requireNonNull(Pulse4Decoder.class.getClassLoader().getResourceAsStream(DECODER_FILE_NAME)), StandardCharsets.UTF_8))
        {
            engine.eval(reader);
        }

I then ran this code but got the following error:

Exception in thread "main" javax.script.ScriptException: <eval>:2:0 Expected an operand but found import
import codec from "some-package";
^ in <eval> at line number 2 at column number 0
    at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:470)
    at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:537)
    at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:524)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
    at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:150)
    at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249)
    at com.edoreld.decoder.Pulse4Decoder.decode(Pulse4Decoder.java:30)
    at com.edoreld.decoder.Pulse4Decoder.main(Pulse4Decoder.java:20)

I thought the problem could be due to Nashorn requiring a specific form of the import statement, so I changed it to const codec = require('@adeunis/codecs');. However, this failed with the following error:

Exception in thread "main" javax.script.ScriptException: ReferenceError: "require" is not defined in <eval> at line number 1
    at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:470)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:454)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402)
    at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:150)
    at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249)
    at com.edoreld.decoder.Pulse4Decoder.decode(Pulse4Decoder.java:30)
    at com.edoreld.decoder.Pulse4Decoder.main(Pulse4Decoder.java:20)

I googled both errors (which is how I came to use --language=es6 in my code originally), but I wasn't able to make it work.

Are import/require statements not supported in Nashorn? How am I supposed to call a function in a JavaScript file that required a specific package if I can't make import/require to work?

0

There are 0 best solutions below