January 18, 2011

Hibernate hbm2ddl won't create schema before creating tables

Situation

I have a local H2 in memory database for integration tests and an Oracle db for production. I do not control the Oracle DB model. The in memory H2 database is created automatically by adding

<prop key="hibernate.hbm2ddl.auto">update</prop>

to hibernate properties in AnnotationSessionFactoryBean. The definition of the entity stored in DB points to a schema

@Entity
@Table(name = "business_operations", schema = "sowa")
public class BusinessOperation {
...


The problem

When creating the H2 database, Hibernate won't create the schema before creating tables. As a result it will show errors when trying to create the tables in non existing schema and fail in any query (queries will be run with sowa.business_operations).

2011-01-18 15:13:30,884 INFO [org.hibernate.tool.hbm2ddl.SchemaUpdate] - Running hbm2ddl schema update
2011-01-18 15:13:30,885 INFO [org.hibernate.tool.hbm2ddl.SchemaUpdate] - fetching database metadata
2011-01-18 15:13:30,915 INFO [org.hibernate.tool.hbm2ddl.SchemaUpdate] - updating schema
2011-01-18 15:13:30,927 INFO [org.hibernate.tool.hbm2ddl.DatabaseMetadata] - table not found: business_operations
2011-01-18 15:13:30,941 ERROR [org.hibernate.tool.hbm2ddl.SchemaUpdate] - Unsuccessful: create table sowa.business_operations 
2011-01-18 15:13:30,942 ERROR [org.hibernate.tool.hbm2ddl.SchemaUpdate] - 
Schema "SOWA" not found;

Turns out this bug is reported and open since 2006: link.


The solution

The solution to this problem is to create the schema before hibernate's hbm2ddl turns on. That would be easy with H2 if we could tell H2 to initialize itself like this:

database.url=jdbc:h2:mem:;INIT=RUNSCRIPT FROM 'src/main/resources/scripts/create.sql';

All seems nice, except H2 RUNSCRIPT FROM command doesn't work with relative resources as you may expect. Fortunatelly INIT allows us to give any commands, not just point to a script, so this little change will solve the problem:

database.url=jdbc:h2:mem:;INIT=create schema IF NOT EXISTS sowa 

Yeah, I know it's obvious and simple stupid, but looking at all the questions on all the mailing lists in google I may have just saved a little bit of somebody's time.

October 31, 2010

Google Guava v07 examples

We have something called Weekly Technology Workshops at TouK, that is, every Friday at 16:00 somebody has a presentation for everyone willing to come. We present stuff we learn and work on at home, but we also have a bulletin board with topics that people would like to listen about. Last week Maciej Próchniak had a talk about Clojure, this time a few folks asked for an introduction to Google Guava libraries.

Since this was a dead simple task, I was happy to deliver.

WTF is Guava?

It's a set of very simple, basic classes, that you end up writing yourself anyway. Think in terms of Apache commons, just by Google. Just to make your life a little bit easier.

There is an early (v04) presentation and there was a different one (in Polish) at Javarsowia 2010 by Wiktor Gworek.

At the time of writing this, the latest version is v07, it's been mavenized and is available at a public maven repo.

Here's a quick review of a few interesting things. Don't expect anything fancy though, Guava is very BASIC.

@VisibleForTesting


A simple annotation that tells you why a particular property access restriction has been relaxed.

A common trick to use in testing is to relax access restrictions to default for a particular property, so that you can use it in a unit test, which resides in the same package (though in different catalog). Whether you thing it's good or bad, remember to give a hint about that to the developer.

Consider:

public class User {
    private Long id;
    private String firstName;
    private String lastName;
    String login; 
 Why is login package scoped?

public class User {
    private Long id;
    private String firstName;
    private String lastName;
    @VisibleForTesting String login;
Ah, that's why.

Preconditions


Guava has a few preconditions for defensive programming (Design By Contract), but they are not quite as good as what Apache Commons / Spring framework has. One thing interesting is that Guava solution returns the object, so could be inlined. Consider:

Using hand written preconditions:
public User(Long id, String firstName, String lastName, String login) {
        validateParameters(id, firstName, lastName, login);
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.login = login.toLowerCase();
    }

