[英]Java and JSR-223 to run Python (or Ruby) code on a Coldfusion server
我試圖使用Java在Coldfusion服務器上運行Python代碼。 我熟悉CFML,但他是Java的絕對初學者。
我可以實例化對象並列出他們的方法,但是我遇到了不同的對象類型。
我試圖在Coldfusion中工作的例子是
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class JSR223 {
public static void main(String[] args) throws ScriptException {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
engine.eval("import sys");
engine.eval("print sys");
engine.put("a", 42);
engine.eval("print a");
engine.eval("x = 2 + 2");
Object x = engine.get("x");
System.out.println("x: " + x);
}
}
到目前為止我在CFML中的表現
ScriptEngine = CreateObject("java", "javax.script.ScriptEngine");
ScriptEngineManager = CreateObject("java", "javax.script.ScriptEngineManager");
ScriptException = CreateObject("java", "javax.script.ScriptException");
我堅持的部分
ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
如何在CFML中創建它?
編輯:
engine = ScriptEngineManager.getEngineByName("python");
writeDump(engine);
給我一個錯誤: 變量[ENGINE]不存在
其他類ScriptEngine如何適應這個?
更新
我可以加載其他Python類,所以我認為jar正確安裝。 即使用以下代碼我可以轉儲interp對象。
interp = CreateObject("java", "org.python.util.PythonInterpreter");
然而,即使這樣調用方法也會給我這個錯誤
java.lang.NullPointerException
關鍵字new
調用類構造函數。 ColdFusion不支持java對象的new
。 相反,使用psuedo方法init() :
init方法不是對象的方法,而是在類構造函數上調用新函數的ColdFusion標識符。
該代碼的字面翻譯是鏈接調用。 首先調用init(),以創建新實例。 然后在該實例上調用getEngineByName():
engine = createObject("java", "javax.script.ScriptEngineManager").init().getEngineByName("python");
雖然為了更好的可讀性,您可能想要分解它:
ScriptEngineManager = createObject("java", "javax.script.ScriptEngineManager").init();
engine = ScriptEngineManager.getEngineByName("python");
順便說一句,在這種特定情況下,您可以在技術上省略對init()
的調用。 一旦調用getEngineByName(),ColdFusion將自動調用no-arg構造函數:
...如果在沒有先調用init方法的情況下在對象上調用公共非靜態方法,ColdFusion會對默認構造函數進行隱式調用。
根據評論更新:
如果engine
沒有定義,這意味着“蟒蛇”發動機沒有被發現。
確保已將
jython jar文件
添加到CF類路徑(或通過
this.javaSettings
中的
this.javaSettings
加載它)。
一旦注冊,代碼應該正常工作。
出於某種原因,如果通過ACF的this.javaSettings動態加載jar, 它就不起作用 。 但是,如果將jython jar放在WEB-INF\\lib
並重新啟動CF,它可以正常工作。 嘗試將jar添加到物理CF類路徑,而不是動態加載它,它應該正常工作。
如果您首先手動注冊引擎,它也適用於CF(見下文)。 不確定為什么在CF中調用ScriptEngineManager時需要額外的步驟,而不是從Eclipse調用。
ScriptEngineManager = createObject("java", "javax.script.ScriptEngineManager").init();
factory = createObject("java", "org.python.jsr223.PyScriptEngineFactory").init();
ScriptEngineManager.registerEngineName("python", factory);
engine = ScriptEngineManager.getEngineByName("python");
// ...
其他類ScriptEngine如何適應這個?
與CF不同,Java是強類型的。 這意味着當您聲明變量時,您還必須聲明其類型(或類)。 原始代碼將engine
變量聲明為ScriptEngine
類的實例。 由於CF是弱類型的,因此不是必需的。 只需像往常一樣聲明變量名稱。 getEngineByName()方法自動返回ScriptEngine
對象(通過API中的定義)。
我能夠使用以下代碼將Leigh的示例工作在Lucee中,並將jar放在與.cfm文件相同的目錄中。 我最初把它放在與Lucee jar相同的文件夾中,但它只是部分工作。
ScriptEngineManager = createObject('java','javax.script.ScriptEngineManager').init();
factory = createObject('java','org.python.jsr223.PyScriptEngineFactory','jython-standalone-2.7.0.jar').init();
ScriptEngineManager.registerEngineName("python", factory);
engine = ScriptEngineManager.getEngineByName("python");
engine.eval("x = 2 + 2");
x = engine.get("x");
writeDump(x);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.