Java 和 JSR-223 到 运行 Python(或 Ruby)Coldfusion 服务器上的代码

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] 不存在

另一个 class、ScriptEngine 如何适应这个?

更新

我可以加载其他 Python classes 所以我认为 jar 安装正确。即使用以下代码我可以转储 interp 对象。

 interp = CreateObject("java", "org.python.util.PythonInterpreter");

但是即使调用方法也会给我这个错误

 java.lang.NullPointerException

关键字 new 调用 class 构造函数。 ColdFusion 不支持 new 和 java 个对象。相反,使用 psuedo-method init():

The init method is not a method of the object, but a ColdFusion identifier that calls the new function on the class constructor.

该代码的 文字 翻译是链接调用。首先调用 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 将自动调用无参数构造函数

...If you call a public non-static method on the object without first calling the init method, ColdFusion makes an implicit call to the default constructor.

根据评论更新:

如果未定义 engine,则表示未找到 "python" 引擎。 确保你有 added the the jython jar file to the CF class path (or loaded it via this.javaSettings in your Application.cfc). Once it is registered, the code should work correctly. For some reason it does not work if you load the jar dynamically through ACF's this.javaSettings。但是,如果将 jython jar 放在 WEB-INF\lib 中并重新启动 CF,它会正常工作。尝试将 jar 添加到物理 CF class 路径,而不是动态加载它,它应该可以正常工作。

如果您首先手动注册引擎,它也适用于 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");
// ...

How does the other class, ScriptEngine fit in with this?

与 CF 不同,Java 是强类型的。这意味着当您声明一个变量时,您还必须声明它的类型(或 class)。原始代码将 engine 变量声明为 ScriptEngine class 的实例。由于 CF 是弱类型的,因此没有必要。只需像往常一样声明变量名。 getEngineByName() method自动returns一个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);