    private void validateParameters(Long id, String firstName, String lastName, String login) {
        if(id == null ) {
            throw new IllegalArgumentException("id cannot be null");
        }

        if(firstName == null || firstName.length() == 0) {
            throw new IllegalArgumentException("firstName cannot be empty");
        }

        if(lastName == null || lastName.length() == 0) {
            throw new IllegalArgumentException("lastName cannot be empty");
        }

        if(login == null || login.length() == 0) {
            throw new IllegalArgumentException("login cannot be empty");
        }
    } 

Using guava preconditions:
public void fullyImplementedGuavaConstructorWouldBe(Long id, String firstName, String lastName, String login) {
        this.id = checkNotNull(id);
        this.firstName = checkNotNull(firstName);
        this.lastName = checkNotNull(lastName);
        this.login = checkNotNull(login);

        checkArgument(firstName.length() > 0);
        checkArgument(lastName.length() > 0);
        checkArgument(login.length() > 0);
    }
(Thanks Yom for noticing that checkNotNull must go before checkArgument, though it makes it a bit unintuitive)

Using spring or apache commons preconditions (the use looks exactly the same for both libraries):
public void springConstructorWouldBe(Long id, String firstName, String lastName, String login) {
        notNull(id); hasText(firstName); hasText(lastName); hasText(login);
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.login = login;
    } 


CharMatcher

For people who hate regexp or just want a simple and good looking object style pattern matching solution.

Examples:

And/or ease of use

