在 Jython 中捕获 java 异常



每当我的VNC连接被终止(每当我重新启动VM)时,我都会尝试捕获一个异常,并且我试图忽略它以继续我的Jython脚本。我不确定如何编写 try catch 语句来捕获异常,因为它源自 Java。这是针对 sikuliX 脚本的。

Exception in thread "Thread-7" com.tigervnc.rdr.EndOfStream: EndOfStream
at com.tigervnc.rdr.FdInStream.readWithTimeoutOrCallback(FdInStream.java:192)
at com.tigervnc.rdr.FdInStream.overrun(FdInStream.java:142)
at com.tigervnc.rdr.InStream.check(InStream.java:37)
at com.tigervnc.rdr.InStream.check(InStream.java:44)
at com.tigervnc.rdr.InStream.check(InStream.java:45)
at com.tigervnc.rdr.InStream.readS8(InStream.java:55)
at com.tigervnc.rdr.InStream.readU8(InStream.java:64)
at com.tigervnc.rfb.CMsgReaderV3.readMsg(CMsgReaderV3.java:50)
at com.tigervnc.rfb.CConnection.processMsg(CConnection.java:67)
at org.sikuli.vnc.VNCClient.processMessages(VNCClient.java:246)
at org.sikuli.vnc.VNCScreen$1.run(VNCScreen.java:82)
at java.lang.Thread.run(Unknown Source)

@abarnert 你真的救了我的一天。我遇到了与OP发布的相同问题。jython代码如下:

################################################################
#               CONFIG DEFINITIONS
################################################################
#GOOD_IMAGE_URL = "http://192.168.1.15/11111111.png"
BAD_IMAGE_URL = "http://192.168.1.15/111111112222.png"
def exceptionDemo(urlPath):
try:
print "exceptionDemo is starting"
myImg = imageio.ImageIO.read(URL(urlPath))
if myImg is None:
print "Img is None"
else:
print "Img is OK"
return myImg
#except Exception, err:
except java.lang.Exception as err:
print "Exception is here"
print err
finally:
print "Finally is here"

此代码的目的是下载 urlPath 指定的图像文件。 当 ulrPath 不好(在这种情况下,111111112222.png不存在)时,我想捕获异常以正确处理此问题。

如果我只是使用正常的"除了异常,错误"来捕获异常,程序将中止而没有任何信息。除了和最后部分中的打印语句应该执行,但是,这并没有发生。看到"异常演示正在启动"后,我得到的什么都没有。

我花了几天时间处理这个问题,一次又一次地在谷歌上搜索,不遗余力。经过几天的调查,我明白了,当你用jython编程时,有两种异常,一种是python异常,另一种是java异常。这个问题的原因是在这种情况下,jython或SikuliX已经抑制了java可抛掷对象。我对jython不是很熟悉,所以这只是我的猜测,还没有经过验证(我更熟悉原生的Python和Java)。

起初,我怀疑这是ImageIO - 本机Java包的问题。我写了一个简单的java演示来测试ImageIO,通过提供错误的图像url来测试ImageIO,它工作得很好,一个很好的"javax.imageio.IIOException:无法从URL获取输入流"被抛弃了。然后,我知道我的猜测是对的。java异常不知何故在jython或SikuliX中没有得到很好的处理。这里的重点是,即使这是根本原因,我仍然需要一种简单而优雅的方式来解决这个问题。我尝试了其他一些解决方法,但没有我预期的那么好。这个问题的本质部分不是下载图像,而是捕获异常。

直到我简单地将"except Exception, err"替换为"except java.lang.Exception as err",代码才像魅力一样工作。我得到了我期望的所有打印输出。

你的帖子真的救了我的一天。干得好,非常感谢。

以下参考资料对我的调查非常有帮助:
javax。ImageIO 方法在 Jython
https://www.jython.org/jythonbook/en/1.0/ExceptionHandlingDebug.html
中以静默方式
全面捕获异常

最后,如果我想向找到这篇文章的人提供任何提示,应该是">远离这种半生不熟的劣质混合语言",你既不会得到 Python 的权宜之计,也不会得到 Java 的健壮性,你最终唯一会得到的就是浪费你的时间。

=====================================================================================================================================================================================================

2019-08-02更新:

作为这篇文章的后续,我为您提供"买一送更多"的交易。它包含了Jython和Sikuli X给你带来的惊喜。

1、不要在Jython中使用任何依赖Netty的东西。这包括 httplib 和 urllib2 等。如果您尝试在循环中获取/发布某些内容,则使用请求或 java.net,它将失败。

有关详细信息,请参阅这篇文章:为什么这个 Jython 循环在单次运行后失败?

2、不要在 Sikuli X 中使用 type() 函数。这个函数通常在python中用于确定对象的类型,但是,Sikuli X使用它来模仿键盘输入函数。如果你坚持,你应该先导入内置,然后这样称呼它:

# -*- encoding: utf-8 -*-
import __builtin__
if __name__ == '__main__':
a=10
print __builtin__.type(a)

详情请参阅:

如何在Sikuli中使用"type"函数检查变量类型 https://answers.launchpad.net/sikuli/+question/239574

这些是我在jython和Sikuli X中遇到的一些陷阱,如果你必须处理这两件事,祝你好运,祝你玩得开心。

如异常处理和调试中所述,在 Jython 中处理 Java 异常的方式与处理 Python 异常的方式相同:

如前所述,在 Jython 中处理 Java 异常是一种常见的做法。通常,我们有一个抛出异常的Java类,这些异常可以在Jython中处理或显示,就像处理Python异常一样。

就您的代码而言,Java 例外只是某个Exception子类的实例。

当然,该子类恰好存在于例如java.lang而不是内置或其他stdlib模块中,并且它将(几乎?)在一直回到Exception之前始终将java.lang.Exception作为中间祖先,但通常,您不关心这一点。

因此,无论您在哪里调用引发此异常的 Java 代码......只需放置一个try:/except Exception as e:except java.lang.Exception as e:或更具体的类型,就像调用 Python 代码时一样。

最新更新