在 Jython 中捕获 java 异常

Catching java exception in Jython

每当我的 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.run(VNCScreen.java:82)
        at java.lang.Thread.run(Unknown Source)

Exception Handling and Debugging 中所述,您在 Jython 中处理 Java 异常的方式与处理 Python 异常的方式相同:

As stated previously, it is a common practice in Jython to handle Java exceptions. Oftentimes we have a Java class that throws exceptions, and these can be handled or displayed in Jython just the same way as handling Python exceptions.

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

当然,该子类恰好位于 java.lang 而不是内置模块或另一个 stdlib 模块中,并且它将(几乎?)始终将 java.lang.Exception 作为中间祖先,然后再获取所有回到 Exception 的方式,但通常,您不关心那个。

因此,无论您在何处调用抛出此异常的 Java 代码……只需输入 try: / except Exception as e:except java.lang.Exception as e: 或更具体的类型,与调用 Python 代码时的方式相同。

@abarnert 你真的救了我的命。我遇到了与 OP posted 相同的问题。 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"

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

如果我只是简单地使用正常的"except Exception, err"来捕获异常,程序将在没有任何信息的情况下中止。 except 和 finally 部分中的 print 语句应该执行,但是,这并没有发生。看到 "exceptionDemo is starting".

后我得到的是什么

我花了好几天时间来处理这个问题,在google上反复搜索,千方百计。经过几天的调查,我发现用jython编程时有两种异常,一种是python异常,另一种是java异常。这个问题的原因是在这种情况下,jython 或 SikuliX 抑制了 java throwables。我对jython不是很熟悉,所以这只是我的猜测,并没有得到验证(我更熟悉原生Python和Java)。

起初,我怀疑是 ImageIO - 本机 java 包的问题。我写了一个简单的 java 演示来测试 ImageIO,通过给坏图像 url,它工作得很好,一个很好的 "javax.imageio.IIOException: Can't get input stream from URL" 被扔掉了。然后,我知道我的猜测是对的。 java 异常在 jython 或 SikuliX 中没有得到很好的处理。这里的重点是,即使这是根本原因,我仍然需要一种简单而优雅的方法来处理这个问题。我尝试了其他一些解决方法,但没有什么比我预期的更好。这个问题的本质部分不是关于下载图像,而是关于捕获异常。

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

你的 post 真的帮了我大忙。干得好,非常感谢。

以下参考资料对我的调查很有帮助:
javax.ImageIO methods fail silently

https://www.jython.org/jythonbook/en/1.0/ExceptionHandlingDebug.html

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

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

2019-08-02更新:

作为此 post 的后续行动,我向您提供 "buy one get more free" 优惠。里面有Jython和Sikuli X给你带来的惊喜

1,不要在 Jython 中使用任何依赖于 Netty 的东西。这包括 httplib 和 urllib2 等。如果您尝试在循环中 GET/POST 某些东西,它将失败,请改用 Requests 或 java.net。

详情请参考这个post:

2、请勿在Sikuli X中使用type()函数。此函数通常在python中用于确定对象的类型,但是Sikuli X使用它来模拟键盘输入功能。如果你坚持,你应该先导入builtin,然后这样调用:

# -*- encoding: utf-8 -*-
import __builtin__

if __name__ == '__main__':
    a=10
    print __builtin__.type(a)

详情请参考:

How to check variable type using “type” function in Sikuli https://answers.launchpad.net/sikuli/+question/239574

这些是我在 jython 和 Sikuli X 中遇到的一些陷阱,如果你必须使用这两个东西,祝你好运,祝你玩得开心。