The hype around the Scala programming language just got too much recently and I decided to give it a go. I'm two thirds of the way through Programming in Scala, a massive but very good tome and I've been experimenting with the language and tools, though only a little bit so far. I have also just received the newly published Scala for the Impatient (a deliberately much more compact book) and will be working through that as well.

To put it mildly, Scala is not for the faint hearted, or anyone who just wants to get some stuff done ASAP. There is a big, steep learning curve and the relative immaturity of the language and the small community means you'd better be used to the pains of the bleeding edge. I thought Ruby was hard work, but Scala is frankly more so in my experience so far.

However the language is somewhat addictive – or perhaps I just like the challenge of learning stuff that takes a bit of grokking. It's a big language, with many very clever facilities and features. It's mind-boggling to start with but I think it's starting to sink in. Of course there's the functional paradigm to understand and master, but I did plenty of that at university so it doesn't frighten me.

Enough people have written about the frustrations and wonders of writing code with Scala, so I think I will reflect on a few miscellaneous findings, mostly of a practical bent.

Compiler speed

The Scala compiler is surprisingly slow and it seems to be one of the main bitching points amongst people trying to get up to speed with the language. But seriously, when you're used to instantaneous results with Grails, or even plain old Java (especially with JRebel) then waiting several seconds even for a trivial app is most upsetting. But I'm trying to be Zen about it.

The mailing lists tend to be full of griping about the compiler's speed, usually met with promises that it's getting faster, but the Scala compiler is so much more complicated than the Java compiler that it seems unlikely to do its work in the blink of an eye anytime soon. See Martin Odersky's explanation of why it's slow on Stack Overflow.

Eclipse support

Eclipse supposedly has good Scala support via the Scala-IDE plugin, but I found the out of box experience so terrible that I have given up. Having created a "new Scala project" I still had to manually add the Scala libraries to the project and manually create run configurations, which would very often still not appear in the lists of ways to run the project. I just want to hit "Go" and for my app to run – it should be trivially easy to make this happen. In my experience the best open source projects are the ones that deliver a delightful out-of-box experience and this has disappointed me on that front.

IntelliJ IDEA support

Luckily the Community (i.e. free) edition of IDEA supports Scala. Even though I hadn't used IntelliJ previously, I figured out how to download their Scala plugin and create a Scala app within just a couple of minutes and it was a very smooth experience compared to installing the Scala support into Eclipse (don't get me started).

However compilation of a Hello World app took 7 seconds every time I modified the single file! A bit of Googling led me to discover FSC – the Fast Scala Compiler – which is part of the standard Scala toolset. Support for FSC is built-in to IDEA but that support is turned off by default. Once I turned it on for my project things hotted up and compilation took just 2 seconds. That's still lamentable compared to most other languages, but just about tolerable for now. I have no idea how things go for a big project, though I get the impression from mailing lists that waiting tens of seconds or even minutes for a compile is fairly commonplace. We shall see.

Play 2.0

One of the reasons I decided to try Scala in the first place was the fuss over the Play 2.0 framework, which has just recently been released in its first 'complete' form. I have only messed with a couple of tutorials so far and frankly it's bewildering and strange coming from frameworks like Spring MVC, Grails, and Ramaze (a small Ruby framework).

There is much wailing and gnashing of teeth on the Play mailing list from people upset about its radical new direction, and its emphasis on Scala compared to Play 1. Maybe it's just the pain of change, but there's no doubt Play 2 is hard work to get to grips with.

I get the impression that a lot of people are missing the point though – it's a case of horses for courses. Play 2 is rather exotically architected using cunning non-blocking approaches that require it to abandon the classic Java Servlet container entirely. It also requires you to write obtuse and sometimes verbose code (compared to Grails say – though it's usually less verbose than Java) and partly because of that non-blocking architecture. Reading and understanding the Play 2 docs on Action Composition may very well require a PhD, but Action Composition is a technique that must be used to achieve relatively common ends. It's all a bit overwhelming for newbies.

