Can’t figure out why ScriptEngine engine is null in code

Tags: , ,



This is some of the code I’m running for a MapleStory server. Whenever a script for an event like talking to an NPC is supposed to occur, this script will be run to create a scripting path for whatever script is being called up (NPC, portal, event etc.).

I am also using jdk1.7.0_80

lang-java
package scripting;

import java.io.File; 
import java.io.FileReader; 
import java.io.IOException;
import javax.script.Invocable; 
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import client.MapleClient; 
import tools.FileoutputUtil;

public abstract class AbstractScriptManager {

    private static final ScriptEngineManager sem = new ScriptEngineManager(null);

    protected Invocable getInvocable(String path, MapleClient c) {
        return getInvocable(path, c, false);
    }

    protected Invocable getInvocable(String path, MapleClient c, boolean npc) {
        FileReader fr = null;
        try {
            path = "scripts/" + path;
            ScriptEngine engine = null;

            if (c != null) {
                engine = c.getScriptEngine(path);
            }
            if (engine == null) {
                File scriptFile = new File(path);
                if (!scriptFile.exists()) {
                    return null;
                }
                engine = sem.getEngineByName("JavaScript");
                if (c != null) {
                    c.setScriptEngine(path, engine);
                }
                fr = new FileReader(scriptFile);
                engine.eval(fr);
            } else if (c != null && npc) {
                c.getPlayer().dropMessage(-1, "You already are talking to this NPC. Use @ea if this is 
                not intended.");
            }
            return (Invocable) engine;
        } catch (Exception e) {
            System.err.println("Error executing script. Path: " + path + "nException " + e);
            FileoutputUtil.log(FileoutputUtil.ScriptEx_Log, "Error executing script. Path: " + path + 
            "nException " + e);
            return null;
        } finally {
            try {
                if (fr != null) {
                    fr.close();
                }
            } catch (IOException ignore) {

            }
        }
    } 
}

This is the bat error I receive:

Error executing script. Path: scripts/event/someEvent.js Exception java.lang.NullPointerException: Cannot invoke “javax.script.ScriptEngine.eval(java.io.Reader)” because “engine” is null

These errors are thrown whenever I try to interact with something that utilizes this method (i.e. clicking NPC or on server start-up when some scripts are run).

Answer

The NullPointerException occurs because the Java Runtime you’re using doesn’t have a “JavaScript” Script Engine installed, causing sem.getEngineByName("JavaScript") to return null.

That was verified (see comment) by running the following code:

ScriptEngineManager sem = new ScriptEngineManager();
List<ScriptEngineFactory> factories = sem.getEngineFactories();
for (ScriptEngineFactory factory : factories)
    System.out.println(factory.getEngineName() + " " + factory.getEngineVersion() + " " + factory.getNames());
if (factories.isEmpty())
    System.out.println("No Script Engines found");

When I run this on various Java implementations on Windows 10, I get the following results:

OpenJDK jdk1.7.0_75:
  No Script Engines found

Oracle jdk1.7.0_80:
  Mozilla Rhino 1.7 release 3 PRERELEASE [js, rhino, JavaScript, javascript, ECMAScript, ecmascript]

Oracle jdk1.8.0_181:
  Oracle Nashorn 1.8.0_181 [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript]

Oracle jdk-9.0.4:
  Oracle Nashorn 9.0.4 [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript]

OpenJDK jdk-11.0.2:
  Oracle Nashorn 11.0.2 [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript]

AdoptOpenJDK jdk-14.0.2+12:
  Oracle Nashorn 14.0.2 [nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript]

AdoptOpenJDK jdk-15.0.1+9:
  No Script Engines found

As you can see, the OpenJDK version of Java 7 doesn’t have a JavaScript engine, because the Mozilla Rhino library isn’t open-source. You need the Oracle version of Java 7 to get the JavaScript engine.

You can also see that JavaScript was removed in Java 15, as documented in the JDK 15 Release Notes:

The Nashorn JavaScript script engine, its APIs, and the jjs tool have been removed. The engine, the APIs, and the tool were deprecated for removal in Java 11 with the express intent to remove them in a future release. See JDK-8236933



Source: stackoverflow