当前位置: 首页 > 知识库问答 >
问题:

从Rhino切换到Nashorn

柴声
2023-03-14

我有一个Java 7项目,它大量使用Javascript编写各种功能的脚本。到目前为止,我一直使用Rhino作为脚本引擎。我现在想转到Java 8,这也意味着我将用Nashorn取代Rhino。

Nashorn与Rhino的兼容性如何?我可以将其用作直接替换,还是我可以预期我的一些脚本将不再工作,需要移植到新引擎?Rhino是否有Nashorn不支持的常用功能?

共有3个答案

潘志国
2023-03-14

当内部类被声明为私有时,Nashorn无法访问该内部类,Rhino可以这样做:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Test {
   public static void main(String[] args) {
     Test test = new Test();
     test.run();
   }

   public void run() {
      ScriptEngineManager factory = new ScriptEngineManager();
      ScriptEngine engine = factory.getEngineByName("JavaScript");

      Inner inner = new Inner();
      engine.put("inner", inner);

      try {
         engine.eval("function run(inner){inner.foo(\"test\");} run(inner);");
      } catch (ScriptException e) {
         e.printStackTrace();
      }
   }

   private class Inner {
      public void foo(String msg) {
         System.out.println(msg);
      }
   }
}

在Java8下,此代码引发以下异常:

javax.script.ScriptException: TypeError: kz.test.Test$Inner@117cd4b has no such function "foo" in <eval> at line number 1
    at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:564)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:548)
戚升
2023-03-14

要在JDK 8上使用import Class方法,我们需要添加以下命令:

load("nashorn:mozilla_compat.js");

但是,此更改会影响JDK 7上的执行(JDK不支持load方法)。

为了保持两个SDK的兼容性,我通过添加try/catch子句解决了这个问题:

try{
    load("nashorn:mozilla_compat.js");
}catch(e){
}
仲孙信瑞
2023-03-14

一个问题是,默认情况下,Nashorn无法再使用importPackage(com.organization.project.package)将整个Java包导入全局范围

然而,有一个简单的解决方法:通过将这一行添加到脚本中,可以启用Rhino的旧行为:

load("nashorn:mozilla_compat.js");

我遇到的另一个问题是在java和javascript之间传递数据时的某些类型转换工作方式不同。例如,当您将Javascript数组传递给Java时到达的对象不能再转换为List,但它可以转换为Map

 类似资料:
  • 我目前正在开发一款只使用2D图形的游戏。 在游戏中,我广泛使用android的来显示我的图形。我听说,使用硬件加速图形,我可以使用它来提高我的应用程序的性能,而不是使用当前的。 目前,我有一个扩展的类,当我自己的线程类扩展调用和方法时,它会更新和渲染游戏状态。线程基本上帮助我保持几乎恒定的FPS。 现在的问题是:我如何从更改为,并调用方法从线程更新和渲染游戏状态,以仍然控制FPS。我阅读了Open

  • Java(TM)SE运行时环境(构建1.8.0_102-B14) Java HotSpot(TM)64位服务器VM(构建25.102-B14,混合模式) 我知道jdk11不包含jre,但是我如何在java 11中从cmd运行java程序呢

  • Nerv 提供了比 React 更好的浏览器兼容性和更高的性能,与此同时也不会放弃 React 庞大的生态系统。兼容 React 生态系统是我们开发 Nerv 的重要目标之一。 假设我们有这样一段代码: var React = require('react'); var ReactDOM = require('react-dom'); class MyComponent extends Reac

  • 你好,我想导入我的android studio项目到Netbeas,但我得到这个错误与Gradle。

  • 问题内容: 我正在创建一个Android应用程序,并通过HttpClient将数据从Android应用程序发送到servlet。我使用HttpPost方法。 我在Android开发人员网站上了解到,Apache HttpClient库在Android Froyo 2.2中存在一些错误,毕竟使用HttpUrlConnection而不是HttpPost是一个好习惯。所以我想将我的HttpPost代码转

  • 我创建了一个应用引擎Flex NodeJS应用程序,没有意识到没有免费层。所以我决定切换到应用引擎标准。我更新了我的,部署好了,一切似乎都在工作。然而,我几个小时前部署了这个,我仍然有两个计算引擎实例在运行。我需要做些什么来关闭这些实例,还是我等得不够长?我根本不想让它们运行,因为我不想为它们付费,尤其是因为标准应用程序根本不使用计算引擎。 我试着去GCP中的Compute Engine选项卡看看