This clever shenanigans enables it to handle 40,000 requests per second (albeit very very simple requests) using less than 20MB RAM. I saw Guillame Bort demonstrate this at QCon and it's certainly impressive. The point though is that it's all architected for the sort of new-breed web app that's dealing with connected rich-clients rapidly pushing and pulling data. If you want to create a few CRUD pages for a small admin team to look after a database then I very much doubt that Play 2 is for you.

Updated 17/3/2011 with a solution to Spring Security redirecting.

I had a bit of a fight against Grails to get security exceptions handled the way I wanted, but having figured it out I thought I'd write it up. It's really very simple – I had just had the wrong end of the stick.

I want to be able to throw an org.springframework.security.access.AccessDeniedException from anywhere in my code and have that appear to the user as a custom error page of my design, but with a 403 response code (that's 403 Forbidden, rather than 500 Internal Server Error) and maintaining the originally requested URL rather than redirecting to an error URL as Spring Security sometimes prefers to do (because then you can't refresh to retry).

My main confusion arose from the way Grails' UrlMappings.groovy handles custom exception mapping. It turns out that you need to do it like this:

// Handling specific exceptions requires a 500 code on the left for the
// mapping to pick them up, but we can send back another code in the
// controller that sends back the response.
"500"(controller:"error", action:"error403", exception:AccessDeniedException)

The only surprising thing is that you need a "500" code at the left rather than "403". The reasoning seems to be that this is the incoming error code to the mapping function, and all exceptions are deemed to represent a 500 error code at this point, i.e. they represent an internal server error, which on reflection isn't entirely unreasonable. To then send the error back to the user I have an ErrorController and an associated view in /views/error/error403.gsp.

@Secured(['permitAll'])
class ErrorController {
def error403 = {
// Ensure that the correct response code gets sent. If we don't do
// this, it may send a 500 (internal server error) response because
// of the way we had to configure the UrlMappings for handling specific
// exception types with 500.
return response.sendError(javax.servlet.http.HttpServletResponse.SC_FORBIDDEN)
}
}

I also figured out how to stop Spring redirecting to a new URL when it decided to deny access. I'd rather the originally requested URL remain in the address bar. The trick is to put the following in Config.groovy.

grails.plugins.springsecurity.adh.errorPage = null

The major remaining annoyance is that these exceptions get reported in the logs whereas I'd rather they weren't (they represent the system working correctly) but I imagine I have to reconfigure logging to resolve that.

I just upgraded to latest Spock and Geb releases (0.5 and 0.5.1 respectively) but have had to undergo a strange sort of hell of odd errors before getting back on track. Turned out none of these were due to any actual code incompatibilities and eventually (after a couple of hours of fruitless head scratching) I got past them by running "grails clean" (which got me to some new errors) and finally by deleting ~/ivy2/cache. The latter step sadly seems to be required quite often when adding or upgrading plugins.

Personally I'm bitterly disappointed that Ivy (or Maven, if that's your poison), the so-called solutions to dependency hell, seems to introduce its own dependency nightmare more often than not. Of course every time you delete that Ivy cache folder you have to wait fifteen minutes the next time you run the app, whilst it downloads hundreds of jars. If you're on the train and not connected to t'Internet, you're really stuck.

I'm sure one day I'll grok what's really going on with this stuff, but for now I feel it ought to just work, but it really doesn't, and many people must waste a lot of time (or give up entirely) as a result.

I feverishly installed the latest Springsource Tool Suite release today – 2.5 RC1. Unfortunately it fairly swiftly started giving me the error shown below as I worked on my Grails project. It was popping up really frequently and would be a show-stopper if I couldn't fix it.

Screen shot 2010-10-15 at 20.50.43

It became apparent that it does this every time I saved a Groovy file that required my running Grails app to reload. It seems that STS didn't like the files in the 'target' folder changing as it recompiled, especially since I have  auto-refresh turned on in STS. I worked around this by setting up a rule for my project to exclude the target folder.

Right-click on the project, selected "Properties…" then Resource > Resource Filters. Add a filter to exclude the folder "target".