        String input = "This invoice has an id of 192/10/10";
        CharMatcher charMatcher = CharMatcher.DIGIT.or(CharMatcher.is('/'));
        String output = charMatcher.retainFrom(input);
 output is: 192/10/10

Negation:
        String input = "DO NOT scream at me!";
        CharMatcher charMatcher = CharMatcher.JAVA_LOWER_CASE.or(CharMatcher.WHITESPACE).negate();
        String output = charMatcher.retainFrom(input);
 output is: DONOT!

Ranges:
        String input = "DO NOT scream at me!";
        CharMatcher charMatcher = CharMatcher.inRange('m', 's').or(CharMatcher.is('a').or(CharMatcher.WHITESPACE));
        String output = charMatcher.retainFrom(input);
output is: sram a m

Joiner / Splitter

As the names suggest, it's string joining/splitting done the right way, although I find the inversion of calls a bit... oh well, it's java.
        String[] fantasyGenres = {"Space Opera", "Horror", "Magic realism", "Religion"};
        String joined = Joiner.on(", ").join(fantasyGenres);
Output: Space Opera, Horror, Magic realism, Religion

You can skip nulls:
        String[] fantasyGenres = {"Space Opera", null, "Horror", "Magic realism", null, "Religion"};
        String joined = Joiner.on(", ").skipNulls().join(fantasyGenres);
Output: Space Opera, Horror, Magic realism, Religion

You can fill nulls:
        String[] fantasyGenres = {"Space Opera", null, "Horror", "Magic realism", null, "Religion"};
        String joined = Joiner.on(", ").useForNull("NULL!!!").join(fantasyGenres);
Output: Space Opera, NULL!!!, Horror, Magic realism, NULL!!!, Religion

You can join maps
        Map<Integer, String> map = newHashMap();
        map.put(1, "Space Opera");
        map.put(2, "Horror");
        map.put(3, "Magic realism");
        String joined = Joiner.on(", ").withKeyValueSeparator(" -> ").join(map);
Output: 1 → Space Opera, 2 → Horror, 3 → Magic realism

Split returns Iterable instead of JDK arrays:
        String input = "Some very stupid data with ids of invoces like 121432, 3436534 and 8989898 inside";
        Iterable<String> splitted = Splitter.on(" ").split(input);
Split does fixed length splitting, although you cannot give a different length for each “column” which makes it's use a bit limited while parsing some badly exported excels.
        String input =
                "A  1  1  1  1\n" +
                "B  1  2  2  2\n" +
                "C  1  2  3  3\n" +
                "D  1  2  5  3\n" +
                "E  3  2  5  4\n" +
                "F  3  3  7  5\n" +
                "G  3  3  7  5\n" +
                "H  3  3  9  7";
        Iterable<String> splitted = Splitter.fixedLength(3).trimResults().split(input);
You can use CharMatcher while splitting
        String input = "Some very stupid data with ids of invoces like 123231/fv/10/2010, 123231/fv/10/2010 and 123231/fv/10/2010";
        Iterable<String> splitted = Splitter.on(CharMatcher.DIGIT.negate())
                                            .trimResults()
                                            .omitEmptyStrings()
                                            .split(input);


Predicates / Functions

Predicates alone are not much, it's just an interface with a method that returns true, but if you combine predicates with functions and Collections2 (a guava class that simplifies working on collections), you get a nice tool in your toolbox.

But let's start with basic predicate use. Imagine we want to find whether there are users who have logins with digits inside. The inocation would be (returns boolean):
Predicates.in(users).apply(shouldNotHaveDigitsInLoginPredicate);
And the predicate looks like that
public class ShouldNotHaveDigitsInLoginPredicate implements Predicate<User> {
    @Override
    public boolean apply(User user) {
        checkNotNull(user);
        return CharMatcher.DIGIT.retainFrom(user.login).length() == 0;
    }    
}       
Now lets add a function that will transform a user to his full name:
public class FullNameFunction implements Function<User, String> {
    @Override
    public String apply(User user) {
        checkNotNull(user);
        return user.getFirstName() + " " + user.getLastName();
    }    
}
You can invoke it using static method transform:
List<User> users = newArrayList(new User(1L, "sylwek", "stall", "rambo"),
  new User(2L, "arnold", "schwartz", "commando"));

List<String> fullNames = transform(users, new FullNameFunction()); 
And now lets combine predicates with functions to print names of users that have logins which do not contain digits:
List<User> users = newArrayList(new User(1L, "sylwek", "stall", "rambo"), 
  new User(2L, "arnold", "schwartz", "commando"), 
  new User(3L, "hans", "kloss", "jw23"));

Collection<User> usersWithoutDigitsInLogin = filter(users, new ShouldNotHaveDigitsInLoginPredicate());
String names = Joiner.on("\n").join( transform(usersWithoutDigitsInLogin, new FullNameFunction()) );

What we do not get: fold (reduce) and tuples. Oh well, you'd probably turn to Java Functional Library anyway, if you wanted functions in Java, right?

CaseFormat

Ever wanted to turn those ugly PHP Pear names into nice java/cpp style with one liner? No? Well, anyway, you can:
String pearPhpName = "Really_Fucked_Up_PHP_PearConvention_That_Looks_UGLY_because_of_no_NAMESPACES";
String javaAndCPPName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL , pearPhpName);
Output: ReallyFuckedUpPhpPearconventionThatLooksUglyBecauseOfNoNamespaces

But since Oracle has taken over Sun, you may actually want to turn those into sql style, right?
        String sqlName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, javaAndCPPName); 
Output: really_fucked_up_php_pearconvention_that_looks_ugly_because_of_no_namespaces

Collections

Guava has a superset of Google collections library 1.0, and this indeed is a very good reason to include this dependency in your poms. I won't even try to describe all the features, but just to point out a few nice things:
  • you have an Immutable version of pretty much everything
  • you get a few nice static and statically typed methods on common types like Lists, Sets, Maps, ObjectArrays, which include:
    • easy way of creating based on return type: e.g. newArrayList
    • transform (way to apply functions that returns Immutable version)
    • partition (paging)
    • reverse
And now for a few more interesting collections.


Mutlimaps

Mutlimap is basically a map that can have many values for a single key. Ever had to create a Map<T1, Set<T2>> in your code? You don't have to anymore.

Multimap<Integer, String> multimap = HashMultimap.create();
        multimap.put(1, "a");
        multimap.put(2, "b");
        multimap.put(3, "c");
        multimap.put(1, "a2"); 
There are of course immutable implementations as well: ImmutableListMultimap, ImmutableSetMultomap, etc.

You can construct immutables either in line (up to 5 elements) or using a builder:
Multimap<Integer, String> multimap = ImmutableSetMultimap.of(1, "a", 2, "b", 3, "c", 1, "a2"); 
Multimap<Integer, String> multimap = new ImmutableSetMultimap.Builder<Integer, String>()
        .put(1, "a")
        .put(2, "b")
        .put(3, "c")
        .put(1, "a2")
        .build();

BiMap

BiMap is a map that have only unique values. Consider this:
@Test(expected = IllegalArgumentException.class)
public void biMapShouldOnlyHaveUniqueValues() {
 BiMap<Integer, String> biMap = HashBiMap.create();
 biMap.put(1, "a");
 biMap.put(2, "b");
 biMap.put(3, "a"); //argh! an exception
} 
That allows you to inverse the map, so the values become key and the other way around:
BiMap<Integer, String> biMap = HashBiMap.create();
biMap.put(1, "a");
biMap.put(2, "b");
biMap.put(3, "c");

BiMap<String, Integer> invertedMap = biMap.inverse();
Not sure what I'd actually want to use it for.

Constraints

This allows you to add constraint checking on a collection, so that only values which pass the constraint may be added.

Imagine we want a collections of users with first letter 'r' in their logins.
Constraint<User> loginMustStartWithR = new Constraint<User>() {
    @Override
    public User checkElement(User user) {
        checkNotNull(user);
        
        if(!user.login.startsWith("r")) {
            throw new IllegalArgumentException("GTFO, you are not Rrrrrrrrr");
        }

        return user;
    }
};    
And now for a test:
@Test(expected = IllegalArgumentException.class)
public void shouldConstraintCollection() {
 //given
 Collection<User> users = newArrayList(new User(1L, "john", "rambo", "rambo"));
 Collection<User> usersThatStartWithR = constrainedCollection(users, loginMustStartWithR);

 //when
 usersThatStartWithR.add(new User(2L, "arnold", "schwarz", "commando"));
}
You also get notNull constraint out of the box:
//notice it's not an IllegalArgumentException :( 
@Test(expected = NullPointerException.class)
public void notNullConstraintShouldWork() {
 //given
 Collection<Integer> users = newArrayList(1);
 Collection<Integer> notNullCollection = constrainedCollection(users, notNull());

 //when
 notNullCollection.add(null);
} 
Thing to remember: constraints are not checking the data already present in a collection.

Tables

Just as expected, a table is a collection with columns, rows and values. No more Map<T1, Map<T2, T3>> I guess. The usage is simple and you can transpose:
Table<Integer, String, String> table = HashBasedTable.create();
table.put(1, "a", "1a");
table.put(1, "b", "1b");
table.put(2, "a", "2a");
table.put(2, "b", "2b");

Table transponedTable = Tables.transpose(table);
That's all, folks. I didn't present util.concurent, primitives, io and net packages, but you probably already know what to expect.

October 17, 2010

Java Developers' Day 2010 review

On the 7-8th of October 2010, Cracow held Java Developers' Day conference. This year it was two days long, so I guess they'll have to think about changing the name. My expectations weren't very high. First of all, I've heard an opinion that JDD is getting worse every year. Second, for the same price as GeeCON you got only one track. Third some of the lectures seemed really uninspiring.

For example, I was afraid, that the one about Flex is going to be the same one I've seen on 4Developers, half a year ago in Poznań. And, of course, there was the one most controversial to all the people I had a chance speaking with, the sponsored lecture from Wipro Technologies, titled: “Wipro in Europe and development opportunities on Polish market”.

Doesn't sound like something you'd like to listen to on a Java conference, does it? More like an advertisement, to me.

Fortunately, my doubts were mostly unfounded.

The first day started a little earlier than planned, with Bill Burke talk about RESTful Java. Quite nice, I must say, as long as you have no idea what REST means, as half of the lecture was very basic. The other part was about JAX-RS (and RESTEasy implementation), and that's where it got my attention. I haven't had a chance to use JAX-RS yet, but the simplicity and efficiency of it is very appealing. I'll have to give it a shot, especially when .NET/Java web service integration is sometimes very painful.

The second talk,  “Java programming in days of multi-core processors”, by Angelika Langer, was gorgeous. Maybe it's because of my limited experience in concurrency, maybe because Angelika presented a more in-depth view on the things happening under the hood, than I am used to, and maybe because she threw away the incorrect model most books present. What I'm sure about, is that Angelika is a great trainer and speaker, with vast knowledge and expertise.  It was a pure pleasure to listen to her and I can only hope to be so passionate and sharp at her age.

Not that she's that old, mind you. It's just that terms like “burned-out” and “tired” do not seem to have anything to do with her.


Then there was Jarosław Błąd from e-point, talking about performance tests in JEE. That was also quite nice, though a little too basic. I wish the speaker could show us a little more real case scenarios and stories, as it was obvious he had a lot of interesting thoughts on that matter, but probably because of NDAs, he decided to go with more theoretical and generic information instead. Anyway, this was a sponsored talk done right. Thanks e-point for not leaving us with just advertisements.

After the lunch came the hit of the day, Ted Neward talk about functional programming for busy developer. A few slides passed by, when Ted asked the audience, whether we would rather see presentation or life coding. Guess what the answer was.

The great thing about the lecture was that Ted didn't use anything more than standard Java, to show us the benefits of thinking in terms of functional languages. The examples were practical, with stuff you can really find from time to time in your code, and the advantages clear and explicit. Somewhere in the middle of the show, Ted said, that he wants us to remember, that we do not have to use anything fancy like Scala, to start solving some classes of problems in a much better way. I only wish he had more time on his hands, but I was lucky to sign in for Scala workshops with him on Friday.

I didn't go for Flex presentation, partially because of the beforementioned doubts, partially because I've met some friends and speakers on the way. I really wish I could be there, on their lectures, especially on Łukasz Kuczera talk about Lift+Comet and Łukasz Szydło presentation about Apprenticeship, but I could either do that or go for the workshop with Ted Neward, and after what Ted had shown us a few hours before, I was sure his workshop will be a mind opener.

And here is for all those anxious about just one track on JDD10. There were actually two on Friday, if you count the workshops, and even though that doesn't seem like much, the quality of what Ted had to offer, beat up the disadvantage of not being able to change every session for something different.

The last lecture on Thursday was “Brave changes: how to make new ideas happen”, given by Linda Rising. While not Java specific, that was quite interesting to me, mostly because of the latest changes I've been part of at TouK (both my own initiatives that you can read about here and here, and overall works on defining company goals and vision). Thing to remember: what your audience is eating is more important than what they are listening to. Scary but true.

Then there was the integration party. And as expected from programmers, Nintendo Wii had a much bigger take than girls :)

