Saturday, October 30, 2010

Installing ING Home'Bank and Belgian eID on Ubuntu

I spend some time today upgrading my laptop from Ubuntu 9.04 (Jaunty Jackalope) to 10.04 LTS (Lucid Lynx) since 9.04 reached it's end of life earlier this month. Overall this was a very smooth process except for two specific apps that I require: ING Home'Bank and Belgian eID.

In an attempt to help people who also need to install one of these apps on a recent Ubuntu version, here is how I did it:

Home'Bank
ING is phasing out it's Home'Bank security module so the download is ages old and references a bunch of old libraries.

Start by downloading the HomeBank333.deb and simply install it as you would any other .deb. Next thing to do is pin the Home'Bank version in Synaptec to avoid this bug: 380511. To do that, start Synaptec, find the homebank package and select Package>Lock Version.

If you try to run /opt/HomeBank/HBSecurity, it will complain about 3 missing libraries:
  1. libtiff.so.3 is missing -- simply sym-link it:
    cd /usr/lib
    sudo ln -s libtiff.so.4 libtiff.so.3
  2. libexpat.so.0 is missing -- install and sym-link it:
    sudo apt-get install libexpat1
    cd /usr/lib
    sudo ln -s /lib/libexpat.so.1 libexpat.so.0
  3. libstdc++libc6.2-2.so.3 is missing -- this is an old Dapper Drake package that you can still download and install
Once these steps have been completed you should be able to run /opt/HomeBank/HBSecurity and start using Home'Bank.

Belgian eID
This is actually straightforward. A .deb package is provided for recent Ubuntu versions that installs and runs without any problems. The only problem on my machine was that my smart card reader was not being recognized (an Alcor Micro Corp. EMV Certified Smart Card Reader in my case -- do a lsusb in a terminal to find out what type of smart card reader you have). To rectify that, I had to install the libccid package:
sudo apt-get install libccid
Once that is done you can simply follow the install instructions provided in a PDF to configure your Firefox to use the new certificates and you should be up-and-running!

Thursday, October 7, 2010

ThreadLocal naming conventions

Since Sonar is now part of our normal build platform on the project I'm currently doing, we're keeping a close eye on the violations it identifies. One rule we violate in a couple of places is the CheckStyle constant naming rule. This rule simply says that the names of all static final variables should be ALL_UPPERCASE_WITH_UNDERSCORES. This is of course a well known Java coding convention. Still, it feels a little unnatural if you apply it to ThreadLocals, which are technically static final variables, but are neither immutable nor do they have a global scope like typical constants. This makes code using ThreadLocals look a bit weird if you use normal Java constant naming, e.g. compare the following:
private static final ThreadLocal<Date> TIME_FRAME = new ThreadLocal<Date>();
...
TIME_FRAME.set(myDate);
private static final ThreadLocal<Date> timeFrame = new ThreadLocal<Date>();
...
timeFrame.set(myDate);
For me using normal variable naming conventions for ThreadLocals seems to better communicate their role and intented usage in the code. Does anybody have an idea what the official Java naming conventions for ThreadLocals are?

Friday, August 27, 2010

Killer tool: Sonar

Today a colleague at work showed Sonar to me, and I must say that I was really impressed! Sonar is an open source code quality analysis tool that uses a number of popular Java code analyzers like PMD, CheckStyle, FindBugs and Cobertura under the hood, and presents the metrics calculated by all of these in a consistent and integrated way. It also keeps track of all the metrics data in a database so you can see how your code quality evolves.

