Groovy/Grails – Pivotal == Opportunity

The news broke this morning that Pivotal plans to withdraw its financial support from the Groovy and Grails projects by the end of March, 2015. The heads of both projects, Guillaume Laforge and Graeme Rocher, have each blogged about it, with their typical grace, thanking Pivotal for the opportunity and assuring everybody that both projects have a long, bright future ahead of them.

Since I.T. is a field that frequently has very little memory, let me remind people about a couple of items:

  1. Groovy existed as a successful open source project for at least four years before SpringSource started supporting it. Grails started as an offshoot of Groovy and was just as popular.
  2. Several of the core teams members of both projects formed the G2One company, which was sufficiently successful in its first year that SpringSource acquired it in the first place

Neither Groovy nor Grails are radical departures from their underlying technologies. That makes them quiet projects — they’re popular, but they aren’t showy. They never have been popular among the hipster IT community, but they get the job done. It’s so easy to add Groovy to existing Java projects that most developers who do it don’t feel obligated to crow about it. Groovy is being used throughout the Java industry, and in most places it’s just acknowledged without comment. Grails, for all its power, feels like an easy way to build traditional Spring/Hibernate web applications, which work really well but are hardly sexy.

It’s therefore not surprising that the potential of Groovy and Grails is often underestimated. I have no idea what Pivotal was thinking, and the public statements about them have been uniformly positive (again, not a big surprise given the people involved), but I find it easy to believe Groovy and Grails were underrated yet again.

Many people will now write many posts demonstrating, yet again, how powerful Groovy is and how easy it is for Java developers to learn. The Grails web site already has dozens of success stories. I’m not going to try to add to that, other than to say I love working with both technologies and they’ve completely changed my life.

I want to mention something else. I’ve been in the IT industry for over 20 years. I was in the engineering community for a dozen years before that. I would hold up my academic background against anybody’s. From all those experiences, I’ve known geniuses and incredibly hard workers, and communities who are friendly, hostile, and everything in between.

I’m here to tell you that the Groovy and Grails core teams members are among the brightest people I’ve ever met, but they’re also successful because they’re wonderful individuals to be around. In an industry often marred by what I like to call “boys behaving badly,” I’ve never heard a negative word about anyone involved in Groovy and Grails. That attitude starts at the top, with great people like Graeme and Guillaume, and I feel privileged to know and work with them, however tangentially.

Look, community matters. It makes the difference between struggling to accomplish anything and enjoying your job. I teach technical training courses for a living, and you should see the joy in Java developers eyes when they learn both how much they can now do, and — this is important — how newcomers are treated with respect and how their questions are answered without patronizing or humiliating attitudes.

They say it’s hard for companies to find good developers these days. Well, here’s your opportunity. For the price of supporting technologies that will inevitably help your bottom line, you can acquire a team of coders that are among the most accomplished, most dedicated, and most easy to work with that you’ll ever meet.

Pivotal is now out of the picture. This is a great opportunity for a smart company to step in, acquire two fantastic teams of developers, and be a hero to the open source community. Heck, I’d do it myself if I could afford it. Don’t miss this chance. They don’t come along very often.

Unit testing Grails controllers, revisited

I’ve been neglecting my blog, which I blame on a combination of using twitter and being on a book project.  More about those later.  In the meantime, I’ve recently been working on some Grails projects and found an issue with unit testing controllers.

I’m now on Grails 1.3.5, and I’m trying hard to do unit tests rather than integration tests.  I rapidly hit a couple of issues, which I want to log here mostly so I don’t forget how I resolved them.

Let’s look at a trivial Hello, World type of example.  Say I have a Grails project called helloworld, with a single controller.

package cc.hello
class WelcomeController {
    def index = { 
        log.info "params: $params"

        String name = params.name ?: 'Grails'
        render "Hello, $name!"	
    }
    
    def redirectMethod = { redirect action:"other" }
    
    def other = { render "Made it here" }
}

This is (deliberately) very similar to the example in the Grails reference guide. If I specify a parameter called name, the index action returns “Hello, $name”, otherwise it returns “Hello, Grails!”. I also added a method to do a redirect, because the generated Grails controllers do that a lot and I want to be able to test them.

To keep the story short, here’s my unit test, which I’ll explain afterwards.

package cc.hello

