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

时间:2015-08-27 02:58:08

标签: java python loops exception-handling jython

我有以下代码:

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());
    }   
}

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

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)

由于代码正在调用的服务器正在我的网络上的localhost上运行(由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异常)?它为什么会被抛出?有没有办法像这样做一个循环?这可以写得更好吗?

2 个答案:

答案 0 :(得分:7)

您使用的python库urllib2使用Netty

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

根据所有这些链接Netty HttpClient在结束后不时失败。看起来Netty在一段时间后恢复,一些应用程序正常地解决了这个问题。无论如何它看起来不稳定。

问:问题代码是我的Python代码还是Java代码?或者它只是Jython的一个问题?

答:问题是由使用urllib2的Jython库Netty引起的。

问:异常意味着什么(看起来像java异常)?它为什么会被抛出?

答:urllib2在内部使用NettyNetty是用Java编写的,并抛出了这个Java异常。 Netty使用自己的Thread Executor,在关闭请求后关闭并且无法使用一段时间。你这次正好打。

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

答:我会尝试使用Requests库。

答案 1 :(得分:0)

每次创建时,尝试为解释器提供一个刚刚初始化的系统状态:

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