Search code examples
javaawtinterruptawtrobot

Is there a graceful way to preserve interrupt status when it's reset by private source code?


I'm using the Robot class to perform mouse functions in my program, however I've encountered an issue with it swallowing the InterruptedException and printing the stack trace. This is not good because I need the interrupted status to be preserved.

I've found the issue occurs specifically in the delay() function of the Robot class, which is called internally:

public synchronized void delay(int ms) {
    checkDelayArgument(ms);
    try {
        Thread.sleep(ms);
    } catch (InterruptedException ite) {
        ite.printStackTrace();
    }
}

The function is public so I was able to create a custom class that extends Robot and override this method to include Thread.currentThread.interrupt(); in the catch block, however I consider this a nasty hack which may have repercussions. Is there a better way to handle this issue?


Solution

  • This looks like this JDK bug report and note these dev mail comments here.

    If you view JDK17 source code you'll see a different implementation which does not lose the status of the interrupt, though because of backward compatibility the original InterruptedException is lost:

    public void delay(int ms) {
        checkDelayArgument(ms);
        Thread thread = Thread.currentThread();
        if (!thread.isInterrupted()) {
            try {
                Thread.sleep(ms);
            } catch (final InterruptedException ignored) {
                thread.interrupt(); // Preserve interrupt status
            }
        }
    }
    

    If you are not able to update to a later JDK it looks like you may as well call Thread.sleep(ms); and handle the exception in your own code.