Archive for February, 2011

Eclipse tip

A quick Eclipse tip that will help you keep your Package Explorer view tidy: you can define abbreviations for the packages you use. Open the Preferences, go to Java / Appearances, check the box and define your abbreviations:

From Scala back to Java

Here is a very interesting story of someone who started using Scala and then decided to come back to Java:

My experiment with Scala is not working out. It’s just not ready for prime time, and is overkill for my needs. Reluctantly, I am falling back to Java.

Here are some of the reasons why this blog post stands out for me:

  • The author didn’t simply look at Scala and shy away from it, he actually started his project but he got bogged down by various obstacles and he decided that he wasn’t going to get a return on his investment (“I wish Scala the best, but I have work to do”).

  • He also still gives plenty of credit to Scala, and while he hasn’t been completely turned off from it, the combination of subpar tooling, language complexity and compiler quirks led to him abandoning Scala for his project.

  • The comments are all extremely interesting, make sure you read them all. No flame wars, no fanboyism, just educated answers from professionals. And Martin stepped in as well.

Here are a few notable quotes from this post along with my thoughts.

Martin Odersky:

It’s true that functional programming folks are increasingly picking [Scala] up. This is a good thing, IMO, because it pushes the envelope of what you can do with the language

This statement concerns me. First, I’m not sure that the envelope needs to be pushed any further in Scala. A lot of potential users are routinely turned off by its excessive functional and academic aspects and its complex type system. The interaction between functional and object oriented features already feels pretty complex to handle, so I certainly don’t want the language to evolve any further. I hope that future efforts will be oriented more toward the libraries and the tools than the language

I think Scala has pushed the functional envelope already a bit too far for comfort.

A commenter named Nat said:

The powerful, convenient type checking is made redundant by the powerful, convenient implicits

I think this is a good way to capture the observation I made above about how the interaction of complex features leads to even more complex behaviors.

Martin Odersky:

I have now switched for all of my development work to our as yet unreleased version of the Scala plugin for Eclipse. That’s after 20 years of emacs. And I am not looking back.

Now I found this quote quite perplexing. The good news is that with Martin’s team taking over the Scala Eclipse plug-in, I am hopeful that we will finally get some significant progress in that area.

However, I am disappointed to learn that until recently, Martin was still using Emacs to write Scala (and I’m guessing, Java before he switched). For those of you who are not familiar with my opinion on the subject, I’ll summarize it thusly: if you are currently using a text editor to write Java/Scala code, you will be even more productive if you switch to Eclipse or IDEA.

The fact that Martin was still using Emacs to write code until recently probably explains why progress on the Scala IDE front has been so glacially slow. And this is tragic because I’m sure that a lot of developers have been turned off from Scala because of the lack of a good IDE plug-in. I’m hoping that with this new direction, Martin will mandate everyone on the core team to force themselves to use Eclipse in order to dogfood and improve the plug-in. It’s the only way we’ll see any progress.

This situation is pretty shameful, to be honest. Scala is about seven years old and the absence of decent IDE support after such a period of time is absolutely unforgiveable, especially given the ambitions of the Scala team.

Jonathan Edwards, the author of the blog post, is going even further:

Design the IDE first, then build a language that does what it needs.

This sounds a bit extreme to me, but I absolutely believe that in order for a language to become successful, both the languages and the productivity tools that surround it (IDE, debugger, etc…) need to be built in lockstep. Granted, this might slow down the development of the language itself, but I see this as a good thing: bringing up the entire stack at the same time is a great way to make sure that the language remains manageable. If your language has become too complex for IDE’s to handle, how do you think users will feel about it?

And this brings us to another weakness of Scala, which Martin himself touches on in another comment:

But what’s absolutely necessary is that the people who work on the IDE have an intimate knowledge of the compiler internals.

This sentence is probably the main reason why IDE support has been so slow. There are obviously very few people who are familiar with the Scala compiler internals (and I remember hearing somebody say that there are probably areas of the compiler that nobody understands any more, I wonder if it wasn’t Martin himself), so the bar is impossibly high for a Scala plug-in to happen.

Sadly, cooperation from the Scala compiler seems completely unavoidable if you want to deliver a decent plug-in, if only because the IDE will need help resolving inferred types and probably other potentially complex constructs such as implicits. I hear Martin’s team is working hard on the compiler so that it will expose a clean API that tools can work with. Let’s hope this work will come to fruition sooner than later.

One last thing: Fantom receives a well deserved mention in this thread. If you still haven’t looked into Fantom and if you are looking for Java’s successor, I strongly encourage you to go take a look at it now.

Verifying the version of your Java classes

One of the constraints when you work on fundamental software is that you need to be very careful about the classes that you ship. Not just the code itself, but also the version of the compiler that you used to compile these classes.

Despite all my precautions, I have sometimes accidentally shipped classes that were using a compiler that’s too recent. The latest occurrence of this incident was with TestNG’s Eclipse plug-in. Despite all the settings specifying that the JDK should be 1.5, I ended up with 1.6 classes in the feature jar file. I eventually figured out that when you actually build the update site, Eclipse uses some ant tasks which seem to ignore the Eclipse preferences and which revert to the global environment’s JAVA_HOME.

So I ended up writing a quick script that makes one last check before actually uploading the files to the site, which I thought some people might find interesting:

for i in `find . -name \*class`
  v=`od -h $i | head -1 | awk '{print $5}'`
  if [ $v != "3100" ]
    echo "Class $i has version $v, expected 3100"
    exit -1

Are your unit tests talking to each other behind your back?

As you have heard and read many times, unit tests should be isolated from each other. In other words, each test method should be self contained and not rely on any state other than the one it created and initialized (typically with an @BeforeMethod method).

While this constraint can impose a lot of complexity on your test methods (they sometimes need to create a lot of state before they are able to perform their testing), the general idea behind test isolation seems pretty easy to enforce. But is it?

How confident are you that your unit tests are isolated from each other? Wouldn’t you like to know for sure?

Here is how you can use TestNG’s JUnit conversion tool to verify the isolation of your unit tests in just a few clicks (this works especially well for JUnit 3 tests, JUnit 4 tests might not convert fully without some manual work).

The first step is to install the TestNG Eclipse plug-in as explained here. If you are not an Eclipse user, consider doing this anyway since it takes just a few clicks and you never have to launch Eclipse ever again after that.

Once the plug-in is installed, open the Java Explorer and right click on the package or source folder that contains your unit tests:

The first page of the wizard lets you create a testng.xml file. You only need to modify two things on this page: the type of parallelism (“methods”) and the number of threads you want to use (start with 15).

Press Next and then Finish. Once the wizard completes it will have converted all your JUnit tests to TestNG. Don’t panic, you can revert this either by undoing the Eclipse refactoring or simply by reverting the files with your source control tool (e.g. `git checkout`).

Now, launch your newly converted tests: right click on the testng.xml file that was generated and select “Run as TestNG suite”:

TestNG is now running all your test methods in parallel, with a thread pool of the size that you specified above. If your test methods are properly isolated from each other, you should see a 100% success. If not… what went wrong?

After converting hundreds of tests like this, I have made some interesting observations on what isolation errors developers can make, but I’ll save this for another post. For now, I’d love to hear how the conversion process went for you, whether it was a complete success but especially if some tests failed. In this case, feel free to share the reason for the failures.