For three hours on Friday, I've been enjoying Ted Neward's Scala workshops. I won't give you much details, except it was really great, since Witek Wołejszo wrote a nice summary already.

And I didn't dare to go for “Wipro in Europe and development opportunities on Polish market”. I was afraid, that my positive experience from JDD10 could be a bit reduced.

Overall, another great conference. Thanks to Witek Wołejszo, Piotr Przybyłek and Tomasz Dziurko for this interesting trip.

October 13, 2010

Wicket form submit not safe for redirecting to intercept page

The problem

When you have a form, that anybody can see, but only logged on users can POST, you may want to redirect the user to the login page, and back to the form after login

Using wicket 1.3/1.4, if you do that using redirectToInterceptPage(loginPage) or RestartResponseAtInterceptPageException, after returning, the client will loose all the data entered to the form.

The details

The reason why this happens, is because of how redirectToInterceptPage works. It saves the URL of the requested page, and later, when continueToOriginalDestination is called, it redirects the client to the saved URL using GET. When the last call from the client was a non-ajax POST to the form, the client will be redirected without any posted data. Wicket will handle the situation issuing  HTTP 302 and redirecting the user again, but all the data is already lost.

The funny thing is that the data is actually getting to the form, because of the first POST, but then it's overwritten with nulls on the redirected GET. To make it clear, here's the HTTP conversation:

