sábado 25 de julio de 2009

Say it with me...GE-NE-RICS

Sorry, I'm in a bad mood today. It must be an uphill battle I guess. I've seen people confused with generics (I'm talking about Java here). They seem to get the concept and can use generic collections pretty well. Once teached they happily write:

Set<Something> somethings = new HashSet<Something>();

And for some unforeseeable reason they're happy with themselfs and proud of using generics. Some of them even attempt to understand advanced concepts like erasure (a concept that shouldn't even exist by the way). And, in fact, they do. Now, that's the end of the story. A dead end indeed.

For the great majority generics are something, revolving collections (and comparators..or was that TOO advanced?), made by Sun so everybody can use them later in their applications. Nobody seems to go one step beyond and try to develop generic classes of their own. Go figure!

So say we are designing a client application that needs to connect to several types of servers. A downright mediocre architect would write:

public interface Server {
   Object openConnection(Object connectionDetails);
}

He will argue that the specific types are unknown at the moment. Utter crap, of course. While an old school, barely capable, one would instead put something like:

public interface Server {
   Connection openConnection(ConnectionDetails connectionDetails);
}

Better no doubt. But it suffers the same issue, namely downcasts. Downcasts are obviously not elegant but they also pinpoint problems and bad practices. Avoid like the plague.

Generics to the rescue. Yes, you can do better! Believe me! That's what generics are really for. Not for collections but for you! For your designs! Let's refactor that interface of us a little. What would we need? Well, we know that a connection to the server is needed and that the server implementation and hence its connection are only known by the subclass in particular. So a FTP client has to return a different connection object that a Subversion client. Fine. Starting were our old good architect left the code we could try to modify it a bit. For example:

public interface Server<T extens Connection> {
   T openConnection(ConnectionDetails connectionDetails);
}

I know what your going to say...does that even compile? But looking at it more closely the changes are really minimum. We are just declaring a generic server that has one unknown parameter. But not completely unknown , at least we know it will be some kind of Connection object. But didn't we have that already covered with the old example? Yes..and now. Let's see an implementation. First we are going to use an abstract base class with some minor checkings:

public abstract class AbstractServer<T extends Connection> implements Server<T> {

   protected abstract T doOpenConnection(ConnectionDetails connectionDetails);

   public final T openConnection(ConnectionDetails connectionDetails) {
      ..do some checks...
      return doOpenConnection(connectionDetails);
   }

}

The only interesting bit of the above code is the way we carry the generic parameter down the hierarchy. Till when? Until the final Server implementation:

public final class SubversionServer extends AbstractServer<SubversionConnection> {

   public SubversionConnection doOpenConnection(ConnectionDetails connDetails) {
      ...
   }

}

See the difference now? The openConnection returns a specific class so the compiler checks the types for us! No more downcasts in the process! No class cast exceptions at runtime. And finally something to be proud of to show to your colleagues ;-)



PS.- In case you're wondering where that code actually comes from I'm happy to announce that I've started a new Open Source project at Google Code: IWebJTracker. It's in its infancy right now but with time it will become an issue (project?) tracker built completely in Java. Think of Trac or Project Tracker. Why I'm doing it? For two reasons: first so IWebMvc has a poster child application, second because there are no good OSS Java issue trackers. And by good here I mean with good Maven integration..Sonar...Hudson...see where I plan to go?

PSS.- Any help is gladly welcome :-)

domingo 19 de julio de 2009

IWebMvc2 Release Candidate 10 available

For the last month or so I've been able to devote some time to IWebMvc2 and now it pays dividends. I've just uploaded a new Release Candidate and I'm well on track for a final release at the beginning of September.

This new version has several interesting upgrades.

Obviously the most notorious are the two new widgets: Multifile upload and Gallery. The former allows the user to upload a number of related documents and group them in the server as one entity. Documents can be added or removed as needed. It's been built from scratch as I wasn't happy with the matching widget in version one. Visually:


Gallery is a direct consequence. It will show all the images from a MultiDocument in a slideshow manner. It's a direct port of the same widget in IWebMvc or a ThumbnailPicker from Dojo.


But the improvements do not end here. I've invested a lot of time to increase performance. The use of Hibernate batch has, at least, halved the boot time (DB populate has gone from over a minute to less than a few seconds) and offers a better response overall. The client has benefit from the new crop of browsers greatly and the demo application runs smoothly on FF 3.5 and Chrome 2 (IE continues to be my bane).

Other minor issues include:
  • This release is based on Maven2 instead of Ant+Ivy
  • Dojo 1.3.2, SoundManager2 upgrade et al
  • Sonar quality assurance (including core refactorings and new unit tests)
  • And add the usual bag of bug fixes..
Of course, this is the first publicized version in a while so you may have missed...

The link widget:


Or the poll widget...


Or the many other...just check and enjoy!

viernes 10 de julio de 2009

Quality assurance with Sonar

It's incredible how unknown a tool like Sonar is yet. I guess Gradle suffers the same destiny. After all, they're both similar in their intent, improve the quality of your software. It seems lots of people know about unit testing (not so many about code coverage), less know about tools like Checkstyle or FindBugs (static analysis of code) and just a minority are aware of other esoteric metrics like cyclomatic complexity. And even the few that use all of them do not extract all the value that a dashboard provides. That's what Sonar handles, it will take your project and stress it showing the results in a visually appealing site. With no extra work from you, the only requirement is to use Ant or, preferably, Maven.

