为什么此Jython循环一次运行后会失败? [英] Why does this Jython loop fail after a single run?

查看:138
本文介绍了为什么此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)

由于正在调用代码的服务器正在(通过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异常)?为什么要扔它呢?有没有办法使像这样的循环?可以写得更好吗?

解决方案

您使用的python库urllib2使用Netty.

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

根据所有这些链接,Netty HttpClient在关闭后有时会失败.看起来Netty会在一段时间后恢复,并且某些应用程序正好可以解决此问题.无论如何,它看起来都很不稳定.


问:令人讨厌的代码是我的Python还是Java代码?还是仅仅是Jython的问题?

A:问题是由使用Netty的Jython库urllib2引起的.


问:异常是什么意思(看起来像Java异常)?为什么会被抛出?

A:urllib2在内部使用Netty. Netty用Java编写,并引发此Java异常. Netty使用其自己的线程执行器,该线程执行器在关闭请求后将关闭并在一段时间内不可用.这次您恰好击中了.


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

A:我会尝试使用请求库. /p>

I've got the following code:

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

For the sake of completeness, I'm adding the Python code:

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

It works flawlessly, but only 10% of the time. If I run it with a main like follows:

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

It works the first time. It gives me the output that I want, which is the data from the http request that is written in my Versions.py file, which the java code above calls. After the second time, it throws this massive error (which is 950 lines long, but of course, I won't torture you guys). Here's the gist of it:

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

My Python traceback that is supplied at the end of the 950 line Java stack trace is mostly this:

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

If anyone is curious, the seemingly offending line in my get_latest_version is just:

handler = urllib2.urlopen(request)

Since the server that the code is calling is being run (by cherrypy) on the localhost on my network, I can see how it is interacting with my server. It actually sends two requests (and throws the exception right after the second).

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"

While I'm never going to run this code in a loop likely, I'm quite curious as to two things:

  • Is the offending code my Python or Java code? Or could it just be an issue with Jython altogether?
  • What does the exception mean (it looks like a java exception)? Why is it being thrown when it is? Is there a way to make a loop like this work? Could this be written better?

解决方案

The python library urllib2, which you use, uses Netty.

Netty has a problem, which is widely known:

According to all of these links Netty HttpClient fails from time to time after closing. It looks like Netty recovers after some time and some applications work just normally with this problem. Anyway it looks unstable.


Q: Is the offending code my Python or Java code? Or could it just be an issue with Jython altogether?

A: The problem is caused by Jython library urllib2, which uses Netty.


Q: What does the exception mean (it looks like a java exception)? Why is it being thrown when it is?

A: urllib2 uses internally Netty. Netty is written in Java and throws this Java exception. Netty uses its own Thread Executor, which is shut down and unusable for some time after closing a request. You hit exactly this time.


Q: Is there a way to make a loop like this work? Could this be written better?

A: I would try to use Requests library.

这篇关于为什么此Jython循环一次运行后会失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