为什么这个 Jython 循环在单个 运行 后失败?
Why does this Jython loop fail after a single run?
我有以下代码:
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
我的 Python 在 950 行 Java 堆栈跟踪末尾提供的回溯主要是这样的:
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
有个问题,广为人知:
- Hopper: java.util.concurrent.RejectedExecutionException: event executor terminated
- Error recurrent : DefaultPromise Failed to notify a listener. Event loop shut down?
- Calling HttpClient.shutdown() causes problem to later created clients
- Shutting down netty 4 application throws RejectedExecutionException
根据所有这些链接 Netty
HttpClient
关闭后有时会失败。看起来 Netty
会在一段时间后恢复,并且一些应用程序可以正常运行这个问题。反正看起来不稳定
问:违规代码是我的 Python 还是 Java 代码?还是完全是 Jython 的问题?
答:问题是由 Jython 库 urllib2
引起的,它使用了 Netty
.
问:异常是什么意思(看起来像java异常)?为什么它被抛出?
答:urllib2
内部使用 Netty
。 Netty
写在Java里面,抛出这个Java异常。 Netty
使用自己的Thread Executor,在关闭一个请求后,会在一段时间内关闭并且无法使用。这次你正好击中了。
问:有没有办法让这样的循环工作?这个能写的更好吗?
答:我会尝试使用 Requests 库。
尝试在每次创建解释器时为其提供一个全新初始化的系统状态:
PySystemState.initialize();
PythonInterpreter interpreter = new PythonInterpreter(null, new PySystemState());
我有以下代码:
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
我的 Python 在 950 行 Java 堆栈跟踪末尾提供的回溯主要是这样的:
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
有个问题,广为人知:
- Hopper: java.util.concurrent.RejectedExecutionException: event executor terminated
- Error recurrent : DefaultPromise Failed to notify a listener. Event loop shut down?
- Calling HttpClient.shutdown() causes problem to later created clients
- Shutting down netty 4 application throws RejectedExecutionException
根据所有这些链接 Netty
HttpClient
关闭后有时会失败。看起来 Netty
会在一段时间后恢复,并且一些应用程序可以正常运行这个问题。反正看起来不稳定
问:违规代码是我的 Python 还是 Java 代码?还是完全是 Jython 的问题?
答:问题是由 Jython 库 urllib2
引起的,它使用了 Netty
.
问:异常是什么意思(看起来像java异常)?为什么它被抛出?
答:urllib2
内部使用 Netty
。 Netty
写在Java里面,抛出这个Java异常。 Netty
使用自己的Thread Executor,在关闭一个请求后,会在一段时间内关闭并且无法使用。这次你正好击中了。
问:有没有办法让这样的循环工作?这个能写的更好吗?
答:我会尝试使用 Requests 库。
尝试在每次创建解释器时为其提供一个全新初始化的系统状态:
PySystemState.initialize();
PythonInterpreter interpreter = new PythonInterpreter(null, new PySystemState());