Jython脚本实现的类从Java中未正确初始化

1 投票
1 回答
642 浏览
提问于 2025-04-16 09:31

我正在尝试做一些类似于问题 4617364的事情,但这是针对Python的——我想从一个Python脚本文件中加载一个类,这个类实现了一个Java接口,然后把它交给一些可以使用其方法的Java代码。但是,当我调用这个对象的方法时,返回的值都是不正确的,而且在初始化器中打印的内容似乎没有任何效果。

我的实现看起来是这样的:

接口:

package some.package;
import java.util.List;
public interface ScriptDemoIf {
    int fibonacci(int d);
    List<String> filterLength(List<String> source, int maxlen);
}

Python实现:

from some.package import ScriptDemoIf

class ScriptDemo(ScriptDemoIf):
    """ Class ScriptDemo implementing ScriptDemoIf """

    def __init__(self):
        print "Script Demo init"

    def fibonacci(self, d):
        if d < 2:
            return d
        else:
            return self.fibonacci(d-1) + self.fibonacci(d-2)

    def filterLength(self, source, maxlen):
        return [ str for str in source if len(str) <= maxlen ]

类加载器:

public ScriptDemoIf load(String filename) throws ScriptException {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("jython");
    FileReader script = new FileReader(filename);
    try {
        engine.eval(new FileReader(script));
    } catch (FileNotFoundException e) {
        throw new ScriptException("Failed to load " + filename);
    }
    return (ScriptDemoIf) engine.eval("ScriptDemo()");
}

public void run() {
    ScriptDemoIf test = load("ScriptDemo.py");
    System.out.println(test.fibonacci(30));
}

(显然,实际中的加载器要更通用一些——它并不假设实现类的名称是“ScriptDemo”——这只是为了简单起见)。

当代码运行时,我没有看到Python的__init__中的打印内容(不过如果我在脚本的主体中放一个打印语句,我是能看到的),但是在run()中的test变量看起来像是一个有效的jython“代理对象”,而且我没有遇到类型转换错误。当我尝试运行fibonacci()方法时,我总是得到0(即使我把这个方法改成总是返回一个固定的数字),而filterLength()方法总是返回null(这可能与Java接口中的默认值有关)。

我到底哪里出错了?

1 个回答

2

你在用哪个版本的jython?你可能遇到了JSR223 Jython的一个bug:http://bugs.jython.org/issue1681

根据这个bug的描述:

在使用JSR-223和Jython 2.5.2rc2时,从嵌入的Jython脚本调用方法没有任何效果,而Jython 2.2.1则可以正常工作。

撰写回答