Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

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.



30 December 2009

Top 5 Java tools I need to work

The year 2009 is ending. Time to reflect about my set of tools for Java development at COR&FJA.


IntelliJ IDEA
IntelliJ IDEA 9 Ultimate is a very good commercial IDE for Java professionals. It has outstanding support for Groovy and Grails development. Since version 9.0 IDEA comes in two different editions. The community edition is open source and free to use. The ultimate edition is the commercial release of IDEA.

dbUnit
dbUnit helps you writing integration tests which require a database. It lets you define specific dataset which can be added to the database before your tests start and removed after your tests have been completed.
A few months ago I started to use dbUnit as a database migration tool. I had the task to migrate a MySQL database to an Oracle database. After some research I decided to export the MySQL schema and importing it to Oracle using dbUnit. Well it perfectly worked out.

JIRA
After using JTrac and Mantis my employer finally decided to use JIRA as standard issue tracker. In my opinion JIRA is in a professional environment the Rolls Royce of issue trackers. Well at least in comparison with JTrac and Mantis :)

Hudson
After using Cruise Control I am really happy to have met Hudson. Setting up Hudson really is quick and easy. A simple setup wont take you more than five minutes. Comparing to Cruise Control this is a BIG plus and finally there is no bloody XML configration anymore.

Grails
It's the end of 2009. I am still a big Grails fan (as you probably have noticed). Grails is a wonderful web framework based on Groovy, Spring, Hibernate and Sitemesh which helps you to build web applications as fast as possible. Few days ago Grails 1.2 has been released.


Well these are the tools I personally like most. What tools do you like? Happy new year everyone!

8 December 2009

Unexpected behaviour of ArrayLists size method

Today I just learned something more about Javas ArrayList and my Debugger after an half an hour of trying to find out what is wrong with my code.
I had the strange situtation that the debugger told me that my list contained 6 elements but the size method of that list returned a value of 7 (see figure below). Apparently the ArrayList accepts null values without complaining about it and these null values are going to modify the size of the list but the debugger - in the case the debugger of IntelliJ IDEA 9 RC1 - filters null values and does not display them.




With the following listing you can reproduce this behaviour using IntelliJ IDEA (or your prefered IDE).

import java.util.ArrayList;
import java.util.List;

public class FunnyLists
{
   public static void main(String[] args)
   {
      List<String>
 list = new ArrayList<String>();
      list.add("Hello");
      list.add(null);
      list.add("World");        

      System.out.println("Size: " + list.size());

      for(String element : list) {
         System.out.println("Element: " + element);
      }
   }
}



This listing generates the following output:
Size: 3


Element: Hello
Element: null
Element: World

27 May 2009

SCJP - Now it gets strange

Which two about using the java.io.Serializable class are true? (Choose two.)

A) If Dog extends Animal, then Animal must implement java.io.Serializable in order to serialize an instance of Dog.
B) If Dog has-a Collar, then Collar must implement java.io.Serializable in order to serialize an instance of Dog.
C) If Dog extends Animal and Animal implements java.io.Serializable but Dog does NOT implement java.io.Serializable, you can serialize an instance of Dog.
D) When an instance of a subclass is deserialized, none of the constructors in it's constructor chain will ever be invoked.
E) If you mark a class's instance variable volatile, and then serialize an instance of that class, the state of the volatile variable will be lost during serialization.

Sun's says: Options B and C are correct. A class's superclasses don't have to implement Serializable in order to be serialized, and if a superclass doesn't implement Serializable then it's constructor will run during deserialization. A transient variable's state is lost during serialization, but a volatile variable's state is not lost.
I really do agree with option C but cannot understand why option B should be absolutely right. I still can serialize the Dog instance even if the included Collar does not implement Serializable. I could mark the Collar instance variable transient and everyone would be happy at runtime.

Becoming a Sun certified Java programmer or how to become a compiler

The next two weeks I am trying to prepare myself to Sun's certified Java programmer (SCJP) exam. Up to now it really does not kick ass. Well my main troubles with the studies are currently some topics in the exam objective 3.5 (Tokenizing).

Objective 3.5 - Tokenizing with Pattern and Matcher
Let's say there's the pattern 'a?' and we would like to tokenize the following string 'aba' using the following Java class.

public static void main(String[] args) {
Pattern p = Pattern.compile("a?"); // compile the pattern
Matcher m = p.matcher("aba");

while (m.find()) {
System.out.println(m.start() + " >" + m.group() + "<");
}
}

What I expected out of this listing was something like this.
0 >a< 
2 >a< 
But what it actually returns was this.
0 >a< 
1 >< 
2 >a< 
3 >< 
Mhm. According to my study book (from which I took this example) they talking about some zero-length matches when using the greedy quantifiers '*' or '?'. They say that zero-length matches can appear under the following circumstances.
  • After the last character of source data
  • In between characters after a match has been found
  • At the beginning of source data (if the first character is not a match. Try tokenizing this string '2aba')
  • At the beginning of zero-length source data
Well this rules seems to be regular expression specific and does not have anything to do with the Java implementation. The only funny thing is - I use RegEx Buddy to develop my regexes - that I cannot reproduce it in my favourite regex editor. Yet another topic to learn by rote (means not really understanding it but memorize it for the exams purpose only)

27 December 2007

Internationalisierung mit dem Spring Framework

