Aug 25 2010

[Unit Testing]: Time zone and stuff…

Do you know those nasty time zone related bugs, too?
They are quite common – but often they are discovered when it is too late. Often every developer and tester lives in the same time zone. So sometimes the software is never ever run in a different time zone until it is shipped…

The problem

The idea of time zones makes calculating with dates/times really difficult.
But probably we have to live with them for a few more years…

So as developers we have to handle them properly.

And handling them properly means two things

Using a nice API

I am certain that it is impossible to write bug free code using just the standard Calendar stuff.
Maybe James Gosling is able to do that – but I even doubt that…

So just use one of those APIs that work. My personal favorite is Joda Time. Many cases then just work.

Testing time zones

As soon as your software handles dates/times it is necessary to test that code.
But my experience shows that hardly anybody tests anything that needs a lot of work to test. And changing the time zone manually needs some (too much?) work.

The solution

JUnit offers rules. Very simple but powerful feature. I have created several custom rules that make live much easier…

And I have created a timezone rule (based on Joda Time) that allows me to run my unit tests in different time zones.
Here it comes:

import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.joda.time.DateTimeZone;
import org.junit.rules.*;
import org.junit.runners.model.*;

/**
* Rule that sets the TimeZone
*
* @author Johannes Schneider (js@cedarsoft.com)
*/
public class DateTimeZoneRule implements MethodRule {
@NotNull
protected final DateTimeZone zone;

public DateTimeZoneRule() throws IllegalArgumentException {
this( "America/New_York" );
}

public DateTimeZoneRule( @NotNull @NonNls String zoneId ) throws IllegalArgumentException {
this( DateTimeZone.forID( zoneId ) );
}

public DateTimeZoneRule( @NotNull DateTimeZone zone ) {
this.zone = zone;
}

private DateTimeZone oldTimeZone;

@Override
public Statement apply( final Statement base, FrameworkMethod method, Object target ) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
before();
try {
base.evaluate();
} finally {
after();
}
}
};
}

private void before() {
oldTimeZone = DateTimeZone.getDefault();
DateTimeZone.setDefault( zone );
}

private void after() {
DateTimeZone.setDefault( oldTimeZone );
}

@NotNull
public DateTimeZone getZone() {
return zone;
}

@NotNull
public DateTimeZone getOldTimeZone() {
if ( oldTimeZone == null ) {
throw new IllegalStateException( "No old zone set" );
}
return oldTimeZone;
}
}

No magic, nothing special, no rocket science.

Just start using rules – if will change the world into a better place…


Aug 24 2010

JUnit: Rules

JUnit has a nice feature now: Rules.
While I don’t like every detail of the implementation, they are basically a very good thing.

This is a short introduction how to use them…

What are rules

Rules are basically wrappers around test methods. They offer a nice way to prepare before a test run and clean up afterwards.
Basically they replace that awful setup/tearDown method stuff…

How to use them

Just create a public (non-static) field for the rule. And add the annotation @Rule.

Example

One of my favorite rules is TemporaryFolder. That rule creates a temporary folder and an easy way to create files and folders…

public class RulesTest {
@Rule
public TemporaryFolder tmp = new TemporaryFolder();

@Test
public void testIt() throws IOException {
  System.out.println( "Creating tmp folder @ " + tmp.newFolder( "aFolder" ).getAbsolutePath() );
  assertTrue( tmp.newFile( "a file" ).exists() );
}
}

The output of this test is (at least on my system):

Creating tmp folder @ /tmp/junit8120700871928645940/aFolder

What to do now?

1. Create a template for your IDE that adds the rule field…

It really is worth it. Please. I know the human being tries to avoid the initial setup costs (of maybe 3 minutes) and prefers to type the same lines several hundred times…

2. Enjoy writing Unit tests (again)

No more long and ugly setup/tearDown methods. No more files accidentally left in the tmp folder…

In the next posts I will show you some more rules that I find very useful….


Aug 7 2010

[Maven + Git] Releasing and Branching done right…

Maven is really awful. I hate it.

But it is by far the best tool available… Therefore I am using it for several years now. And since it is a tool one has to struggle with, I have invested a lot of time into optimizing my build environment. So I know Maven quite well now – better than I wanted…

And of course I am using Git. And I really love it. But unfortunately Git is just a second class citizen in Maven land. The basic things work, but other things don’t (like mvn release:branch).

I have created this checklist for doing a release. Just take a look and compare it with the steps you are doing. I’d like to hear some opinions and ideas for improvements.

Small scripts

I use some scripts that make my life easier:

The setup

The version numbers

The upcoming release will be 1.0.0 (the first release for this project). Therefore no maintenance branches exist yet.

Currently the master branch is set to 1.0.0-SNAPSHOT.

The branches

Branch Description
master Contains the current development version (that will be released as next major release).

(I have an additional pu branch that is merged to master automatically when all tests have been run successfully, but that doesn’t matter for this entry)

