Saturday, September 16, 2006

Don't swallow InterruptedException. Call Thread.currentThread().interrupt() instead.

Have you ever written the following code?
try {
doSomething();
} catch(InterruptedException swallowed) {
// BAD BAD PRACTICE, TO IGNORE THIS EXCEPTION
// just logging is also not a useful option here....
}

I have! I newer knew what the heck to do with those annoying InterruptedException when I simply wanted to call Thread.sleep(..). What is this InterruptedException? Why is it thrown? Why can't I ignore it?

Before I explain the whys, here is what you should do (if you don't re-throw):
try {
doSomething();
} catch(InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}


What is the InterruptedException?

There is no way to simply stop a running thread in java (don't even consider using the deprecated method stop()). Stopping threads is cooperative in java. Calling Thread.interrupt() is a way to tell the thread to stop what it is doing. If the thread is in a blocking call, the blocking call will throw an InterruptedException, otherwise the interrupted flag of the tread will be set. A Thread or a Runnable that is interruptable should check from time to time Thread.currentThread().isInterrupted(). If it returns true, cleanup and return.

Why is it InterruptedException thrown?

The problem is that blocking calls like sleep() and wait(), can take very long till the check can be done. Therefore they throw an InterruptedException. However the isInterrupted is cleared when the InterruptedException is thrown! (I have some vague idea why this is the case, but for whatever reason this is done, that is how it is!)

Why can't InterruptedException be simply ignored?

It should be clear by now: because ignoring an InterruptedException means resetting the interrupted status of the thread. For example, worker threads take runnable from a queue and execute they may check the interrupted status periodically. If you swallow it the thread would not know that it was interrupted and would happily continue to run.

Some more thoughts
Unfortunately it is not specified that Thread.interrupt() can only be used for cancellation. It can be used for anything that requires to set a flag on a thread. So, ending your task or runnable early might be the wrong choice, if the interrupted status is used for something else. But common practice is to use it for cancellation. But even if it is used for something else, you code does not have the right to reset the interrupt flag (unless you are the owner of the thread).

To learn more read the nice article Dealing with InterruptedException by Brian Goetz.

Or read Java Concurrency in Practice By BriaBrian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, and Doug Lea. It's a great book! If you program in java 5 this book is a must read!. I bought the book after I read Brians artikle. I have not yet read the entire book, but what I have read impresses me. It gives a lot of theorie and options. Very competent and complete, but I'm missing a set of simple patterns for concurrent programming. I'm looking forward to Doug Leas 3rd edition of Concurrent Programming in Java

Summary: If you don't know what to do with an InterruptedException call Thread.currentThread().interrupt()

Sunday, September 10, 2006

Pitfalls of Long.parseLong/Long.decode...

What is wrong with this code?
assert 0x0cc175b9c0f1b6a8L == Long.parseLong("0cc175b9c0f1b6a8",16);
assert 0xd41d8cd98f00b204L == Long.parseLong("d41d8cd98f00b204",16);
The second Long.parseLong will fail in the second line:
java.lang.NumberFormatException: For input string: "d41d8cd98f00b204"
The reason is that javas long is signed, but 0xd41d8cd98f00b204L is an unsigned long. Interesting, but annoying, if you want to parse an unsigned long in java. It makes Parsing and verifying hex, octal and decimal numbers more complicated, if you have a field that represents a C/C++ unsigned long (a 64 bit number)....

The solution is to use BigInteger:
assert 0x0cc175b9c0f1b6a8L == new BigInteger("0cc175b9c0f1b6a8",16).longValue();
assert 0xd41d8cd98f00b204L == new BigInteger("d41d8cd98f00b204",16).longValue();
However, you must ensure that the BigInteger does not exceed 64 bits. So here's my unsigned long parser
public static long parseUnsignedLong(String s, int radix) 
throws NumberFormatException {
BigInteger b= new BigInteger(s,radix);
if(b.bitLength()>64)
throw new NumberFormatException(s+" is to big!");
return b.longValue();
}
Note: if you want to do any kind arithmetic with unsigned longs (like min/max checking) you have to use BigInteger objects.... Unless you are only interested in the bits of the long, the return value of my parseUnsignedLong is not really useful: it should better return the BigInteger!

Thursday, September 07, 2006

The Dependency Injection Pattern: an alternative to Factories and Service Locators

On my vacation I listened to about 30 pod-casts. Although most of what I heard was not new, it still was a good refresher and exciting to listen to. It also inspired me to order a few books and make me think more about what I am doing as software engineer.

One pattern that was new to me is Dependency Injection. It was mentioned in software engineering radio Episode 2 on Dependencies. Instead of using a Factory or a Service Locator (like OSGi), make your class have some members referring to the interfaces it uses. The Dependency Injector then uses either the constructor or some set methods to provide your class with the implementations of the classes your object needs. Read the One minute description and the Two Minute Tutorial of PicoContainer (a nice little Dependency Injection Framework) to see what I mean.

Martin Fowler wrote a long article about Inversion of Control Containers and the Dependency Injection pattern.

I was always wondering why using interfaces when you have only one implementation of the interface anyway. So, why bother? With Dependency Injection you can test your object easyly using Mock Objects. Jeremy Weiskotten wrote an Dr.Dobb's Article on why Dependency Injection is very helpful to create testable and decoupled objects.

Dependency Injection makes it very clear which interfaces your objects depend on. This makes refactoring, testing and understanding code easier. Factories and Service Locators often provide more products than needed by a single class and therefore you cannot really tell what the class depends on.

I'll play with Dependency Injection :-)

Monday, August 21, 2006

Going on vacation with a mp3 player full of geek pod-casts...

I'm going on vacation for two weeks to Athens and Crete. My wife is Greek and therefore we go every summer to Greece. Going on vacation also means no laptop (that's not my deceison ;-). So usually, I take some geek books with me. This time I loaded my mp3 player with the 9 Callisto pod-casts from Eclipse Zone and a few of the Software Engineering Radio pod-casts.
I tried it on Friday. It's a almost like being in a conference call. But it's better: I can wind back if I get sidetracked and I don't have to be afraid that suddenly someone says: "And Michael, what do you think?....". I was shopping and listening to Richard Gromback on GMF. I was waiting in the queue to pay and when it was my turn, I started talking in English to the German cashier -- lost in cyberspace...

One thing I think pod-casts should do: Please say at the beginning of the pod-cast when it was recorded! If someone says: "Next month we'll release foobar..." it is annoying not to know when next month is or was...

And now, relaaaaaxxx, summer, sun, beach, fun -- for 2 weeks -- I'll be back Sep.5 late afternoon....

Friday, August 18, 2006

Blog comments, my mistakes and good feedback...

Marko Schulz asked me why his comments did not appear in my blog. I checked it and I realized that I had a setup problem with my blog (my mistake). Now all comments are visible and new comments will be shown automatically! I'll check them for spam later.

Here's what I learned from the comments:
I checked all comments and I found a few spams, but most comments brought up valid points. Thank you for your feedback!

Thursday, August 17, 2006

MDSD/MDA framework openArchitectureWare 4.1 is available at eclipse.org

I just read the announcement that openArchitectureWare 4.1 is available. openArchitectureWare is hosted at eclipse.org/gmt/oaw. It is one of the coolest projects at eclipse.org but it seems not to get much attention. If you are interested in MDSD or MDA take a look at openArchitectureWare - openArchitectureWare is really cool!

Parsing and verifying hex, octal and decimal numbers...

How to parse a number that might be octal, decimal or hexadecimal. Numbers like 0xFF, 0x1e, 077, -123, -0x12, -066. This must have been solved a million times, and here's my version:

Thank you for all the comments! My code is stupid! Use Long.decode(numberString).longValue() Instead!
String sign="";
int base=10;
if(numberString.startsWith("-")) {
sign="-";
numberString=numberString.substring(1);
}
if(numberString.startsWith("0x")) {
numberString=numberString.substring(2);
base=16;
} else if(numberString.startsWith("0") && numberString.length()>1) {
numberString=numberString.substring(1);
base=8;
}
return Long.parseLong(sign+numberString,base);


OK, and here is my VerifyListener:
class NumberVerifyer implements VerifyListener {
final boolean fSigned;
NumberVerifyer(boolean signed) {
fSigned=signed;
}
public void verifyText(VerifyEvent e) {
Text text = ((Text)e.widget);
StringBuffer fulltext = new StringBuffer(text.getText());
fulltext.replace(e.start, e.end, e.text);
String sign=""; //$NON-NLS-1$
if(fSigned)
sign="-?"; //$NON-NLS-1$
e.doit = fulltext.toString().matches(sign+"(0?|[1-9][0-9]*|0x[0-9a-fA-F]*|0[0-7]+)"); //$NON-NLS-1$
}
}

Wednesday, August 16, 2006

Vote for the eclipse 3.3 release train name. Europa is a bad choice!

Vote for the Eclipse Release Train Name (2007). There has been some discussions in bugzilla.

I think Europa is a very bad choice for two reasons:

1. There are too many Google hits already if you search for eclipse europa.

2. In many languages Europa means Europe and this will confuse. Messages like the "Europa Build Workshop", sounds for many non-native speakers like "The Build Workshop Europe". If English is your native language, you might not understand this point, but for Germans this is very confusing. For the same reason you would not call a workshop held in the nice Austrian village called Fucking the "Fucking Workshop" ;-)....