import grails.test.*

class WelcomeControllerTests extends ControllerUnitTestCase {
    WelcomeController controller

    protected void setUp() {
        super.setUp()
        controller = new WelcomeController()
        mockController(WelcomeController)
    }

    void testIndexNoParameters() {
        controller.index()
        assertEquals "Hello, Grails!", controller.response.contentAsString
    }

    void testIndexWithName() {
        controller.params.name = "Dolly"
        //mockParams.name = "Dolly"
        controller.index()
        assertEquals "Hello, Dolly!", controller.response.contentAsString
    }

    void testRedirect() {
        controller.redirectMethod()
        assertEquals "other", controller.redirectArgs['action']
    }
}

The key features of this test are:

  • I have to call super.setUp() in my setUp() method, or calling mockController throws a NullPointerException. The actual error is “Cannot invoke containsKey() on a null object”. In other words, the maps for the mock objects aren’t being set up without calling setUp() in the superclass. This cost me a lot of searching to figure out.
  • Unlike mocking the domain objects, you can instantiate the controller and then call MockController afterwards. For domain classes you either have to mock the domain first, or call the version of mockDomain or mockForConstraintsTests that takes a list of instances as its second argument.
  • The reference documentation tests the redirected method by comparing the generated URL to controller.response.redirectedUrl. That expression always returned null for me, however, and a search of the grails-users list showed it returns null for lots of people. Eventually I found in the excellent Grails in Action book by Peter Ledbrook and Glen Smith that the redirectArgs map has the name of the redirected action under the "action" key, so I can just compare to that. That’s what I’m doing above.

Hopefully these points will help keep someone else from making the same mistakes I did.

Using a codec in a Grails unit test

This is a small issue, but I encountered it and found a solution on the mailing lists, so I thought I’d document it here.

I was demonstrating a trivial Grails application in class today and decided to unit test it. The app has a single controller, called WelcomeController:

class WelcomeController {
  def index = {
    def name = params.name ?: "Grails"
    render "Hello, $name"
  }
}