Das Spring Framework bietet einen einfachen Mechanismus um Applikationen zu internationalisieren (I18N) ohne die sprachspezifischen Texte in den Sourcecode einbetten und somit bei Änderungen erneut kompilieren zu müssen. Mittels der Klasse ReloadableResourceBundleMessageSource können die sprachspezifischen Texte in Java Properties Dateien ausgelagert werden. Die Klasse bietet, wie es ihr Namen schon verspricht, das Erkennen von Änderungen, die zur Laufzeit in der Properties Datei gemacht werden, an die Applikation weiterzuleiten.

Als erstes benötigt man die angesprochene Properties Datei, in diesem Beispiel hat sie den Dateinamen meinePropertyDatei.properties und enthält zwei Properties namens login.username und login.password. Diese beiden Properties Einträge dienen bspw. als Textinhalte für Masken, auf welchen ein Login durchgeführt wird.
Nachfolgend sind zwei Properties Dateien abgebildet. Einmal die erwähnte meinePropertyDatei.properties, welche als Basis Datei dient und dann eine Property Datei namen meinePropertyDatei_DE.properties, welche Texte in deutscher Sprache beinhaltet. Wie dieser Postfix im Dateinamen durch Spring behandelt wird, möchte ich zu einem späteren Zeitpunkt in diesem Artikel erklären.

[meinePropertyDatei.properties]

1. login.username=Please enter your username
2. login.password=Please enter your password


[meinePropertyDatei_DE.properties]

1. login.username=Bitte geben Sie Ihren Benutzernamen ein
2. login.password=Bitte geben Sie Ihr Passwort ein


Um die Klasse ReloadableResourceBundleMessageSource in der eigenen Applikation via Spring verwenden zu können, muss diese im ApplicationContext vermerkt werden. Dabei gibt man den Dateinamen der Basis Properties Datei meinePropertyDatei.properties ohne Dateiendung (und ohne Postfix) an.

[spring.xml]

1. <bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
2. <property name="basenames">
3. <list>
4. <value>meinePropertyDatei</value>
5. </list>
6. </property>
7. </bean>


Damit man nun aus der Applikation auf die Properties Datei bzw. deren Textinhalte zugreifen kann, muss man in der entsprechenden Klasse nur die Interfaceklasse MessageSourceAware implementieren.

[HibernateUserService.java]

1. public class HibernateUserService implements MessageSourceAware {
2.
3. private MessageSource messageSource;
4.
5. public void setMessageSource(MessageSource messageSource) {
6. this.messageSource = messageSource;
7. }
8.
9. public void printStuff() {
10. System.out.println("Username Text: "
+ messageSource.getMessage("login.username", null, null));
11. System.out.println("Password Text: "
+ messageSource.getMessage("login.password", null, null));
12. System.out.println("Deutscher Benutzername Text: "
+ messageSource.getMessage("login.username", null, Locale.GERMAN));
13. System.out.println("Deutscher Passwort Text: "
+ messageSource.getMessage("login.password", null, Locale.GERMAN));
14. }
15.}


Nun muss man die Klasse HibernateUserService nur noch dem Spring Context bekannt machen.

[spring.xml]

1. <bean name="userService"
class="ch.minsight.core.java.services.HibernateUserService" />


Wenn man nun das Bean userService via dem Spring Application Context anfordert wird die MessageSource automatisch in die Instanz von HibernateUserService implantiert. Dies nennt man ein sogenanntes 'Autowiring', da Spring automatisch erkennt, dass HibernateUserService eine MessageSource benötigt und somit das Bean mit der ID 'messageSource' übergibt. Wie man aus dem Java Sourcecode entnehmen kann, können die Texte unter Bekanntgabe der jeweiligen Locale, sprachabhängig ausgelesen werden.

23 December 2007

TeamCity 3.0 - Ein weiteres kostenloses Continous Integration Tool steht zur Verfügung

Praktisch zur gleichen Zeit wie IntelliJ IDEA 7.0 veröffentlich wurde, haben die Entwickler von JetBrains das Continuous Integration Tool TeamCity 3.0 freigegeben. Bisher habe ich jeweils mit CruiseControl(.NET) in Projekten gearbeitet, bin aber seit dem Erwerb von IntelliJ IDEA 7.0 auf TeamCity aufmerksam geworden. Es wird in einer Professional und Enterprise Edition angeboten, wobei die erstere Version kostenlos ist und sich laut JetBrains für kleinere und mittlere Entwicklungsunternehmen eignet. In dieser Version können 20 Softwareprojekte parallel verwaltet werden. Ausserdem können maximal 20 Anwender in TeamCity festgelegt werden. Dies sind aber bereits die einzigen Einschränkungen, welche in der Professional Edition hingenommen werden müssen. Eine Auflistung aller Features von TeamCity findet man hier.

Im direkten Vergleich mit CruiseControl sticht einem die relativ simple und GUI-unterstützte Konfiguration ins Auge, welche ermöglicht, dass sich der Administrator nicht mit einem XML Konfigurationsdokument à la CruiseControl auseinandersetzen muss. Ferner steht für die gängigen IDEs ein Plug-in für TeamCity zur Verfügung, mit welchem man das Continous Integration Tool aus der Entwicklungsumgebung steuern kann.

TeamCity 3.0 ist als Windows Installer, Mac OS X und Linux Setup verfügbar, welches jeweils mit einem integrierten Apache Tomcat mitgeliefert wird. Alternativ steht einem ein Web Application Archive (WAR) für ein Deployment auf einem eigenständigen Application Server.

TeamCity 3.0 macht mir nach ersten kleinen Tests einen sehr ausgereiften Eindruck. Es macht richtiggehend Spass mit TeamCity zu arbeiten, da alles sehr einfach zu konfigurieren ist.