可以弄清楚为什么ScriptEngine引擎在代码中为null

发布于 2025-02-04 06:21:51 字数 2379 浏览 1 评论 0 原文

这是我正在为MapLestory服务器运行的一些代码。每当应该发生像与NPC交谈之类的事件的脚本时,将运行此脚本以创建所谓的任何脚本(NPC,Portal,Event等)的脚本路径。

我还使用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) {

            }
        }
    } 
}

这是我收到的蝙蝠错误:

错误执行脚本。路径:脚本/事件/someEvent.js异常 java.lang.nullpointerexception:无法调用 “ javax.script.scriptEngine.eval(java.io.reader)”,因为“引擎”为null

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

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

jJeQQOZ5 2025-02-11 06:21:51

NullPoInterException 发生,因为您使用的Java运行时没有安装的“ JavaScript”脚本引擎,引起 sem.getEngineByName(“ JavaScript”)返回 > 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版本才能获取JavaScript引擎。

您还可以看到JavaScript已在Java 15中删除,如 JDK 15发行说明

已删除了Nashorn JavaScript脚本引擎,其API和 JJS 工具。发动机,API和该工具在Java 11中被删除,并在将来的版本中明确删除它们。请参阅JDK-8236933

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

稚气少女 2025-02-11 06:21:51

我对JDK 17和 lib rhino.js.enengine-1.7.71.jar 也有同样的问题。

org.mozilla.javascript-1.7.5.jar

也添加了我的班级路径。解决了错误。

I had the same problem with JDK 17 and lib rhino.js.engine-1.7.71.jar.

I added

org.mozilla.javascript-1.7.5.jar

to my classpath too. That solved the error.

薄凉少年不暖心 2025-02-11 06:21:51

或者,只需直接使用犀牛本身,没有 scriptenginemanager

pom.xml:

<dependency>
  <groupId>org.mozilla</groupId>
  <artifactId>rhino</artifactId>
  <version>1.7.15</version>
</dependency>

<dependency>
  <groupId>org.mozilla</groupId>
  <artifactId>rhino-engine</artifactId>
  <version>1.7.15</version>
</dependency>

<dependency>
  <groupId>org.mozilla</groupId>
  <artifactId>rhino-runtime</artifactId>
  <version>1.7.15</version>
</dependency>

java代码:

import java.util.*;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;


public static String executeScript(String js) {
    // Creates and enters a Context. The Context stores information
    // about the execution environment of a script.
    Context cx = Context.enter();
    try {
        // Initialize the standard objects (Object, Function, etc.)
        // This must be done before scripts can be executed. Returns
        // a scope object that we use in later calls.
        Scriptable scope = cx.initStandardObjects();


        // Now evaluate the string we've colected.
        Object result = cx.evaluateString(scope, js, "<cmd>", 1, null);

        // Convert the result to a string and print it.
        logger.debug(Context.toString(result));
        return (String) result;
    } finally {
        // Exit from the context.
        Context.exit();
    }
}

Or, just directly use rhino itself, without ScriptEngineManager:

pom.xml:

<dependency>
  <groupId>org.mozilla</groupId>
  <artifactId>rhino</artifactId>
  <version>1.7.15</version>
</dependency>

<dependency>
  <groupId>org.mozilla</groupId>
  <artifactId>rhino-engine</artifactId>
  <version>1.7.15</version>
</dependency>

<dependency>
  <groupId>org.mozilla</groupId>
  <artifactId>rhino-runtime</artifactId>
  <version>1.7.15</version>
</dependency>

java code:

import java.util.*;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;


public static String executeScript(String js) {
    // Creates and enters a Context. The Context stores information
    // about the execution environment of a script.
    Context cx = Context.enter();
    try {
        // Initialize the standard objects (Object, Function, etc.)
        // This must be done before scripts can be executed. Returns
        // a scope object that we use in later calls.
        Scriptable scope = cx.initStandardObjects();


        // Now evaluate the string we've colected.
        Object result = cx.evaluateString(scope, js, "<cmd>", 1, null);

        // Convert the result to a string and print it.
        logger.debug(Context.toString(result));
        return (String) result;
    } finally {
        // Exit from the context.
        Context.exit();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文