Monday, October 13, 2008

Simply Groovy (How to gain Competitive Advantage on Weiqi Gao's Friday Java Quiz)

Weiqi Gao runs the popular Friday Java Quiz. He provides puzzles and invites us to ruminate on bed-time reading of the Java Language Specification, or to recall a Java Puzzler that may have been discussed over dinner. (He would be dismayed if he knew that we occasionally just watch TV.) Often, he absolutely forbids us from using the compiler.

Whatever: if you're like me, you take your best, thoughtful guess and then fire up an editor to check. Often, this is rushed, because it would be nice to be the first one to post a comment. All too often, I don't get to the verification stage because it is just too much effort. I only have so many public static void mains in me.

These days, I just use Groovy's command-line. It gives me an advantage in terms of speed, and it often makes the problem more fun, because I have to formulate it in a different way.

For example, in the latest quiz, Weiqi says that it can't get much simpler.

In Java, the code is (mostly) as simple as possible:


import java.io.*;

public class Foo {
public static void main(String[] args) {
Serializable bar = null;
System.out.println(bar instanceof Serializable);
}
}

Yet with Groovy's -e parameter, life is much easier (and faster):


$ groovy -e " Serializable bar = null ; \
println (bar instanceof Serializable) "

The snippet above has 2 cool elements: (a) Groovy auto-imports java.util.* and java.io.* (e.g. Serializable) for you and (b) it will evaluate an expression on the fly. Because Groovy accepts most Java, this is a handy way to beat the masses to the answer of the Friday Java Quiz.

More than that, it is a great way to answer many quick questions in Java. I often use it in my team's war room when a question arises.

Note: I'm not sure, but I think that -e may have a bug in 1.5+ on a Windows machine. A single statement works fine, but this:


groovy -e " println 'hi' ; println 'there' "


seems to have trouble on a Windows box. Drop a line on your experience.

Wednesday, October 8, 2008

Ant vs Maven, Episode 2 : Gant or Gradle?

[Editor's note, 2020: those interested in former Codehaus projects may be interested in this link.]

In June, I gave a tech talk on Gant. Gant is a Groovy layer on top of Ant -- essentially Groovy's AntBuilder on sterioids. My thesis was:

  • We are in a post-Ant world, and at a crossroads. One road involves continuous integration tools such as Hudson. Another road concerns project framework builds such as Maven. A final road is for general purpose build tools such as Ant. These roads may intertwine, and even build on one another.
  • However, with respect to the latter road: we need a new general purpose build tool. We owe a tremendous debt to Ant, and it is still useful, but it has serious problems. First, XML is not a programming language. Second, the Ant community can't decide if it is declarative or imperative: e.g. properties are immutable, except when they aren't. Finally, some of Ant's built-in tasks (e.g. javac) are great: call them "big iron" workhorses; however, the act of "machining" a new task is prohibitively difficult.
  • Enter Gant: it rests on top of the "big iron" tasks of Ant, but allows us to work with a real programming language (Groovy) so that simple logic is trivial and new tasks are like working with modelling clay. Put another way, if Ant is a rigid, metal clock, then Gant is weirdly fluid -- yet both keep time.
That was June. Now, alas, it isn't so simple: Gant has had a competitor named Gradle. Gradle is more 'heavyweight' than Gant: it uses a full Directed Acyclic Graph (DAG) and aspires to be closer to something like Maven or SCons. In terms of formal build theory, Gradle is more powerful than Gant. The question, posed on the Groovy mailing list, is how to unify the forces. It is a fascinating debate, and rather important to the Groovy community. I haven't used Gradle so I can't choose, but I will say that I think this direction is the future for build tools: dynamic languages are a great fit for builds. Here is a quick (hopefully correct) rundown:
  • Gant rests on top of Ant. It is lightweight and is used as a task management framework in Grails (quite a pedigree there).
  • Gradle has strong Ant integration, but aspires to be more than a scripting language for Ant. It has DAG support and targets a space closer to, and actually beyond, Maven.
  • In simple terms, Gant is analogous to Ant ; Gradle is analogous to Maven. And so many of the usual arguments apply. However, an open question is if Gradle can serve Gant's position as a lightweight tool (where lightweight itself is open to definition).
If you want to be on the bleeding edge, check out this debate. I'm happy to see that the discussion is civil and intelligent: these are cool blokes. Very interesting.

Razz Your Friends : the best Java Exception ever

Hey! what is this mess? You are totally throwing a CME!

Where CME is defined here (and used metaphorically)

Thanks to CtJ correspondent Steve Holdener for the tip.

Monday, October 6, 2008

I have seen the Future and its name is Ruby

Well, I haven't seen the future, but this guy has... I defer to Future Man for an update on the current state of the language:



ps. Be sure to see the outtake (?) at the end.

Sunday, October 5, 2008

Thank You, Java 5

Alex Miller polled Java users and a fair number are still using JDK 1.4. This post is intended for those folks: have hope, there is truly useful stuff in Java 5.

In this post, I will mention a couple of my favourites. These have been well-documented, and are not even the 'coolest' features, but my respect for them has been well-earned over the last few months.

Background

I've been part of a team that has been moving a project from JDK 1.4 to Java 6, and introducing Hibernate/Postgres to replace (in incremental steps) an existing, legacy framework that works with an OODB. This has been a serious refactoring and fairly risky. My analogy is that of putting in a subway transit system into a modern city: it is a massive job, but will be well worth it.

Ten months later, we appear (knock wood) to be finished with a major version of this migration. I've used the following Java 5 features before, but now I am truly fond of them.

The For Loop

When I first saw the new for loop, I yawned:


List<String> list = new ArrayList<String>();

// snip

for( String s : list ) {
System.out.println(s);
}


It was a nice bit of syntactic sugar, but I was unimpressed. Now, I can't stand to see an old-style loop. The new loop is so much cleaner. A major bonus for us is that it works with arrays:


String[] array = new String[]{ "abc", "def" };

for( String s : array ) {
System.out.println(s);
}


As we have refactored, the code literally looks washed and waxed afterwards. Very nice.

Generics

When I first saw generics in Java, I was unimpressed. With a background in C++ and other languages, I understood the point but felt that Java had lost some of its Smalltalk influence, and that the syntax was plain ugly. When I realized the "wall of erasure" (as coined by Brian Gilstrap), I was even less enthused:


List<String> list = new ArrayList<String>();

list.add("Cubs swept by Dodgers.");
list.add("any team can have a bad millenium!");

// on a static page, generics allows us to avoid the cast,
// which is boring, and compile-time checking.
// The biggest advantage is in a good IDE
// where this information comes alive:

String first = list.get(0);


Now, I am an absolute fan. Yes, the corner cases are sharp, and the FAQ is very long for a reason. Yes, we may well need reified types to get full generic capabilities. I don't care: the new static typing of collections saved our project. Seriously. We were wading through dozens of collections in the legacy code and would have never been able to untangle all the knots without Java generics and Eclipse. I repeat: generics saved us, and I am grateful.

The Upshot

We shouldn't suspend our critical thinking and skepticism when it comes to new language features. However, we should also believe that people are earnestly trying to add value when new features are proposed. For one, I am going to keep an open mind when it comes to looking at the new features for Java 7+. Who knows: the features which cause us to roll our eyes may well be our future favourites.

ps. This is another post but unit testing and integration testing (with dbUnit) was equally essential to our success. Of the bugs in new code, my guess is that 90% were in code that was not tested.

pps. We have barely used static imports, but Eric has done some cool things with them. They are underrated, IMO.