15 August 2009

Type Parameters and Reflection

Last week I had an opportunity to participate in the development of XMAdsl, an Xtext based model driven development extension of openXMA. In the new release we want to use Value Objects for all relevant values. E.g. the birth date of a person should not be an arbitrary java.util.Date, but a specific BirthDateValue instance. The Value Object hierarchy looks like that:
abstract class ValueObject<T> {
private final T value;
public ValueObject(T pValue) {
value = pValue;
}
// shortened for brevity...
}

class ValueObjectDate extends ValueObject<Date> {
public ValueObjectDate(Date pDate) {
super((Date) pDate.clone()); // Date is mutable
}
// shortened for brevity...
}

class BirthDateValue extends ValueObjectDate {
public BirthDateValue(Date pValue) {
super(pValue);
}
}
ValueObject, ValueObjectDate and all other Value Object base classes are packaged in the platform used by the generator. BirthDateValue and all other concrete subclasses are generated depending on the model. Such method signatures are more readable and passing a date of payment as a birth date by accident gets impossible. (Value Objects have other advantages, e.g. being read only, but that's not the point here.)

Reflection PoolAll Value Objects use the ValueObjectType Hibernate User Type for persistence. Obviously the User Type has to know the type of the Value Object to create new instances and the type of the value inside it to map it onto the database column. But how to get the inner type? Our first approach was to configure it. As the Hibernate configuration is generated as well, that's no big deal. Nevertheless it's a bit lame and definitely not DRY.

So the question is how to find the type parameter of a generic super class. In the given case the inner value is passed as constructor argument, so we can easily do better using reflection on the constructor parameter:
for (Constructor<?> c : pValue.getConstructors()) {
if (c.getParameterTypes().length == 1) {
return c.getParameterTypes()[0];
}
}
// throw an exception
Nice. That fixed our problem but made me think further. What if there would would be no method or field with the concrete type of the type parameter, e.g. when using collections as super classes and not defining any new methods? It's also possible to find the type using reflection:
public Class<?> findType(Class<?> pValue) {
if (pValue == Object.class) {
// throw an exception
}

// is it generic itself?
if (pValue.getTypeParameters().length > 0) {
return (Class<?>) pValue.getTypeParameters()[0].getBounds()[0];
}

// is the super class typed?
if (pValue.getSuperclass().getTypeParameters().length > 0) {
Type superClass = pValue.getGenericSuperclass();
ParameterizedType type = (ParameterizedType) superClass;
return (Class<?>) type.getActualTypeArguments()[0];
}

// go up to super class
return findType(pValue.getSuperclass());
}
A class knows if it's super class had type parameters using getGenericSuperclass(). If the class has a type parameter itself we don't know it due to erasure, but at least we get its lower bound. In all other cases we go up the class hierarchy. Finally a little test if it works as expected...
@Test
public void testFindType() {
assertSame(Date.class,
userType.findType(ValueObjectDate.class));
assertSame(Date.class,
userType.findType(BirthDateValue.class));
}

18 July 2009

Holiday Blues

Holidays in Greece: Chilling out in the sun, spending time with the family, having some rest and much free time. Time to think about my job, my life and the whole universe ;-) However too much thinking makes me sad...

Greek Beach It has been more than half a year now that I have left Herold for good. In the end work there got quite boring and some things really sucked. But after staying there for five years the development team became my family. My bond with my colleagues kept me from leaving earlier and made it a really hard decision when the time for something new had finally come. I still remember them and from time to time I suffer moments of painful memories. I do not know how it came to be like that. There were no activities together, no common hobbies to talk about, even no geek interests to compete in. We did not meet after work or go out for a beer together, at least not more than once or twice a year.

Nevertheless I am thinking of them: Alex making his acrid remarks; Andreas refreshing me with new ideas, that always seemed to be much too revolutionary; Anton, although we hardly talked to each other; Ben making us play network games after work; Claudia my "soul-sister"; Claudio, exchanging stories about our misbehaving sons during lunch break; Dominik, always calm and relaxed; Martina having much too much energy; Petra; Richard testing a new database tool each week; Ronnie; Sylvi; Tim making me laugh about all his carpenter jokes; and Vero, the caring soul of the team, although she could really be mean sometimes.

My dear colleagues I miss you.

3 June 2009

Practical Unit Testing

In the beginning of June I gave a presentation about practical unit testing with JUnit at the Java Student User Group in Vienna. JSUG is a small group of dedicated students that formed last year. The scope was practical as well as pragmatic - in fact just bits of information I considered useful for the daily development. It was good to see young developers that are eager to write tests. I hope when they are thrown into legacy code later in their career that their principles will not just crumble.

Download the Practical Unit Testing presentation slides.

Projector: Capitol Theatre in WestbankResources used in the slides:
This section contains links to topics I talked about. I give a list of all my sources. Hopefully Google does not punish me for creating this link-farm like page ;-)

JUnit basics used sources from Unit testing (Wikipedia), JUnit.org & JUnit, Early look at JUnit 4, Design to Unit Test, Test-driven design, Part 1 & Part 2; Checkstyle, FindBugs and PMD.

The mocking chapter used sources from jMock, EasyMock (Easier testing with EasyMock), Initializing bean using EasyMock, Mocking & Spring, Oh no, we're testing the Mock! and the Law Of Demeter.

Singletons are a pain for testing: Patterns I Hate, Singletons Are Evil and Why Singletons are Evil, Refactor singleton, Test flexibly with AspectJ and mock objects with AspectJ and the Google Singleton Detector.

There are some tools to help testing J2EE apps: HtmlUnit/HttpUnit, HttpClient, Testing Servlets and ServletUnit, Jetty, Cactus, Simple-JNDI, MockEJB and ActiveMQ.

Tuning the tests means often tuning the database: DbUnit, H2 and HSQLDB.

The Code Coverage chapter talks about EMMA (EclEmma), Cobertura, Agitar but Don't be fooled by the coverage report, Crap4j, Testability Explorer.

A new trend is testing with scripts: Unit test your Java code faster with Groovy or Using JRuby for Java testing, RSpec, JRuby, JtestR and ScalaCheck/Specs.

Finally some cool tools for testing and the build are JUnitPerf, SWTBot, XmlUnit, Distributed JUnit and GridGain.