javascript - 在 Java 中访问 JavaScript 对象的字段

标签 javascript oracle scala java

我正在编写一个 Scala 应用程序(应该使用 Spark 在 Hadoop 上运行),我的用户将执行他们上传的 JavaScript 片段,并且我希望向这些 JavaScript 用户提供对用 Scala 编写的某些辅助函数的访问权限(例如“进行 HTTP 调用”等)。所以我所做的就是编写一个大的 JavaScriptHelpers 对象,然后使用

授予对该对象的访问权限
engine = scriptEngineManager.getEngineByName("JavaScript")
engine.put("jql", JavaScriptHelpers)

这样用户就可以在 JavaScript 中说出jql.httpPost(...)。实现这一点的 Scala 代码如下所示:

def httpPost(where: String, params: Object): Try[String] = {
  params match {
    // JavaScript string becomes Java's String:
    case body: String =>
      // ...

    // JavaScript object becomes Java's ScriptableObject
    case obj: ScriptableObject =>
      val params = convertToMap(obj)
      // ...
  }
}

protected def convertToMap(obj: ScriptableObject): Map[String, String] = {
  (for (key <- obj.getIds().toList) yield {
    (key.toString, obj.get(key) match {
      case s: String =>
        s
      case d: java.lang.Double if d.toString.endsWith(".0") =>
        d.toInt.toString
      case other => other.toString
    })
  }).toMap
}

我发现访问存储在 JavaScript 对象中的信息的唯一方法是将它们视为 sun.org.mozilla.javascript.ScriptableObject 的实例。现在,这对我本地的 OpenJDK 安装来说就像一个魅力

java version "1.7.0_75"
OpenJDK Runtime Environment (fedora-2.5.4.2.fc20-x86_64 u75-b13)
OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode)

但是当我在正在运行的 Hadoop 集群上运行相同的代码时

java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

然后我得到:

java.lang.NoClassDefFoundError: sun/org/mozilla/javascript/ScriptableObject
    sun.org.mozilla.javascript.internal.JavaMembers.discoverAccessibleMethods(JavaMembers.java:383)
    sun.org.mozilla.javascript.internal.JavaMembers.discoverAccessibleMethods(JavaMembers.java:335)
    sun.org.mozilla.javascript.internal.JavaMembers.reflect(JavaMembers.java:455)
    sun.org.mozilla.javascript.internal.JavaMembers.<init>(JavaMembers.java:76)
    sun.org.mozilla.javascript.internal.JavaMembers.lookupClass(JavaMembers.java:847)
    sun.org.mozilla.javascript.internal.NativeJavaObject.initMembers(NativeJavaObject.java:88)
    sun.org.mozilla.javascript.internal.NativeJavaObject.<init>(NativeJavaObject.java:78)
    sun.org.mozilla.javascript.internal.NativeJavaObject.<init>(NativeJavaObject.java:68)
    ...

并查看 Oracle 与 JDK 7 捆绑的 Rhino 版本,可从 http://www.oracle.com/technetwork/opensource/jdk7-source-1634015.html 下载似乎所有 sun.org.mozilla.javascript.* 类都已移至 sun.org.mozilla.javascript.internal.*

现在我该如何处理这种情况?是否有任何独立于 Rhino 的方法来访问 Java 中 JavaScript 对象的字段?或者,如何在本地环境中使用 ...javascript.ScriptableObject 时强制 Oracle JVM 使用 ...javascript.internal.ScriptableObject

非常感谢任何帮助。

最佳答案

您可以使用函数重载。

// `params` matches a JavaScript string
def httpPost(where: String, params: String): Try[String] = {
  // ...
}

// `params` matches a JavaScript object
def httpPost(where: String, params: java.util.Map[_, _]): Try[String] = {
  // ...
}

此解决方案适用于我的环境(Oracle JDK 8 和 OpenJDK 1.7)。

关于javascript - 在 Java 中访问 JavaScript 对象的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29030479/

相关文章:

javascript - 在 canvas 和 jquery 中设置图像大小百分比

database - PostgreSQL -> 甲骨文复制

SQL查询返回所有包含%的记录

scala - 为什么我的服务器不在 Play 2.6.x 中请求客户端证书?

scala - 如何在 Play 2.0.1 中使用 TestServer 运行多个功能规范?

scala - 将方法注入(inject)现有类

javascript - foo.toString() 和 Object.prototype.toString.call(foo) 有什么区别?

javascript - 如何通过 Javascript 在 Popover Content (Bootstrap) 中添加 Html 标签(如 <button>)

javascript - Angular - ng-disabled 在范围更改后不起作用

ruby-on-rails - 无法将Rails应用程序连接到Oracle