next Contains some experimental code (that will be merged to master one day)
maint-[VERSION] Maintenance branches for every version. Just bugfixes are commited here and merged up.

Release: What has to be done

The master branch contains the latest peace of software that shall be released (that means that all bugfixes have been merged in from the maint* branches).

  • Tag for the release
  • Creating a new maint-* branch with updated version number
  • Updating the version number for master
  • Probably updated the version number for next, too

And: Of course release one version of our software…

The Checklist

1: Ensure all bugfixes have been merged into master

git log master..maint-[VERSION]

2: Creating the maint-branch

git checkout master
git checkout -b maint-1.0.0
git publish-branch

3: Releasing on maint

mvn release:prepare
mvn release:perform

4: Merging maint to master

git checkout master
git merge maint-1.0.0

5: Updating the version on master

mvn versions:set -DnewVersion=1.1.0-SNAPSHOT -DgenerateBackupPoms=false
git commit -a -m "preparing for next major release: updated version in master"

6: Merging master to next

git checkout next
git merge master

That merge has probably one merge conflict: The version in the pom.xml. Just keep the value of the next branch.

7: Updating the version for next (optional/if necessary)

mvn versions:set -DnewVersion=2.0.0-SNAPSHOT -DgenerateBackupPoms=false
git commit -a -m "preparing release: updated version in next"

8: Pushing the changes

git push

The result

Now there are three branches with different version numbers:

Branch Version
maint-1.0.0 1.0.1-SNAPSHOT
master 1.1.0-SNAPSHOT
next 2.0.0-SNAPSHOT

Aug 6 2010

Code Generation done right…

Code Generation solves a lot of problems. And everybody uses it all the day: Ever generated Getters/Setters using your IDE? Or method stubs? Or constructors?

And sometimes complete classes are generated. One famous example is Hibernate that is able to generate Java classes from a database schema.

Most of the projects I have seen so far use a templating engine (FreeMarker or Velocity) to create the source files. Hibernate switched from Velocity to FreeMarker some years ago…

This approach is quite good for simple cases. Those can be solved quite fast using that approach.

Complexity

But things get worse, if you have to generate more sophisticated code. Of course FreeMarker supports conditions and you can do quite amazing things using complex model classes. On the other hand those templates start to get really complicated and hard to debug over time.
And of course you always have two sources: The template file and your data model.

Imports

One thing special to Java source files are the imports. When you conditionally use a class somewhere, you also have to add the import statement conditionally… Nothing that can be solved easily using FreeMarker.

So sometimes one might wish to have a nice API that does all the dirty work for you…

The alternative: Codemodel

I have looked around to find such an API. And it took me quite a long time to find one.
And that API is quite near beside you. Just a little bit hidden.

JAXB has a sub project called codemodel. This is an API that allows you to create Java classes by just using an API…

How to use Codemodel

There is no separate jar for codemodel. But the classes are shipped with every JAXB installation. So since JDK 1.6 the classes are just here and waiting to be used. But since they have renamed the package as “internal” I suggest to import the JAXB jar manually:

For Maven users this should be enough:

<dependency>
  <groupId>com.sun.xml.bind</groupId>
  <artifactId>jaxb-xjc</artifactId>
  <version>2.2.1</version>
</dependency>

A quick introduction

The API is not perfect yet. And it is not documented very well. But it is nearly complete and I didn’t miss much.
Here is a short example that should give you a fast start:

JCodeModel codeModel = new JCodeModel();
JDefinedClass foo = codeModel._class( "a.b.c.Foo" ); //Creates a new class

JMethod method = foo.method( JMod.PUBLIC, Void.TYPE, "doFoo" ); //Adds a method to the class
method.body()._return( JExpr.lit( 42 ) ); //the return statement

The code can be written to the file system. But it can also be written to a single output stream. This is great for testing:

ByteArrayOutputStream out = new ByteArrayOutputStream();
codeModel.build( new SingleStreamCodeWriter( out ) );

This code outputs that code:

-----------------------------------a.b.c.Foo.java-----------------------------------

package a.b.c;

public class Foo {

public void doFoo() {
return 42;
}

}

Great, isn’t it?


Aug 5 2010

Java Surprise: Setters/Getters and Collections

Inspired by the Java Killers series, I wanted to post a problem I stumbled across some years ago:

Imagine a bean containing a field.

class Car {
private final List tires = new ArrayList();

public void setTires( List tires ) {
this.tires.clear();
this.tires.addAll( tires );
}

public void addTire( Tire tires ) {
this.tires.add( tires );
}

public List getTires() {
return Collections.unmodifiableList( tires );
}
}

What is the output of that code?

Car car = new Car();
car.addTire( new Tire() );
car.addTire( new Tire() );

List carTires = car.getTires();
System.out.println( "before: " + carTires.size() );
car.setTires( carTires );
System.out.println( "after1: " + car.getTires().size() );
System.out.println( "after2: " + carTires.size() );

The first part is easy:

before: 2

But the rest?

Continue reading