2

I have an exception I'm trying to catch whenever my VNC connection is killed (whenever I restart my VM) and I'm trying to ignore it to continue my Jython script. I'm not sure how to write a try catch statement to catch the exception since it's originating from Java. This is for a sikuliX script.

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)
Dillon Miller
  • 763
  • 1
  • 6
  • 18

2 Answers2

4

@abarnert You really saved my day. I have encountered the same problem as OP posted. The jython code is as following:

################################################################
#               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"

the purpose of this code is to download the image file specified by urlPath. when the ulrPath is bad(in this case, the 111111112222.png does not exist.), I would like to catch the exception in order to handle this issue properly.

If I simply use the normal "except Exception, err" to catch the exception, the program will just abort without any information. The print statements in except and finally section are supposed to execute, however, that didn't happen. What I get is nothing after seeing "exceptionDemo is starting".

I spent days on dealing with this problem, searching on google again and again, leaving no stone unturned. After days of investigation, I get the idea that there are two sorts of exceptions when you programming in jython, one is python exception, the other is java exception. The reason for this problem is that either jython or SikuliX in this case, has suppressed the java throwables. I am not very familiar with jython, so it's just my guess and it has not been verified(I am more familiar with native Python and Java).

At first, I doubt it's ImageIO - the native java package's problem. I wrote a simple java demo to test ImageIO by giving the bad image url, it worked great, a nice "javax.imageio.IIOException: Can't get input stream from URL" had been thrown out. Then, I know that my guess is right. The java exception somehow did not well handled in jython or SikuliX. The point here is that even if this is the root cause, I still need a simple and elegent way to deal with this problem. I tried some other workarounds, but nothing is as good as I've expected. The essential part of this problem is not about downloading the image, it's about catching the exception.

It was not until I simply replace "except Exception, err“ with "except java.lang.Exception as err" that the code is working like a charm. I got all the printouts that I expected.

Your posts really saved my day. Good job and many thanks.

The following references are very helpful in my investigation:
javax.ImageIO methods fail silently
trap exceptions comprehensively in Jython
https://www.jython.org/jythonbook/en/1.0/ExceptionHandlingDebug.html

Finally, If there were any tips I would like to offer to people who find this post, it should be "STAY AWAY FROM THIS KIND OF HALF-BAKED SHODDY HYBRID LANGUAGE", You will get neither the expediency of Python, nor the robustness of Java, the only thing that you eventually will get is a big waste of your time.

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

Update on 2019-08-02:

As a follow-up of this post, I offer you a "buy one get more free" deal. It contains a heck of surprise brought you by Jython and Sikuli X.

1, DO NOT USE ANYTHING DEPENDS ON Netty in Jython. This includes httplib and urllib2, etc. It will fail if you try to GET/POST something in a loop, use Requests or java.net instead.

for details, please refer to this post: Why does this Jython loop fail after a single run?

2, DO NOT USE type() function in Sikuli X. This function is normally used in python to determine the type of an object, however, Sikuli X use it to mimic the keyboard input function. If you insist, you should import builtin first, then call it like this:

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

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

for details, please refer to these:

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

These are some pitfalls that I have experienced in jython and Sikuli X, if you have to work with these two things, good luck and wish you have fun.

shi jing
  • 64
  • 4
1

As explained in Exception Handling and Debugging, you handle Java exceptions in Jython the same way you handle Python exceptions:

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.

A Java exception is, as far as your code is concerned, just an instance of some Exception subclass.

Of course that subclass happens to live in, e.g., java.lang instead of builtins or another stdlib module, and it will (almost?) always have java.lang.Exception as an intermediate ancestor before getting all the way back to Exception, but generally, you don't care about that.

So, wherever you're calling the Java code that's throwing this exception… just put a try: / except Exception as e: or except java.lang.Exception as e: or more specific type, the same way you would when calling Python code.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • @DillonMiller I don’t know what you mean by that. If the top level of your program is in Python, you can put an exception handler at that level. If you’re starting your threads in Python, you can put an exception handler in the top-level thread func. And so on. It’s no different from what you’d do if there were no Java involved, and barely different from what you’d do in Java if there were no Jython involved. – abarnert May 25 '18 at 21:52
  • @DillonMiller I still don’t understand your question. If you catch it outside your `main` function and ignore it, that will _work_, but it doesn’t seem all that useful—after the `except: pass` your program just exits, right? Do you understand the basics of exception handling in either Python or Java? If not, you need to read a tutorial on that; the Jython-specific stuff of how Python can catch Java exceptions isn’t the hard part; it’s the trivial part. – abarnert May 25 '18 at 21:56