为什么这个 Jython 循环在一次运行后会失败?

2022-09-03 15:43:41

我有以下代码:

public static String getVersion() 
{
    PythonInterpreter interpreter = new PythonInterpreter();

    try 
    {
        interpreter.exec(IOUtils.toString(new FileReader("./Application Documents/Scripts/Version.py")));
        PyObject get_version = interpreter.get("get_latest_version");
        PyObject result = get_version.__call__(interpreter.get("url"));
        String latestVersion = (String) result.__tojava__(String.class);
        interpreter.close();
        return latestVersion;
    } catch (IOException ex) {
        ex.printStackTrace();
        interpreter.close();
        return Version.getLatestVersionOnSystem();
    }

为了完整起见,我添加了Python代码:

import urllib2 as urllib
import warnings

url = 'arcticlights.ca/api/paint&requests?=version'

def get_latest_version(link=url):
    request = urllib.Request(link)
    handler = urllib.urllopen(request)
    if handler.code is not 200:
        warnings.warn('Invalid Status Code', RuntimeWarning)
    return handler.read()

version = get_latest_version()

它完美无缺地工作,但只有10%的时间。如果我用一个主来运行它,如下所示:

public static void main(String[] args)
{
    for (int i = 0; i < 10; i++) {
        System.out.println(getVersion());
    }   
}

它第一次工作。它给了我我想要的输出,这是来自http请求的数据,它写在我的文件中,上面的java代码调用它。在第二次之后,它抛出了这个巨大的错误(这是950行长,但当然,我不会折磨你们)。这是它的要点:Versions.py

Aug 26, 2015 10:41:21 PM org.python.netty.util.concurrent.DefaultPromise execute
SEVERE: Failed to submit a listener notification task. Event loop shut down?
java.util.concurrent.RejectedExecutionException: event executor terminated

我在950行Java堆栈跟踪末尾提供的Python回溯主要是这样的:

File "<string>", line 18, in get_latest_version 
urllib2.URLError: <urlopen error [Errno -1] Unmapped exception: java.util.concurrent.RejectedExecutionException: event executor terminated>

如果有人好奇,我身上看似令人反感的台词就是:get_latest_version

handler = urllib2.urlopen(request)

由于代码调用的服务器(由 cherrypy)在我的网络上的本地主机上运行,我可以看到它如何与我的服务器交互。它实际上发送两个请求(并在第二个请求之后立即引发异常)。

127.0.0.1 - - [26/Aug/2015:22:41:21] "GET / HTTP/1.1" 200 3 "" "Python-urllib/2.7"
127.0.0.1 - - [26/Aug/2015:22:41:21] "GET / HTTP/1.1" 200 3 "" "Python-urllib/2.7"

虽然我永远不会在循环中运行此代码,但我对两件事非常好奇:

  • 违规代码是我的 Python 还是 Java 代码?或者这可能只是Jython的一个问题?
  • 异常是什么意思(它看起来像一个java异常)?为什么它被扔了呢?有没有办法让这样的循环工作?这可以写得更好吗?

答案 1

您使用的 python 库使用 。urllib2Netty

Netty有一个问题,这是众所周知的:

根据所有这些链接关闭后不时失败。看起来一段时间后会恢复,并且某些应用程序可以正常工作,并出现此问题。无论如何,它看起来不稳定。NettyHttpClientNetty


问:违规代码是我的 Python 代码还是 Java 代码?或者这可能只是Jython的一个问题?

答:问题是由 Jython 库引起的,它使用 .urllib2Netty


问:异常是什么意思(它看起来像一个 java 异常)?为什么它被扔了呢?

答:内部使用。 是用 Java 编写的,并引发此 Java 异常。 使用自己的线程执行器,该执行器在关闭请求后关闭并在一段时间内不可用。这次你打得正好。urllib2NettyNettyNetty


问:有没有办法让这样的循环工作?这可以写得更好吗?

答:我会尝试使用请求库。


答案 2

尝试在每次创建解释器时为其提供新初始化的系统状态:

PySystemState.initialize();
PythonInterpreter interpreter = new PythonInterpreter(null, new PySystemState());

推荐