Tuesday, August 15, 2006

Am I the only person having problems with the update manager?

I wonder if I am the only person in the world using the update manager and having problems. Two weeks ago I reported a real show-stopper update manager bug: Update does not work if *ANY* error is found in configuration. I expected that it would be marked as a duplicate but I seem to be the only person having the problem. I cannot finish the updates dialog because of some mysterious errors:



The annoying thing is that "Manage Configuration" seems happy and shows no error:



The error is caused by some installed features that require a specific version of a plugin.

<?xml version="1.0" encoding="UTF-8"?>
<feature id="broken.feature" label="Broken Feature" version="1.0.0">
<description>.</description><copyright>.</copyright>
<license>.</license>
<requires>
<import feature="org.eclipse.platform" version="3.1.2" match="perfect"/>
</requires>
</feature>


What puzzles me the most is not the bug itself, but the fact I seem to be the only one getting the bug (I get it with 3.2 and 3.3M1).....

If you want to try it, just unzip this feature in your eclipse/feature directory and restart eclipse and try to install a feature using the update manager.

Workarounds
Fix the feature.xml file by removing the required version string.
Or use another working eclipse installation and install the plugins into a new extension location and add the extension location to your eclipse using "Manage Configuration".

Update manager battle: the players Yoxos - YUM - eclipse...

Yoxos

I am very frustrated with the eclipse update manager. In my opinion, it is simply unusable. But what are the alternatives? A few weeks ago, I bought a 1 year subscription of yoxos for $99. Unfortunately, since then, no new updates appeared on my yoxos update manager. The yoxos update manager is quite cool. It's a perspective that allows you to select the plugins you want:



This looks very much like the yoxos on demand site (yes, this is a screenshot of an ajax application!):



I don't know how it works, when new updates are available, but I expect it will work smoothly (well, I payed for it -- therefore it has to work ;-))


TUM - Tikal Update Manager

TUM (Tikal Update Manager) is a open source project forge project called tikal run by Tikal.

They create a dialog with some cool icons. Yoxos seems much more mature, but TUM was just announced....



The Eclipse Update Manager

The eclipse update manager seems also to be enhanced. I have not seen it (because I hope for yoxos to install it for me...), but the screenshots seem promising.



The battle shall start...

I really hope that finally the update manager gets more attention. My favorite is clearly yoxos, because they don't use annoying blocking dialogs, but a perspective. The funny thing is, that eclipse 1 used a perspective as well, and in eclipse 2 it became wizard based...