Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 157604 - [Jobs] The following rule does not apply: Don't swallow InterruptedException. Call Thread.currentThread().interrupt()
Summary: [Jobs] The following rule does not apply: Don't swallow InterruptedException....
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Runtime (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: platform-runtime-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-09-17 23:35 EDT by Michael Scharf CLA
Modified: 2006-10-27 12:08 EDT (History)
9 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Scharf CLA 2006-09-17 23:35:21 EDT
I just blogged about the rule
  Don't swallow InterruptedException. Call Thread.currentThread().interrupt() instead.
  (http://michaelscharf.blogspot.com/2006/09/dont-swallow-interruptedexception-call.html)
It is based on a paper by Brian Goetz called "Dealing with InterruptedException" http://www-128.ibm.com/developerworks/java/library/j-jtp05236.html and the book "Java Concurrency in Practice" By BriaBrian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, and Doug Lea (http://www.amazon.com/exec/obidos/ASIN/0321349601/ref=nosim/none0b69).

However browsing the eclipse code (after publishing the blog entry :-/), I have the impression that InterruptedException are used differently and the above rule does not apply because I have seen only a few place where isInterrupted and interrupted is called....

Another indication is that org.eclipse.ui.examples.jobs the jobs do exactly the opposite of that recommendation: they call 
  try {
     Thread.sleep(sleep);
  } catch (InterruptedException e) {
     Thread.interrupted();
  }

Thread.interrupted is not needed anyway because an InterruptedException resets the interrupted state anyway. But that gives me an indication that the paradigms of the jobs framework and java (1.5) are fundamentally different.


I hope I am wrong and this bug will be marked invalid!
Comment 1 Boris Bokowski CLA 2006-09-18 00:18:58 EDT
Setting the bug description back to what it looked like before I added myself to the cc list.
Comment 2 Boris Bokowski CLA 2006-09-18 08:34:48 EDT
This looks like a bug in the example to me.  I believe the rule you quoted does apply.

BTW, if you frequently call operations that may throw InterruptedException, you don't need to check for isInterrupted(), assuming that you handle the exceptions appropriately by re-throwing or calling interrupt().
Comment 3 John Arthorne CLA 2006-09-18 12:17:35 EDT
I agree this just looks like a bug in the example code.  

However, it's worth noting that the Java interrupt mechanism is not generally used by Eclipse for handling cancelation (partly because it's so poorly specified that this is what it is intended for, and anyone could throw it for some other reason). Instead, Eclipse almost universally uses IProgressMonitor in long running or blocking operations where cancelation support is needed.

Eclipse does however use InterruptedException for a very special purpose within the UI thread.  If the UI thread is blocked, and a thread that owns some lock calls Display.syncExec, deadlock would be likely to occur.  The Eclipse workbench implementation of syncExec will interrupt the UI thread in this situation to break the deadlock.  Often the "correct" pattern in Eclipse when InterruptedException is encountered in the UI thread is like this:

while (true) {
   try {
      doSomeLongRunningOrBlockingWork();
      break;
   catch (InterruptedException e) {
      //someone may be trying to do a syncExec, so spin the event loop and retry
   }
   while (display.readAndDispatch()) {
      //spin the event loop until no more events
   }
}

This is fairly complicated, but if you're doing long running or blocking operations in the UI thread you're asking for trouble anyway.  This pattern is just used in the rare situations where it is not possible to fork the long running work into a non-UI thread.
Comment 4 John Arthorne CLA 2006-10-06 12:03:10 EDT
Example code fixed.
Comment 5 Michael Scharf CLA 2006-10-27 12:07:39 EDT
> However, it's worth noting that the Java interrupt mechanism is not generally
> used by Eclipse for handling cancelation (partly because it's so poorly
> specified that this is what it is intended for, and anyone could throw it for
> some other reason). Instead, Eclipse almost universally uses IProgressMonitor
> in long running or blocking operations where cancelation support is needed.

Unfortunately, Thread.interrupt() is the *only* way to terminate a blocking call (see bug 157604). A long running call that is in a blocking call cannot be canceled by IProgressMonitor, because Thread.interrupt() is not called.
Comment 6 Michael Scharf CLA 2006-10-27 12:08:33 EDT
oops, I mean see bug 162577