I've been slowly banging away at a small Grails app on the train to and from work, to teach myself Groovy the language and Grails the web framework. I already had a good familiarity with Java, Spring and Hibernate so it is mostly a case of learning what Groovy and Grails add on top of those. I've still got a long way to go, but I thought it worth jotting down some thoughts in case they help somebody else work their way into this particular world.

Overall, it's been fairly pleasant and I'm optimistic that it's probably as good a way to go about your average web app as any I've found before, and I've tried plenty over the past decade, including a few fairly obscure ones. I should point out that I don't believe in silver bullets any more. There are always going to be frustrations along the way when using any technology for a non-trivial project involving real-world customer requirements, but it's instructive to see just how many of those frustrations there are, and how hard they are to get past. I'm pleased to say that each time I've got a bit stuck with Grails I've been able to dig myself out fairly swiftly with the help of the existing documentation, other web resources, the #grails channel on freenode IRC and the grails-user mailing list. Furthermore, the principle of least surprise (POLS) is alive and well, meaning that when I hope that I'd find a particular feature to solve my problem du jour, it's usually there for me to find.

It's not all sunshine and roses though. For instance when I upgraded to Grails 1.3.3 my unit tests started failing with a strange and unhelpful stack trace emanating deep from within the guts of the plugin framework. Turns out this is a bug introduced in 1.3.3 that plenty of people have been caught out by. I've had to go back to 1.3.2 for now. It's a shade surprising and disappointing that a release could contain a bug like this, and that it's not been fixed and re-released yet. I worry that people trying Grails out for the first time with 1.3.3 will have a bad experience and give up early because of issues like this.

I had a struggle to find half decent tools. I've been a huge fan of Netbeans over the past several years and it claims to have great Groovy and Grails support, but I found it to be woeful I'm afraid. Common GSP tags completely confused the GSP editor (it claims the syntax is wrong) so I struggle to believe that those claiming it has this great support have actually tried developing a non-toy Grails app with it. I've settled on SpringSource Tool Suite (a bastardised Eclipse) which isn't bad – though as of this writing you definitely want to get the 2.3.3 M2 version for the latest Groovy and Grails support that's not yet in the stable release.

I'm currently getting to grips with Groovy and Grails. One major frustration that took a while to figure out was HTML escaping in GSP pages. Here's the simple lowdown, including at the end the important bit that I had struggled to realise, which is how to not escape specific strings when global HTML escaping is turned on.

Manual escaping

Out of the box (i.e. with a vanilla Grails app with default config) you need to explicitly escape any dangerous strings with the encodeAsHTML() function that Grails makes available on all Strings: ${dangerString.encodeAsHTML()}. This is a bit verbose, but at least it's very clear, and because it's just a method on String it's available everywhere in your app, not just in GSPs.

Auto-escaping with default codec

If you modify Config.groovy to contain grails.views.default.codec = "html" (which is there by default and set to "none") then it automatically calls encodeAsHTML() for you whenever you use ${} in GSPs. This is clearly quite a handy option and a much safer way of configuring things as it lessens the likelihood of slipping up and leaving a hole in your app.

Overriding auto-escaping per item

