People who are familiar with my articles know that I’m interested in Vaadin (see the "Go further" section below) and also more recently in Scala since both can increase your productivity.
Thus it is only natural that I tried to embed the best of both worlds, so to speak, as an experience. As an added challenge, I also tried to add Maven to the mix. It wasn’t as successful as I had wished, but the conclusions are interesting (at least to me).
I already showed how to create Scala projects in Eclipse in a previous post, so this was really a no-brainer. However, layering Maven on top of that was trickier. The scala library was of course added to the dependencies list, but I didn’t found how to make Maven compile Scala code so that each Eclipse save does the compilation (like it is the case with Java). I found the maven-scala-plugin provided by Scala Tools. However, I wasn’t able to use it to my satisfaction with m2eclipse. Forget the Maven plugin… Basically what I did was create the Maven project, then update the Eclipse configuration from Maven with m2eclipse and finally add the Scala builder: not very clean and utterly brittle since any update would overwrite Eclipse files. I’m all ears if anyone knows the "right" way to do!
Now to the heart of the matter: I just want a text field and a button that, when pressed, displays the content of the field. Simple enough? Not really. The first problem I encountered was to create an implementation of the button click listener in Scala. In Vaadin, the listener interface has a single method
void buttonClick(Button.ClickEvent event). Notice the type of the event? It is an inner class of
Button and wasn’t able to import it in Scala! Anyone who has the solution is welcome to step forward and tell it.
Faced with this limitation, I decided to encapsulate both the listener and the event class in two standard Java classes, one in each. In order to be decoupled, not to mention to ease my life, I created a parent POM project, and two modules, one for the Java workaround classes, the other for the real application.
Next obstacle is also Scala-related, and due to a lack of knowledge on my part. I’m a Java boy so, in order to pass a
Class instance, I’m used to write something like this:
eventRouter.addListenerVisibleClickEvent.class, this, "displayMessage")
Scala seems to frown upon it and refuses to compile the previous code. The message is "identifier expected but 'class' found". The correct syntax is:
eventRouter.addListener(classOf[VisibleClickEvent], this, "displayMessage")
Moreover, while developing, I wrote a cast the Java way:
getWindow().showNotification(button.getCaption() + " " + (String) field.getValue())
My friend Scala loudly complained that "object String is not a value" and I corrected the code like so:
getWindow().showNotification(button.getCaption() + " " + field.getValue().asInstanceOf[String])
Astute readers should have remarked that concatenating strings render this cast unnecessary and I gladly removed it in the end.
In the end, it took more time than if I had done the example in Java.
- For sure, some of the lost time is due to a lack of Scala knowledge on my part.
- However, I’m not sure the number of code lines would have been lower in Java, due to the extra-code in order to access inner classes .
- In fact, I’m positive that the project would have been simpler with Java instead of Scala (one project instead of a parent and 2 modules).
The question I ask myself is, if Scala cannot extend Java inner classes - and that being no mistake on my part, should API evolve with this constraint? Are inner classes really necessary in order to achieve a clean design or are they only some nice-to-have that are not much used?
In all cases, developers who want to code Vaadin applications in Scala should take extra care before diving in and be prepared to have a lower productivity than in Java because there are many inner classes in Vaadin component classes.
You can find the sources for this article here in Maven/Eclipse format.
To go further: