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

Ziz*_*212 15 python java 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();
    }
Run Code Online (Sandbox Code Playgroud)

为了完整起见,我添加了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()
Run Code Online (Sandbox Code Playgroud)

它完美无缺,但只有10%的时间.如果我用以下主要运行它:

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

它第一次工作.它给了我想要的输出,这是来自我的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
Run Code Online (Sandbox Code Playgroud)

我在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>
Run Code Online (Sandbox Code Playgroud)

如果有人好奇,我看似令人讨厌的线条get_latest_version只是:

handler = urllib2.urlopen(request)
Run Code Online (Sandbox Code Playgroud)

由于代码正在调用的服务器正在我的网络上的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"
Run Code Online (Sandbox Code Playgroud)

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

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

Ole*_*nko 7

urllib2您使用的python库使用Netty.

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

根据所有这些链接Netty HttpClient在关闭后不时失败.它似乎Netty在一段时间后恢复,一些应用程序正常工作与此问题.无论如何它看起来不稳定.


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

答:这个问题是由Jython的库造成的urllib2,它使用Netty.


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

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


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

答:我会尝试使用Requests库.