我正在編寫一個Scala應用程序(應該使用Spark在Hadoop上運行),我的用戶需要執行他們上傳的JavaScript代碼段,並且我想提供對某些寫入的幫助函數的訪問在Scala中(比如「發送HTTP呼叫」等)給這些JavaScript用戶。所以我要做的就是寫一個大JavaScriptHelpers
對象,然後使用訪問Java對象中的JavaScript對象的字段
engine = scriptEngineManager.getEngineByName("JavaScript")
engine.put("jql", JavaScriptHelpers)
這樣用戶就可以說在JavaScript jql.httpPost(...)
給訪問該對象。斯卡拉代碼,使這成爲可能看起來如下:
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對象的字段?或者,如何強制Oracle JVM在本地環境中使用...javascript.internal.ScriptableObject
而使用...javascript.ScriptableObject
?
任何幫助非常感謝。
嗯。出於我的想法:您正在爲用戶提供帶有Jacascript語法的DomainSpecificLanguage。您是否看過JSR 233?另外轉換一個Javascript對象有很多庫已經涵蓋了這個話題,我的第一個命中是http://stackoverflow.com/questions/1395551/convert-a-json-string-to-object-in-java – 2015-03-13 11:09:10