Client: POST http://localhost:8080/test?wicket:interface=:3:form::IFormSubmitListener:: (post to the form)
Server: HTTP 302 Moved Temporarily (the input was parsed, the model was updated, but you are being redirected to the login page because of redirectToInterceptPage or exception)
Client: GET http://localhost:8080/?wicket:interface=:4:::: 
Server: HTTP 200 OK (server is responding with the login page)
Client: POST  https://localhost:8443/j_spring_security_check.... (post login and password, here using spring security)
Server: HTTP 302 Moved Temporarily (validation is done. Now you are redirected from spring security to the page with wicket redirectToInterceptPage)
Client: GET https://localhost:8443/redirectAfterLogin  (here  redirectToInterceptPage is called)
Server: HTTP 302 Moved Temporarily (you are being redirected the original URL)
Client: GET http://localhost:8080/test?wicket:interface=:3:form::IFormSubmitListener:: (the same URL as the first POST but this time without post data. now your form is being submitted again, but with nulls instead of entered data)
Server: HTTP 302 Moved Temporarily (being redirected by wicket, because of Redirect After Post pattern)
Client: GET http://localhost:8080/?wicket:interface=:3:1::: (back on the form page)
Server: HTTP 200 OK (the form is empty by now)

As you see, if wicket would not redirect you at the end to the url requested by POST, but to the one called by last GET before the original POST, your data would be there.

The issue was reported two years ago. Doesn't look like it's getting fixed any time soon.

The walkaround

If you can require your users to be logged in before you show them the form, you are safe. If not, you can submit the form by AJAX. This will solve the problem, because wicket will recognize, that it cannot redirect the user to the AJAX POST target (<ajax-response> is not exactly what the user would like to have rendered in the browser), and will redirect with GET to the URL of the last page instead, which was also requested by GET. And since the data was converted to the form model in the first POST (line 1), all is well.

And in case you don't want to have a partial page update via AJAX, but would rather like to render the whole page, all you need to do is add setResponsePage(getPage()) to your button. For example like this:


    class AjaxSendButton extends AjaxFallbackButton {
        public AjaxSendButton(String id, Form form) {
            super(id, form);
        }

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form form) {
            //process your form input here
            setResponsePage(getPage());
        }
    }

Now your ajax form behaves just like a non ajax form, but can be redirected to an intercept page

The catch

When submitting forms via AJAX you have to be aware, that your form may be submitted without your submit button being clicked on. This may have unforseen consequences. For the whole problem description and a solution go here

October 5, 2010

Video from my presentation at Agile Warsaw

Here's the video from my presentation and the discussion about Agile Skills Project and our experiments in motivating developers at my company, that I had a chance to show at Agile Warsaw.

Do not ask my why the camera is 100% time focused on the wall, I have no freaking idea :) The voices are there, and that matters.

You can either watch it on Parleys: http://parleys.com/d/2019 or right here. Be warned: it's in Polish.

September 21, 2010

Getting rid of null parameters with a simple spring aspect


What is the most hated and at the same time the most popular exception in the world?

I bet it's the NullPointerException.

NullPointerException can mean anything, from simple “ups, I didn't think that can be null” to hours and days of debugging of third-party libraries (try using Dozer for complicated transformations, I dare you).

The funny thing is, it's trivial to get rid of all the NullPointerExceptions in your code. This triviality is a side effect of a technique called “Design by Contract”.

