3 March 2010

Java Calendar API - A misleading piece of software


Today I found a bug in a software module which was caused by the misleading Calendar API of Java regarding the method called before. Of course if the author of the code would have considered the API documentation where the behavior is well described this bug could have been prevented. But the method seems absolutely simple that I would not have read the API documentation neither.


Here comes the code in which the bug was located

public boolean isPasswordExpired(Date lastPwdChange,
  boolean isPwdChangeNeeded) {
 boolean pwdExpired = false;
 if (getMaxValidityTime() > 0 && lastPwdChange != null) {
  Calendar calendar = Calendar.getInstance();
  calendar.setTime(lastPwdChange);
  calendar.add(Calendar.DAY_OF_YEAR, getMaxValidityTime());
  log.debug("Password must not be older than " + getMaxValidityTime() + " days");
  pwdExpired = calendar.before(new Date()); // <-- here comes the BUG!
 }
 return pwdExpired || isPwdChangeNeeded;
}

isPasswordExpired checks if a password has expired. The bug is located at calendar.before(new Date()) where the before method of a java.util.Calendar gets called. Since the parameter of before is a java.lang.Object actually everything can be used to call before. In this example the parameter is a java.util.Date. This looks quiet straight forward, does it? But its oh so wrong!


The API documentation describes it as follows:
if and only if when is a Calendar instance. Otherwise, the method returns false.
Since this feature 'A password can expire' has not been used until now and the code has not been covered by unit tests :( this malfunction has not been detected yet.