But seeing is believing so I'll try to convince you showing the whole process and what kind of enhancements you'll be getting. As the demo project I've chosen IWebMvc2. I've nearly finished the development by now so it's a perfect timing to improve quality. In addition it's a complex web application made of three different sub-projects so something must arise. IMHO the quality of the code is pretty good, in theory I just want proofs...did I just say humble? ;-).

The first task is downloading the project and installing it. It's trivial believe me (well as long as you know how to unpack an archive...). To run Sonar just go to the bin folder, select your OS and execute the provided script. Trivial again. Sonar show be accessible (although empty) at http://localhost:9000 by now. Go there and login with admin/admin. Select configuration and under Quality Profiles click on Sonar way with Findbugs: set as default.

Next step is to build our project and include the Sonar phase. This is done typing:

mvn clean compile sonar:sonar

Pretty easy, wasn't it? If the project was built successfully the console was updated and shows something like:

A quick glance reveals a row per project analyzed indicating the number of rules violated and the coverage of the unit tests. There's a little bug with the latest JDK and Cobertura that reports 0% coverage always. As a workaround use JDK6_Update13 for example. The build time reflects how long ago was this information retrieved (not how long took the build itself, tricky). One click on the project shows the dashboard (this is a trimmed version):

Here's the bread and butter! All kind of metrics! From the whole project. The graphic displays the number of modules (JARs) and the relative size of each one. It's used to drill down and get module specific statistics. In fact, every link allows to navigate to new pages with deeper details.

Our task is to improve the quality of the project (bit by bit) so we can navigate to the Violations section and get a detailed report of the problems:

The rules are divided in several areas, some are require while others are optional. Selecting one rule gives the complete list of locations where the code fails to comply. Selecting one of those locations highlights the code:

In the above example Sonar has detected a private method that is never called. For performance and maintainability it should be removed altogether. Now, this is not true at all because I KNOW this method is called using reflection. So I should just ignore this error (caution! static analysis tools are not perfect!). Otherwise I could simply open an IDE and correct the mistake.

Of course Sonar remembers previous scenarios and can track the project life cycle (time machine they call it). Ideally you should be tying Sonar with a Continuous Integration server (out-of-the-box includes a Hudson plug-in).

I'm not gonna lie, quality requires effort. Even if you're an outstanding programmer. Sonar will just help (a lot actually) by providing visual and reporting tools but expect a slow (sometime tedious) climb to the top. Fortunately, in the end, it pays dividends.

martes 7 de julio de 2009

Finally...Maven

I've always been a happy Ant user. Even more so since Ivy has been available. Obviously that puts me in one side of the fence and I've been a very proactive supporter of that kind of project configuration. I must admit that included some rants about Maven here and there. In my biased opinion Maven lacked the flexibility that Ant provided and it was all about dependency management which was handled fine by Ivy. Probably my lack of confidence (knowledge) with the tool had some influence there too.

Four things made me reconsider my position: Hudson, Sonar, Netbeans 6.7 and the amount of time I was spending writing scripts. At work I had to install a CI server a couple of weeks ago and I was not using CruiseControl if at all possible (bad bad memories, I guess). That left Hudson as the best option (well, for me). I spent some time through the documentation and quickly realized that Maven was quite more straightforward than Ant this time. I needed a quality tool as well and Sonar has always been on my radar. Sonar works (again) out-of-the-box with Maven and requires some extra configuration with Ant. Being the lazy developer that I am I decided to test Maven with one project and see the results.

My first impression was pretty favorable. Migrating a simple Java project was a breeze and setting the job in Hudson trivial. I had the statistics online in less than half an hour. Finally I was understanding what was so good with Maven. It was not transitive dependency management, it was Convention over Configuration with the added benefit that other people where writing very interesting plugins for me. With absolutely no work on my side I had an automated build, quality control (testing plus quality assurance) and Jetty running. By now, I was in love with Maven. In more detail:

  • Zero configuration
    So much time lost with Ant refurbishing the same scripts time and again...

  • Dependency management
    I found Maven quite easier to handle than Ivy. I really really missed the master configuration of Ivy though (it saves time when you don't want transitivity for any reason).

  • IDE support
    Today all major IDEs include seamless integration with Maven2. Latest Netbeans release, in particular, works wonders (the reactor plugin is awesome). Ivy support is scarce by contrast.

  • Redistribution
    I've had to invest quite some work, many times, to offer Ant+Ivy scripts along with different project files (Eclipse, Netbeans, IDEA) to appease all kind of users. Not any longer. POMs are treated as first class citizens everywhere now. With the added benefit that I'll be able to upload the builds to the central repository.

  • Future
    I'm under the impression that things like OSGi will be pretty much simpler with this approach.

All in all, I'm leaving Ant. For good. I can't say anything but praises about Ant, it's been years of comradery. And yes, it's a somewhat sad situation but I can't help seeing it obsolete, overridden..