I won't go into much details about the theory, you can find everything you need on Wikipedia, but in the nutshell Design by Contract means:
  • each method has a precondition (what it expects before being called)
  • each method has a postcondition (what it guarantees, what is returned)
  • each class has an constraint on its state (class invariant)

So at the beginning of each method you check whether preconditions are met, at the end, whether postconditions and invariant are met, and if something's wrong you throw an exception saying what is wrong.

Using Spring's internal static methods that throw appropriate exceptions (IllegalArgumentException), it can look something like this:
import static org.springframework.util.Assert.notNull;
import static org.springframework.util.StringUtils.hasText;

public class BranchCreator {
    public Story createNewBranch(Story story, User user, String title) {
        verifyParameters(story, user, title);
        Story branch = //... the body of the class returnig an object
        verifyRetunedValue(branch);
        return branch;
    }

    private void verifyParameters(Story story, User user, String title) {
        notNull(story);
        notNull(user);
        hasText(title);
    }

    private void verifyRetunedValue(Story branch) {
        notNull(branch);
    }
}

You can also use Validate class from apache commons instead of spring's notNull/hasText.

Usually I just check preconditions and write tests for postconditions and constraints. But still, this is all boiler plate code. To move it out of your class, you can use many Design by Contract libraries, for example SpringContracts, or Contract4J. Either way you end up checking the preconditions on every public method.

And guess what? Except for Data Transfer Objects and some setters, every public method I write expects its parameters NOT to be null.

So to save us some writing of this boiler plate ocde, how about adding a simple aspect that will make it impossible in the whole application, to pass null to anything other than DTOs and setters? Without any additional libraries (I assume you are already using Spring Framework), annotations, and what else.

Why would I like to not allow for nulls in parameters? Because we have method overloading in modern languages. Seriously, how often do you want to see something like this:

Address address = AddressFactory.create(null, null, null, null);


And this is not much better either