So far this is all exactly as per the Grails docs (which go into much more detail on codecs and what's really going on, including creating your own) but the crucial bit they fail to mention is what to do if you've turned on the global html codec, but have situations where you don't want escaping. The answer is to simply use the alternative JSP style interpolation syntax <%=mySafeHTMLString%> since the codec is only applied to ${}.

Overriding auto-escaping per page

You can also set the codec on a per-page basis, overriding that set in Config.groovy, with <%@page defaultCodec="html" %> or <%@page defaultCodec="none" %> as appropriate.

Overview

I've spent the past couple of weeks reading up on Grails, a web application framework inspired by Ruby on Rails. It takes advantage of Groovy, a dynamic programming language that runs on the JVM and is best described as a cross between Java and Ruby. Groovy has support for most existing Java syntax, but also a lot of Ruby-style syntax and dynamic features. To be honest I find that the Java aspects of Groovy (and Grails) drag the whole experience down a bit compared to writing Ruby, but it should be significantly nicer to work with than pure Java.

The big selling point of Groovy and Grails over Ruby on Rails comes from the compatibility with the whole Java ecosystem. You can have your clever dynamic language without giving up the Java libraries and deployment environments that your projects and customers may demand. This is clearly quite a compelling idea if like me you've got a long history of doing big Java web apps but have recently been converted to the dynamic cause.

One thing that is very important to realise is that Grails is not a port of Rails. It is in fact built on top of the Spring stack, including Spring MVC, REST support, dependency injection, transactionality and Hibernate amongst others. If you're already familiar with Spring this is probably a good thing, though I do worry that the framework on top of framework approach could lead to having more to learn (and mess up) overall.

Practical findings

My initial experiments showed an interesting result that rather worried me. I set up a domain class and a controller with def scaffold = true to provide built-in CRUD for my domain class. However the CRUD pages this presented were noticeably sluggish in the browser and benchmarking confirmed it could only manage about 2 requests per second. This is lamentably poor and even now I can't figure out how it's managing to spend so much time achieving not very much.

After a bit of experimentation I determined that if I use grails generate-all to put the scaffolding code in place in my classes (rather than using the dynamic scaffolding) then things speed up enormously. In fact I can now get about 200 requests per second. It's hard to see how there can be such a massive performance gulf between the two scenarios as I would have thought that the only extra overhead for dynamic scaffolding is the initial dynamic intercept of the missing action method and calling into the scaffolding code. Hopefully a Grails expert can explain this, or I will eventually figure it out myself. At least now I have determined that for real-world scenarios there isn't going to be a performance issue, though I am surprised that the Grails docs don't have a massive "Warning – dynamic scaffolding is really slow" box.

For now I haven't done much but read the docs and try a few things. I hope to get deeper into it soon.

I've been having a lot of trouble with my Ruby 1.9.1 install on Mac OS X. Mostly it works fine, but I struggle when installing gems that require native extensions. I think this is because the way my install was built causes linkage problems, perhaps due to 32 vs 64 bit issues, or due to linkage with other libraries. I'm not entirely sure what's causing the problems, but recently I decided enough was enough and tried out rvm since I've heard a lot of good things about it. I got the impression that by compiling from my own source I was stubbornly making a lot of my own trouble.

Rvm is trivial to install: it's a gem that installs some of its own executables. I did hack my PATH first, to remove /usr/local/bin (where my custom Ruby lived) so that I'd be using the stock Mac OS X Ruby for the rvm install.

> sudo gem install rvm
> rvm-install

Note that rvm-install added the following to the end of ~/.bash_profile automatically, so I could ignore the instruction it gave me about adding it myself:

if [ -s ~/.rvm/scripts/rvm ] ; then source ~/.rvm/scripts/rvm ; fi

I then used rvm to install a fresh version of Ruby 1.9.1:
>> rvm install 1.9.1

Actually that failed with an error about libsqlite3.dylib being the wrong architecture – perhaps another hangover from my old manual installs, or a problem I'm going to have to solve sometime in the future! For now I moved the old version of that file and tried again:

> sudo mv /usr/local/lib/libsqlite3.dylib /usr/local/lib/libsqlite3.dylibOLD
> rvm install 1.9.1

And that left me with a decent ruby 1.9.1 install. Which brought me back to one of the things that I was originally frustrated by: getting NetBeans Ruby debugging working with the fast debugger. With my old install the ruby-debug-ide gem would not install, but I'm pleased to report that it does with this new setup.

However getting NetBeans to actually use my new rvm ruby required a bit of a trick. The Ruby Platform management GUI in NetBeans doesn't show you hidden folders in its file picker, so you can't navigate to the ~/.rvm/ruby-1.9.1-p243/bin/ruby file that it wants. The trick is to create a non-hidden symlink, so you can then find it from NetBeans (and it's also handy to get at your rvm files from Finder):

> ln -s ~/.rvm ~/rvm

One word of warning: once you're using an RVM Ruby install, do not use sudo for gem installs, as the gems (and every part of rvm) live in ~/.rvm so sudo is not required. In fact using sudo will knacker your gems quite badly as it gets its PATH wrong and its permissions and you end up deleting a bunch of stuff to get back to a known good state. I learnt this the hard way!