【发布时间】:2015-11-21 06:42:58
【问题描述】:
我有以下代码:
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% 的时间。如果我使用如下的 main 运行它:
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异常)?为什么它被抛出?有没有办法让这样的循环工作?能不能写得好一点?
【问题讨论】:
-
可能是您访问资源的速度太快了,在第一次调用
getVersion()时,您锁定了尚未释放的文件。您可以尝试在循环中的getVersion()之后调用Thread.sleep 或Thread.yield 吗? -
@DaedalusUsedPerl 我会尝试让线程休眠,你认为我应该这样做多久?也许 2-3 秒?
-
即使是一秒钟也可能是矫枉过正,但我不确定。尝试 2 并向上/向下调整以适应。
-
如果循环运行 20 次,它是否有 5% 的时间工作?这看起来像是解释器清理资源的问题。尝试将解释器设置为静态字段,然后不要调用 close。
-
@DaedalusUsedPerl 它并没有真正做任何事情,同样的结果。经过长达 5 秒的测试。
标签: java python loops exception-handling jython