When I deploy the application and access the Welcome controller (via http://localhost:8080/hellograils/welcome/index), it displays “Hello, Grails!”. If I append “?name=Dolly” to the URL, the result is “Hello, Dolly!”. All nice and simple.

I decided I wanted to write a test case for this, and lately I’ve been learning how to favor unit tests over integration tests as much as possible, mostly for speed. I therefore wrote the following tests:

import grails.test.*

class WelcomeControllerTests extends ControllerUnitTestCase {
  void testWelcomeWithoutParameter() {
    def wc = new WelcomeController()
      wc.index()
      assertEquals "Hello, Grails!", wc.response.contentAsString
    }

  void testWelcomeWithParameter() {
    def wc = new WelcomeController()
    wc.params.name = "Dolly"
    wc.index()
    assertEquals "Hello, Dolly!", wc.response.contentAsString
  }
}

When I run the unit tests (i.e., grails test-app unit:), everything runs correctly.

One of the students pointed out that though this is a trivial example, it’s open to XSS (cross-site scripting) attacks. In the URL, replace “name=Dolly” with “name=alert('dude, you've been hacked')” and the embedded JavaScript code executes and pops up an alert box.

I knew that an easy solution to this would be to modify the index action in the controller to look like:

class WelcomeController {
  def index = {
    def name = params.name ?: "Grails"
    render "Hello, $name".encodeAsHTML()
  }
}

The “encodeAsHTML” method escapes all the HTML, so the output of the hack is just “Hello, alert(…” (i.e., the script is shown as a string, rather than executed) and the problem goes away.

The issue I encountered, though, is that my unit tests started failing, with a missing method exception that claimed that the String class doesn’t have a method called encodeAsHTML. That’s correct, of course, because that method is dynamically injected by Grails based on the org.codehaus.groovy.grails.plugin.codecs.HTMLCodec class. In a unit test, though, the injection doesn’t happen, and I get the exception.

One solution to this, as pointed out on the very valuable grails-users email list, is to add the method to the String class via its metaclass. In other words, in my test, I can add

  void setUp() {
    super.setUp()
    String.metaclass.encodeAsHTML = {
      org.codehaus.groovy.grails.plugins.codecs.HTMLCodec.encode(delegate)
    }
  }

Now the String class has the encodeAsHTML method, and everything works again.

Then I started browsing the Grails API, and found that in ControllerUnitTestCase there’s a method called loadCodec. The GroovyDocs weren’t very informative, but I found in the jira for Grails that issue GRAILS-3816 recommends the addition of the loadCodec method for just this sort of purpose.

That means that I can actually write

  void setUp() {
    super.setUp()
    loadCode(org.codehaus.groovy.grails.plugins.codecs.HTMLCodec)
  }

and everything works as it should. Since this isn’t terribly well documented, I thought I’d say something here. Hopefully this will save somebody some looking around.

SpringOne 2GX final thoughts

I wound up too busy to maintain my daily reports, but here are a couple of items I want to highlight as important take-aways from SpringOne 2GX. Rather than just recap sessions or dole out marketing-type praise, I’m going to focus on some things I learned that I didn’t necessarily expect.

  1. A lot of people who advocate Scala or Clojure over Groovy emphasize their scalability and features like immutable objects. Groovy’s @Immutable annotation takes care of the latter, and the gpars project handles the rest. You can use @Immutable right away. The gpars project is still pretty early in its lifecycle, but it’s going to be HUGE.
  2. By the way, despite the fact it looks like it’s pronounced “Gee-Pars” (and Paul King kept calling it that), I love the way Scott Davis kept referring to it as “jeepers” 🙂
  3. Twitter has reached “essential” status at conferences. This is the first conference I attended where I would have missed half of what was going on if I hadn’t been using my Twitter client the whole time (I use twhirl, btw, but I’m open to other possibilities). Most of the presenters (@glaforge, @graemerocher, @paulk_asert, @daveklein, @jeffscottbrown, @scottdavis99, @aalmiray, and several others that would come to mind if I thought harder about it) were continually tweeting good info. As a company, @ManningBooks did an excellent job, especially with their #hideandtweet game.
  4. As a totally unexpected (to me) underlying theme, the rise of non-relational databases is striking. Apparently, the major cloud providers (Google AppEngine, Amazon SimpleDB) have decided that relational simply doesn’t scale, so they’re going with “schemaless” solutions. I had no idea how significant that was until I heard enthusiastic support for the idea from the audience of one of the Amazon cloud computing sessions. I know a lot of DBAs who are in for quite a shock. So is Oracle, too, and that’s got to be a Good Thing.
  5. Like Grails recently and Ruby on Rails before that, the new Spring Roo project makes existing web development approaches look antiquated. Roo and Grails are siblings that will learn a lot from each other as they continue to grow. For example, Grails has an interactive console, but it isn’t nearly as cool as Roo’s. I’m sure that’ll change soon enough.
  6. The extraordinarily humility and friendliness of the Groovy and Grails core teams is charming. Everyone I met seems almost embarrassed to be having so much fun working on something they like so much. There’s none of the arrogance or elitism that characterizes so many other revolutionary groups, and they always go out of their way to help and answer questions. I love talking to them and really hope to be included as one of them some day.
  7. Speaking of that, sometimes timing is everything. I told Guillaume Laforge (Groovy team lead, for those who don’t know) that he was one of my personal heroes and nearly made him spit up his drink. Sorry, I didn’t get a picture. 🙂
  8. Griffon made several fans at the conference, especially among the existing Groovy people. I still think it’s a bit early for mainstream practice, but all the signs are favorable.
  9. October is definitely the right time to visit New Orleans.

I had a very good time at the conference and am already looking forward to the next one.

SpringOne 2GX Day 0

I’m at the SpringOne2GX conference (http://www.springone2gx.com) in New Orleans this week. Monday (which they’re calling day 1 but I’m referring to here as day 0) consisted only of registration plus a reception and finally a keynote by Rod Johnson.

As a frequent NFJS attendee, the “reception” was a bit of a culture shock. One of the great appeals of No Fluff, Just Stuff is that there are no vendors present. This reception turned out to be purely a vendor reception, with wine and beer and light munchies. The vendors were all talking about Spring, of course, not Groovy or Grails. I didn’t find any of them particularly overwhelming.

The most amusing part is that one of the Platinum Sponsors was, of all companies, Microsoft. The Microsoft rep was sitting at a table by himself, with no posters or anything. He was sitting in front of a Mac (!).

When I asked him about the Mac, he showed me that it was running VMWare and a Windows 7 pre-release version. Then I asked him about he platinum status, in a rather obnoxious way.

“I can understand why Microsoft might want to be here,” I said, “but Platinum Sponsor? What’s up with that? What’s your goal?”

“We’re talking about our integration story,” he said.

“You mean web services?”

“No,” he said, and then proceeded to describe accessing MS apps via RESTful web services (or maybe just GETful — I didn’t get the details). He also mentioned some MS product I’d never heard of.

When I prodded again about the platinum sponsorship, he confessed that this isn’t really a large conference for MS, so the platinum sponsorship really wasn’t much money to them. Must be nice.

I also asked him why he didn’t have any posters or anything. He said that MS has a major developer conference coming up in a couple of weeks. When he went to get the stuff he needed for this conf, it turned out everything was already packed away. 🙂

The other big event of the evening was Rod Johnson’s keynote. That turned out to be a mixed bag, at least from my point of view. He spent the first 20 minutes or so reviewing the glorious history of Spring, focusing on a timeline and all the enthusiasm in the developer community. Now, I’ve been using (and teaching) Spring for years and I really like it, but this felt like a “fire up the troops” talk as though we were marketeers.

He did break for demos of Spring Integration, and tc server with the cool performance monitoring stuff, and a review of what’s new in 3.0. Then he set up the demo by Graeme Rocher, the extremely impressive lead of the Grails project.

To introduce the topic of Grails, Rod made an extremely odd segue. He mentioned how he was able to get “bacon ice cream” in the hotel (a real, of strange product). He somehow related that to a picture of three pigs, and said that pigs build brick houses, and that Grails is built on a brick foundation. That foundation included Spring of course, but he forgot to say anything about Hibernate. 🙂

Graeme, wisely IMHO, ignored all that. He showed how the latest version of STS (SpringSource Tool Suite) had very good Grails support. The version he showed will be released Wednesday. Graeme was great, as usual. The only problem I ever have with him is that he tends to make everything look easy, which can be a tad misleading. Still, the support looked solid, and as a community we desperately need that.

The one practical point I took from Rod is that apparently there’s going to be a developer version of tc server. I was really looking forward to checking into tc server, until I found you have to pay for it. I can’t justify that, especially when GlassFish has improved so much over the past few years and JBoss still works, too. Now if there’s a free dev version, maybe I’ll try it.

The biggest message I got from the whole evening, though, is that so far this is a Spring conference, not a Groovy/Grails conference. I hope that doesn’t carry through the whole way.

For me, the best part was finally getting to meet Guillaume Laforge, Paul King, and Robert Fischer in person. I also re-connected with Dave Klein and the indefatigable Andres Almiray. That rocked. The Groovy/Grails/Griffon (!) community is filled with great people.

I’ll try to update this blog periodically as the conference goes on. Any comments, of course, are welcome and appreciated.

Humor lost on Grails Podcast

During the last Grails Podcast, Glen and Sven mentioned how they’d received feedback from me on the previous podcast, part two of their interview with Scott Davis. Instead of reading my feedback verbatim, they made the (possibly wise) decision to just summarize it.

The only problem I have with their decision is that I went to a lot of trouble to make my message as funny as possible, and I even included a comment about Dave Klein in it. All of that was lost. So, as a (possibly unwise) service to my readers, I thought I’d reproduce my message here.

My message is below. I also feel the need to embed some of my own comments, which I’ll include in square brackets [like this].

———— Original message [with annotations] ——————
Hi Glen and Sven,

I just listened to your two-part podcast with Scott Davis, and I feel I have to correct the record on a couple of points. In part two, Glen asked Scott about the O’Reilly book that he and I are working on, entitled “Making Java Groovy“. During that discussion, Scott pronounced my name correctly, which is pretty amazing, but he mistakenly said that I live in the Philadelphia area. Actually, I live in Connecticut, and have for the past 20 years. My sister lives outside of Philly, but I don’t think Scott knows that.

[Missed opportunity for a joke: “Wait a minute… what is Scott Davis doing with my sister?”]

Scott also mentioned that the book has been taking a bit longer than we originally anticipated. Actually, that’s true. One of the reasons is that writing this book has been too much fun. I’m really enjoying working through all the different ways to enhance Java systems with Groovy, ranging from Swing user interfaces (as Scott mentioned) to using Groovy to configure Spring beans to building Groovy handlers for JAX-WS web services. These days I’m hard at work on a chapter called “Groovy in the Cloud”, describing my experiences with Groovy and Java on Google App Engine. I’m also working with a lot of XML-based baseball data, which means that Red Sox games are deductible, right?

[Note the subtle interplay of self-deprecating humor with actual info about the book. Plus, I managed to work in a baseball joke, though it was pretty lame.]

Let’s also get real here. Some of the delays are your fault, Glen. You keep tweeting about all the interesting things you’re learning and doing, and then I feel I have to follow up and discuss them in our book. So quit it.

[I thought the “so quit it” line was maybe the best one of the message, but I probably should have put it in all caps. Also, I meant to say that it’s all the news items in the podcast that I find time consuming, since they inevitably cause me to dig into them.]

Finally, you and I both know that producing real quality takes time. It’s hard to write good code, and it’s hard to write good prose, and it’s doubly hard to do both at the same time. So this stuff just takes time. Unless you’re that hoser Dave Klein, who produced his fantastic book “Grails Quickly” so quickly (pun intended) that it’s making us all look bad. He’s a freakin’ loser, and I mean that in the nicest possible way.

[Total back-handed compliment for Dave Klein. Didn’t see that one coming, did you? I’m sure he didn’t. As it turns out, the actual title of his book is “Grails: A Quick Start Guide” and can be found through the link at PragProg. Why pick on Dave, other than the fact that he did such an awesome job? One good way to sell books is to generate artificial controversy, and who’s a better target for that than the Klein-meister? Besides, he’s got so many kids at home he’ll never have time to read this message. (Oops! Too over the top? YMMV)]

Keep up the good work and see you both at 2GX,

[Ooh, subtle plug for the SpringOne2GX conference, too. Sweet.]

Ken Kousen
————– End of annotated message ————

See? The message had everything, with even a reference to the 2GX conference, so I was quite surprised when Glen and Sven decided to just summarize the newsy parts. Don’t get me wrong — I was half-terrified that they would read it, and if you listen closely you can almost hear both Glen and Sven uncomfortably debating what to do with it. The result, though, probably left most listeners (almost certainly including my poor co-author) wondering what the heck I was on about in the first place.

Well, now you know. While I doubt it would qualify as worthy of a Grails Podcast “Poll of the Week”, I’m curious to see what you think. Did they do the right thing by leaving out all the good stuff (I mean, “humor”)? Am I not nearly as funny as I think I am? (Wait, don’t answer that one.)

Comments are of course welcome. You can also harass (I mean “tweet”) me on Twitter. I’m @kenkousen over there.

Now back to working on the book…

Minor bug in Grails selenium plugin

There is a minor bug in the selenium plugin for Grails. It has been discussed on the mailing list, but I thought I would also document it here. I’m using Grails 1.0.3 with version 0.4 of the selenium plugin, which wraps selenium core version 0.8.3.

If you install the plugin and try to run the new Grails tasks (create-selenium-test, create-selenium-domain-test, or run-selenium), the system fails with the error

Could not execute method appContext
No such property: appContext for class: ...

It turns out that the way the appContext variable is handled in Grails has changed, and the plugin hasn’t yet updated to accommodate it.

The recommended fix is to go into the “plugins/selenium-0.4/scripts” directory in your Grails project, and replace ${appContext} with ${grailsAppName} in all the Groovy scripts.

If you use the Selenium IDE in Firefox to write your tests, then the fix doesn’t matter until you try to use the run-selenium target. Still, might as well fix it everywhere. This came up on the mailing list back in July, so I assume an updated plugin will be available as soon as the author gets around to it.

I also find that adding the path to firefox.exe to my system path (default is “c:\Program Files\Mozilla Firefox” — don’t you hate Windows paths with spaces??) makes it easier to run the test suite.

Incidentally, unlike Canoo Web Test, you have to make sure your web app is running before executing the test suite. Selenium fires up the browser and puts it through the proper sequence, so the app has to be running first.

I’ve decided that rather than choosing between Selenium and WebTest, I actually like using both. The Selenium IDE in Firefox is really slick and easy to use, while the output reports in WebTest are gorgeous.

%d bloggers like this: