Tuesday, February 28, 2012

Static imports in Eclipse

When working with testing frameworks such as Junit and Mockito, static imports are quite common. However, Eclipse does not handle those so well when pressing Ctrl+Enter, if they are not already imported. To hint Eclipse of which classes you want to look in for static imports, this handy trick could be useful: under
Java->Editor->Content Assist->Favorites
Choose new Type... and add org.mockito.Mockito and the other classes from which you need static methods.

Thanks to http://piotrjagielski.com/blog/working-with-static-imports-in-eclipse/

Friday, February 24, 2012

An embarrassing NullPointerException

I did a classical mistake today, yet it took me long enough to find the error. I got a NullPointerException on the following method call (somewhat simplified):
myMethod(myObject.getId());
I was totally sure myObject was not null, and even though I knew that the id was null I didn't bother as that should not be a problem...until I checked the method signature of myMethod:
public void myMethod(long value) {...}
As it takes a primitive long as argument, and myObject's id was the object Long, an implicit conversion is made in the calling moment, so the real code looks like:
myMethod(myObject.getId().longValue());
I'm a fan of auto-boxing and -unboxing, but sometimes I obviously have to be a little more observant.

Templating in Eclipse

A great but underused feature in Eclipse (and most other IDE:s) is code templates. I am often declaring a logger member variable which looks like this:
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
To make this easier, I can create a template, by going to Window->Preferences, Java->Editor->Templates->New...
I fill in a shortcut, for example log, choose "Java Type Members" in the context select box, a short description and then in the "pattern" textarea I write:
private static final Logger LOG = LoggerFactory.getLogger(${enclosing_type}.class);

Now when I write log followed by Ctrl+Enter, I get the whole thing written for me.

Bean properties with the second letter uppercased

The Java bean specification lacks details in some areas, and how to handle properties with an initial lower case letter followed by an upper case letter is one of those (i.e aProperty). The problem appears when trying to create a getter for a property like this. Should it be called getAProperty or getaProperty?

It turns out that best practice seems to be to call it getaProperty, because of the special handling of properties with two leading upper case letters (See section 8.8 in the specification). GetAProperty could translate to the (approved) property name AProperty, because if a name has two leading upper case letters they are left untouched. Unfortunately, not all tools handle this equally, so JAXB for example creates the getter getAProperty from a schema property aProperty, while jersey/jackson does it right, making interoperabililty difficult.

My recommendation therefore is to avoid this kind of naming alltogether, to avoid those problems.

Thursday, February 23, 2012

JacksonJsonProvider, java.util.Date and java.sql.Date

Today I had a wonderful problem related to the different date objects in Java. I had made the mistake using rs.getDate() to get a date from the database, not realizing that I lose the time part in doing so. It however became apparent to me in an unusual way:

The problem I had was that an object like this
public MyObj {
  java.util.Date myDate; 
}
was serialized by Jackson to a date string "2012-01-05", without the time.

Everywhere I read it said that java.util.Date in Jackson is serialized using unix timestamp, so I did not understand from where this formatted string came. I dug a bit in the serialization process in Jackson and I saw that it was using a SqlDateSerializer to serialize the Date, which I found strange.

I then realized that when fetching the date from the database, I iterated through a ResultSet and set myDate using
myObj.setMyDate(rs.getDate("MY_DATE"));
, which of course is a big no-no. Not only do I lose the time part, but as java.sql.Date inherits from java.util.Date (thanks, jdbc designers) I get a creepy java.sql.Date object in myObj. This in turn caused Jackson to use the SqlDateSerializer, which serialize the dates as strings without time, which I am now happy for, as it made finding out what was wrong a little easier.

So the solution became quite simple; I instead used a method which null-checked rs.getTimestamp() and created my own real java.util.Date-object using
new java.util.Date(timestamp).

Monday, April 11, 2011

Commit shortcut in Eclipse

Problem:
In a vanilla installation of Eclipse + Subclipse, some of the team keyboard shortcuts, such as Commit (SVN), no longer works.
Solution:
Windows->Customize Perspective
Under the tab "Command Groups Availability", check "SVN".