Microsoft.Office.Interop.Excel.Workbook theWorkbook = ExcelObj.Workbooks.Open(openFileDialog.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

The solution

So here is a simple solution: you add one class to your project and a few lines of spring IoC configuration.

The class (aspect) looks like this:
import org.aspectj.lang.JoinPoint;
import static org.springframework.util.Assert.notNull;

public class NotNullParametersAspect {
    public void throwExceptionIfParametersAreNull(JoinPoint joinPoint) {
        for(Object argument : joinPoint.getArgs()) {
            notNull(argument);
        }
    }
}

And the spring configuration is here (remember to change the namespace to your project).
<aop:config proxy-target-class="true"> 
    <aop:aspect ref="notNullParametersAspect">
        <aop:pointcut expression="execution(public * eu.solidcraft.*..*.*(..))
                          &amp;&amp; !execution(public * eu.solidcraft.*..*Dto.*(..))
                          &amp;&amp; !execution(public * eu.solidcraft.*..*.set*(..))" id="allPublicApplicationOperationsExceptDtoAndSetters"> 
            <aop:before method="throwExceptionIfParametersAreNull" pointcut-ref="allPublicApplicationOperationsExceptDtoAndSetters"></aop:before>     
        </aop:pointcut> 
 
        <task:annotation-driven>
            <bean class="eu.solidcraft.aspects.NotNullParametersAspect" id="notNullParametersAspect"></bean>
        </task:annotation-driven>
    </aop:aspect>
</aop:config>

The "&amp;&amp;" is no error, it's just && condition escaped in xml. If you do not understand aspectj pointcut definition syntaxt, here is a little cheat sheet.

And here is a test telling us that the configuration is succesfull.

public class NotNullParametersAspectIntegrationTest extends AbstractIntegrationTest {
    @Resource(name = "userFeedbackFacade")
    private UserFeedbackFacade userFeedbackFacade;

    @Test(expected = IllegalArgumentException.class)
    public void shouldThrowExceptionIfParametersAreNull() {
        //when
        userFeedbackFacade.sendFeedback(null);

        //then exception is thrown
    }

    @Test
    public void shouldNotThrowExceptionForNullParametersOnDto() {
        //when
        UserBookmarkDto userBookmarkDto = new UserBookmarkDto();
        userBookmarkDto.withChapter(null);
        StoryAncestorDto ancestorDto = new StoryAncestorDto(null, null, null, null);

        //then no exception is thrown
    }
} 
AbstractIntegrationTest is a simple class that starts the spring test context. You can use AbstractTransactionalJUnit4SpringContextTests with @ContextConfiguration(..) instead.

The catch

Ah yes, there is a catch. Since spring AOP uses either J2SE dynamic proxies basing on an interface or aspectj CGLIB proxies, every class will either need an interface (for simple proxy based aspect weaving) or a constructor without any parameters (for cglib weaving). The good news is that the constructor can be private.

September 6, 2010

Agile Skills Project at my company

Unfulfilled programmers


Erich Fromm, a famous humanist, philosopher and psychologist strongly believed that people are basically good. If he was right, then either our society is a mind-breaking dystopia or we have a great misfortune of working in a field that burns people out, because many IT people I know are more like Al Bundy than anyone else.

Why is being a couch potato something wrong? Happiness can be achieved in many different ways, but not by passive pleasures. One way of pursuing happiness is by self realization and while self realization can happen in any activity, it's makes perfect sense to have it at work, where you spend one third of your life time anyway.

But many developers I know, consider work as something boring at best, dreadful at worst. True, programming can be awful, when you have to dig deep into a terrible code base without any perspective for a change, but IT is vast and you can always find something interesting, and once you learn it, you will find a way to make money on it, either by changing position inside your company or changing your employer altogether.

Yet most unhappy IT professionals don't do anything to change their situation. The main reason for that is, because it requires a lot of learning, and learning at home is not the most beloved activity for a couch potato.

So why are developers turning into couch potatoes in the first place? Why the last thing a typical developer will do back home is learning and polishing his skills? There are plenty of reasons for that.

The three main roots of an IT couch potato


First, our work is tiresome. Nearly every job offer you can find mentions “able to work under pressure” and “flexible long working hours” in the requirements. This translates directly to the “burn-out” phenomenon.

Second, the technological landscape is changing overwhelming fast. Unless you work for a slowly adapting institution like a bank, your skills will be outdated in a few years time. Sure the deceased Sun, god help us, granted Java developers four years of relative stagnation, but that's an exception and it's going to end soon enough anyway (unless, of course, these are just convulsions before slow death of technology). You better learn and you better learn fast, or you'll have no other option than to promote yourself into management.

Third, just how long can you sit by your computer everyday? Yeah, I know, some people spend years playing WoW, Eve and alike, barely moving. I am a sinner myself, with Steam reporting over 350 hours in Modern Warfare 2, 200 hours in F.E.A.R. 2 multi, and countless months of my life wasted by Sid's Civilization. But for not-addicted, it's just simply stupid, not to mention unhealthy, to have your ass integrated with the chair. No matter how comfortable it may be. There is more to life than that.

Case Study at my company


It all started with a few SQL programmers grumbling about how they are bored to death, and how they would like to switch to OO programming. I'm not a person who waits, so next thing I did was asking our management if they could move those guys to Java/C# projects. And the management was all for it, with just one requirement: they would have to first learn our technology stack at home, not to be totally lost and unproductive. After all, the more technologies an employee know, the more valuable he is for the employer (think about switching people between projects).

A few months later and nothing has changed. I'm asking sql guys how the learning is going, and I get the answer: it hasn't started yet.

Now, I know the best way to learn something is by hands-on experience at work. After all that's why I've been changing my job a few times: to have a real world experience. It's easier to learn french if you move to Paris. And learning at home is hard because of the aforementioned reasons. The very same reasons, why you get only 650 people on a free conference, like Javarsovia.

So what can we do, then? How about we remove all the obstacles? How about we make learning at home fun, satisfying and profitable. How about we provide  motivation and feedback. How about we also solve the never-ending dissonance between employee's financial and employer's productivity expectations on the way. Sounds interesting? Let's try, then.

First: make it profitable.


Up to some point, people get motivated by money. It won't work if you are already earning enough to pay for everything you need, but in a country like Poland, to be able to build/buy yourself a house, you have to be making many times the average salary. So here, money is still a major motivator. Every year, every developer goes back to his boss and says: I want more.

Guess what, your boss wants to pay you more. No kidding. After all Henry Ford's said:
“There is one rule for industrialists and that is: make the best quality of goods possible at the lowest cost possible, paying the highest wages possible”.

Highest wages. You boss really wants to pay more. But to stay in business, the company needs you to either improve the quality or productivity. Both mean more money to the business, and more money to pay you with. If you consider that, the goal of a developer who wants to learn something new (or get better at something) is on the way to make the company more profitable. After all, this is software development – you never know what technology you gonna need tomorrow.

This works both for completely new stuff, and for learning something that company is already quite good at. If you know several technologies that the company is working with, you are more valuable, because you can handle more projects (you boss may think in terms of reallocating resources).

After thinking about all of this I went to my bosses and asked them: will you pay more to the people who learn different technologies at home? Even when they can't use them right now at work? Will you give a rise to those Oracle guys, if they learn Java?

The answer was: definitely! They actually said that every time a developer asks for a rise, they ask him back: what have you done in the last year to improve your market value? What have you learned? Because every time an employee's market value increases, the company's value increases.

Simply speaking: more skills means more money. Both for the developer and for the company. It's amazing, how often people forget about it. Making it crystal clear can give you a motivational boost to do something at home and a nice perspective. You don't have to switch your job to get a rise. You need to learn more, and they'll happily pay you more.

Second: make it easy


The main question with learning is where to start from? And for software developers it's the most important, most difficult question, because there is no way to learn everything, because spending years studying can be simply a waste of time, if the technology is dead/outdated the moment you get productive with it. What should I learn or why should I learn at all, if the risk of wasting the most precious thing in my life, my time, is so high? How do I decide what to learn.

Lets make learning safe and easy.

Your best bet is to start with something that has much longer life expectancy, something that will help you right away, no matter what a technology you have to work with in your next project. And something that is relatively simple to learn: agile skills.

These are skills of an agile developer, well established, well recognized, and not going away any time soon, because we still do not have anything on the horizon that could surpass them.

Yeah, I know, the world 'agile' is so popular nowadays, that even my grandma is agile, but lets go for a solid list of things agile. No bullshit theory, no marketing mumbo jumbo, give me a precise, distilled and refined list of things I should learn, things that will help me, things worth spending my time on.

Here it is:

The Agile Skills Project


The project is all about self improvement and learning. It's a great inventory of “ isolated, learned, practiced, and refined” agile skills, with definitions, resources, descriptions of steps to mastery and success stories. Take a look at the “Pair Programming” page, for example.

All the skills are divided into different areas: Business Value, Collaboration, Confidence, Product, Self Improvement, Supportive Culture, Technical Excellence. You even get a nice mind-map with it.

This is a single reference point for all those who do not know where to start or where to go next. All these skills are in high demand on the market and with a very long Time-To-Live. The best thing is though: no matter what technology you gonna work with tomorrow, you can benefit from them.

I took the list from the website, tidied it up a bit, refactored it for the needs of my company, and proposed it as a Request For Comment, a wiki page, where everyone gets to discuss and shape up the idea, before we give it to the management.

Soon we had a discussion. It wasn't easy to make everyone understand the concept, but after a while people joined in, and we added some more stuff.

Level up!


The Agile Skills Project is more than a simple index. It tries to create a learning ecosystem, by defining quests:
"Quests" are on-the-job experiments, self-assessments, peer-reviews, course experiences or other activities intended to help a person better apply a particular agile developer skill set.

It's a bit like a Role Playing Game. You have your quests, you do them, you get experience. For experience you get more money and new toys (technologies) to play with.  It's fun. Billions of MMORPG players cannot be wrong.

But to make that happen we need something every game has: feedback.

Third: give feedback


OK, so we have a bit of motivation (money) and a list of goals (agile skills). Who is going to give us quests, and who is going to tell us we did a good job? How will we have our feedback?

The first and most important thing, is to see the results of you actions. Otherwise you loose focus and motivation (money can only get you that far). Therefore you should create a list of quests you have done. Put it on the intranet or somewhere, where you can show it to others. It's important, because you are going to share it with your mentor.

Yes, a mentor. Choose someone from your company, someone you trust, someone you respect. It doesn't have to be an Einstein. Meet with this person once a month, during your work-time. An hour should do. Discuss with your mentor what quests you want to accomplish this month. Could be anything, reading an IT book, learning new programming language or taking another step to master one of the agile skills from the list. Tell your mentor when you'll be done. Meet together again next month, and either put the quest in your done-list, or mark it as 'failed'.

The role of the mentor is to listen to you, remove obstacles, help you choose a good path and give you feedback.

You'll be surprised by how much the meeting with your mentor motivates you. It works much better than money: you don't want to fail in the eyes of the mentor, because this is the guy you respect, and you want him to respect you as well. And once you see your constant improvement by filling the list of quests done with your mentor, it gets addictive.

Smells corporate?


How is this any different to what you can sometimes see in a corporation, with a year long plan of tasks your boss is giving you to accomplish to get your bonus?

Well, first of all, these will be your quests, chosen by you. Second, you will choose your mentor as well. Your boss usually doesn't know a thing about what you are doing. Third, it's all about your self-improvement, not meeting some company goals. You get better at something, the company gets better at something. After all a company is not much more than the people working at it.  Fourth, it's a fast feedback cycle, you do not have to wait till the end of the year to get it.

And finally, it may be a bit corporate, because I have never seen any small company doing anything like this. But even if it is, it still seems like worthwhile. Anything to get me out of the couch.

Discuss


It's a bit too early to tell whether the idea will be successful. We have just started. Fo me it is already helpfull, because with a list of quests done I have have a feeling of progress. If you'd like to discuss this, and other ways to animate software developers to do something more, I'm leading a meeting at Agile Warsaw group about it, on the 20th of September, 19:00. Feel invited.

By the way, here you have a trial of "other ways to animate" from our internal TouK Code Jam Party, we held a week ago. Doesn't look mych corporate, does it?