One part of Sonar is a Web front-end for the metrics database, and the other part is a Maven plugin that runs all code analyzers and pumps the collected data into that database. (As an aside: imagine how much harder it would be to develop a tool like this if there wasn't a dominant build solution in the Java space like Maven.)


As a package Sonar just ticks all the right boxes. It's really easy to get up and running (starting its DB/Web server and running mvn clean install sonar:sonar in your Maven project is all there is to it), feels absolutely solid, has a friendly UI and looks very polished overall.

Warmly recommended!

Wednesday, July 21, 2010

How much damage can a Java Error do?

In Java there is a clear distinction between recoverable Exceptions and fatal Errors. It's common for applications to have a catch-all block so that they can continue running even if unexpected problems occur:
while (true) {
 try {
  // execute application logic
 } catch (Throwable t) {
  // log exception and/or display to the user
 }
}
This will catch both Exceptions and Errors. Although it's fine to catch an Exception and have the application carry on, this is typically not a good idea when an Error occurs!

I recently saw a bug in an application that caused a StackOverflowError. However, because of a catch-all block the application tried to recover from the problem and carry on. As it turns out this caused all kinds of instability and seemingly unrelated problems: connection leaks, ThreadLocal corruption and other such joys.

If you think about it this makes sense. A StackOverflowError indicates that the JVM ran out of stack space to properly invoke methods. Of course this has implications for things like finally blocks, and certainly for method invocations in those finally blocks! If you can no longer rely on the proper execution of your finally blocks you end up in a world of pain with things like messed up ThreadLocals. There are similar considerations for OutOfMemoryError and certainly for the other VirtualMachineErrors.

In summary: Errors can do a lot of damage! Don't keep the application running if you encounter an Error. Instead, try to log the problem and die. Only recover in case of Exceptions.
while (true) {
 try {
  // execute application logic
 } catch (Exception e)
  // log error and/or display to the user
  // => recover
 } catch (Error e) {
  // log error and/or display to the user
  // => exit JVM
 }
}

Tuesday, June 1, 2010

Bitemporality in Python

A few years ago I published a Java framework to deal with bitemporal issues in rich domain models. The code is freely available under a BSD style license.

As a first piece of non-trivial Python programming I coded up an equivalent framework in Python 2.5, available here. The framework allows you to set up a class with bitemporal properties that track the history and evolution of the value assigned to those properties. Here's a small example that should give you a feel for what you can do:
from bitemporal import *

class Person:

 def __init__(self, name):
  self.name = name
  self.address = BitemporalProperty()

p = Person("John Doe");
p.address.assign("Smallville", Interval(date(1975, 4, 3), date.max))
p.address.assign("Bigtown", Interval(date(1994, 8, 26), date.max))

print p.address.now() # Bigtown
print p.address.on(date(1980, 1, 1)) # Smallville

I'm looking for feedback on this code, which right now is only about 300 lines long. Is this code pythonic? Or is this Java-style Python code? If so, what areas need to be improved? Personally, I have doubts about at least a few things:
  • The type checks in the TimeFrame class (and a few other classes) feel iffy:
    @classmethod
    def set_reference(cls, value):
     if type(value) == date:
      cls.reference = datetime.combine(value, time())
     else:
      cls.reference = value
    
    But how else do I ensure that a timeframe always holds a datetime?
  • The BitemporalWrapper class feels Java-like. It decorates another object with bitemporal information and functionality. Is there a better way to do this in a dynamically typed language?
  • I considered using @property for the assign() method on the BitemporalProperty class, but the problem is that you often want to pass in a validity interval, which rules out use of "=".
Does anybody have any tips how this code can be improved?

Thursday, May 13, 2010

Python default argument madness

I've been learning python recently. I'm just getting started so I'm running into all the stupid beginner problems, for instance the insane behaviour of default argument values. Take this example:
from datetime import datetime
import time

class Weird:

 def __init__(self, dt = datetime.now()):
  self.dt = dt

w1 = Weird()
time.sleep(1)
w2 = Weird()
w3 = Weird(datetime.now())

print w1.dt == w2.dt # True
print w1.dt == w3.dt # False
The datetime in the w1 and w2 objects will actually be the same since the default argument value in the method definition is only evaluated once! What!?!? This essentially renders default arguments useless since you always end up writing the following:
class Weird:

 def __init__(self, dt = None):
  self.dt = dt or datetime.now()
I don't understand why you would design a default argument values features in your language like this. Doing it this way certainly violates the principle of least astonishment!

Saturday, May 1, 2010

What is good code?

As a project tech lead I do a lot of code review, so the "What is good code?" question comes up a lot. Of course there are many things that factor into the "good code" equation such as efficiency, correctness and elegance. For me the most important property of good code is that it should adhere to the principle of least astonishment. In other words: good code is code that does what you expect it to do in the way you expect it to be done.

Following this principle has important benefits when it comes to reading, understanding and maintaining a piece of code. It also typically improves the correctness of the code: you tend to get code that obviously has no deficiencies, in stead of no obvious deficiencies (as Tony Hoare said).

I was happy to learn that I'm in good company when it comes to attributing the principle of least astonishment to good code. Both Uncle Bob (in his excellent Clean Code book) and Peter Seibel (in his very interesting Coders at Work) ask several famous programmers about good code. A lot of the interviewees directly or indirectly mention the principle of least astonishment (for instance Ward Cunningham, Joe Armstrong and Simon Peyton Jones).