无法弄清楚为什么 ScriptEngine 引擎在代码中为空

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

这是我 运行 为 MapleStory 服务器编写的一些代码。每当与 NPC 交谈等事件的脚本应该发生时,该脚本将 运行 为正在调用的任何脚本(NPC、门户、事件等)创建脚本路径。

我也在用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) {

            }
        }
    } 
}

这是我收到的 bat 错误:

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

每当我尝试与使用此方法的东西交互时(即单击 NPC 或在某些脚本 运行 时服务器启动时),就会抛出这些错误。

出现 NullPointerException 是因为您正在使用的 Java 运行时没有安装“JavaScript”脚本引擎,导致 sem.getEngineByName("JavaScript") 到 return null.

已通过 运行 以下代码验证(参见 ):

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");

当我 运行 在 Windows 10 上的各种 Java 实现上执行此操作时,我得到以下结果:

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

如您所见,Java 7 的 OpenJDK 版本没有 JavaScript 引擎,因为 Mozilla Rhino 库不是开源的。您需要 Java 7 的 Oracle 版本才能获得 Java 脚本引擎。

您还可以看到 Java脚本已在 Java 15 中删除,如 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