Where to host your Grails application

As I wrote recently, I have joined the Grails and Groovy crowd. I finished my first simple web application, which was actually more than just a local prototype, but I needed to host it somewhere. As with all Java based web-application, it is much harder to find a good and cheap hosting provider. It is much easier with PHP. So I started to look for a Grails hosting provider and ended up where every Grails developer will be looking sooner or later - this page.

I scrolled down the list and nothing really suited me. I have to admit that I stopped reading carefully after a couple of hosting providers. Since this was just my own web-application to play with, I did not want to spent much for hosting every month. I did another search in Google and came to this German blog entry. The guy basically recommended 3 different hosting providers for Grails applications: eatj.com, javaprovider.net and mor.ph. Out of these he liked mor.ph the most. So I decided to try them first.

Unfortunately I could not find anything related to hosting on their website. I have no idea what they are offering but web-hosting did not jump me off the screen. Next I tried javaprovider.net. This provider has a 30-days trial offer, where you can test your web-application for free basically. Exactly what I wanted. You choose between shared Tomcat or private Tomcat. In the private Tomcat you have 32MB heap memory, in the shared version the heap memory is shared with other applications. I signed up for a shared Tomcat trial account. First of all, the trial account in javaprovider.net is not entirely free anymore. I had to pay $0.50 when signing up. This is to scare idiots off. The account was created immediately. However, they set up a private Tomcat account even though I wanted a shared one. The private account plan would cost me $9.99 every month. Way to much for my little toy website. I selected some stupid sub domain, like tv3.javaprovider.net - it will probably not work anymore when you read this. I entered the MySQL details into the production environment block of my DataSource.groovy file.


dataSource {
    pooled = false                          
    driverClassName = "org.hsqldb.jdbcDriver" 
    username = "sa"
    password = ""    
}
environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'createeate-drop','update'
            url = "jdbc:hsqldb:mem:devDB"
        }
    }   
    test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:hsqldb:mem:testDb"
        }
    }   
    production {
        dataSource {
            pooled = true                          
            driverClassName = "com.mysql.jdbc.Driver"
            dbCreate = "update"
            url = "...." <--- Enter here
            username = "...." <--- Enter here
            password = "...." <--- Enter here
        }
    }
}


Then I packaged everything again using the Maven 2 Grails plugin.


mvn package -Dgrails.env=production


For some reason the WAR file was not build when I ran mvn grails:package -Dgrails.env=production

Finally I deployed the WAR file into my javaprovider.net Tomcat. It worked out of the box! However, as I started to click around for a bit it stopped worked. I checked my Tomcat logfiles and saw a nasty OutOfMemoryError. Obviously 32MB heap is way to little, and this was even the better account plan in javaprovider.net. I opened a ticket and asked them about Grails hosting. They got back to me after a day, saying the I needed at least 256MB heap for running a Grails application and it would cost me around $30/month. This is simply not true! Read on.

While waiting for the ticket reply, I signed up with the last Grails hosting provider that was mentioned in the original blog post - eatj.com. They have a free trial account too, great for testing. The trial account has even 64MB heap. However, their cheapest commercial offer is $9.85/month, so I knew from the start that I would not use them. To make a long story short, I used their MySQL details, repackaged, deployed and it worked fine without any memory issues. Now I knew at least, that 64MB heap would be enough for my Grails app.

In search for a cheaper alternative to host a Grail web application, I saw an offer from a German hosting provider called Netcup. They are offering a vserver with 100MB of guaranteed memory. The price is very low. You pay one time 10€ which is about $14 and 1,69€ per month ($2.40). Since it is a vserver, you have to install everything yourself, like Java, Tomcat, MySQL etc. When you order the account, they set up a Debian Etch for you, including pre-installed Apache and MySQL. I used this image for a bit but their /etc/apt/sources.list file was pretty limited and I struggled to install Java. I switched to Ubuntu Hardy, which I knew. You can switch between images with a few click in a web console. Their Ubuntu image also had a weird sources.list file but I changed it they way how I had it locally and it worked. I installed Java, MySQL, Tomcat 6 and deployed my Grails webapplication. It worked like a charm.

You get a static ip-adress, which is enough for now. No domain needed for testing. You can check it out here. Log in with (reik/schatz). I am watching tons of TV series like Lost, Heroes, True Blood, 24, Prison Break, Friday Night Lights, Supernatural, Dexter etc. Every time I forgot which episode I saw last, so I wrote this little Grails application where you can save the last episode you have seen.

For me the netcup.de vserver is the best option if you want to host a Java based web application using Grails and Groovy. Here is a comparison of the annual prices including one time fees:


  • eatj.com Basic: $98.50

  • javaprovider.net Private: $119.88

  • mor.ph ?

  • netcup.de vserver Aluminium: 30.28€ ($42.71)

JSON in Grails with nested collections

I have totally fallen in love with Grails and Groovy. I am probably the last Java developer in the world to try out Groovy and Grails but it has never been my top priority. So I started to write a little web application for myself, which I will host later on Google App Engine.

One common scenario is that you have nested domain classes. In my case, I have a Show class. A Show is basically a TV series like Lost or Deperate Housewives. Each Show has a list of Season's. These seasons are strictly in order, like Lost has Season 1, 2, 3, 4 and 5 so far. Each Season has a number of Episode's, which are also stricly ordered. Then finally each Episode can be aired in different formats like HDTV, 720p or Standard. This makes up a nice class hierarchie having 1:n relations.




class Show {

String name

static hasMany = [ seasons : Season ]

static mapping = {
table 'ct_show'
}

static constraints = {
name(size:1..100,blank:false)
}
}

class Season {

Integer seasonNumber

static hasMany = [ episodes : Episode ]

static mapping = {
table 'ct_season'
}

static constraints = {
seasonNumber(size:1..100,blank:false)
}
}

class Episode {

Integer episodeNumber

static hasMany = [ formats : Format ]

static mapping = {
table 'ct_episode'
}

static constraints = {
episodeNumber(size:1..100,blank:false)
}
}

class Format {

String name

static mapping = {
table 'ct_format'
}

static constraints = {
name(size:1..100,blank:false)
}
}




Now I had a typical use case, that when you want to use Ajax within you web application, you want the Controller classes to return you domain objects as JSON. In Grails this is easy to accomplish, just read this example. However, I had the big problem that my domain class hierarchy heavily uses nested collections. This will not work when you just do this:



render Season.get(1) as JSON



In this blog post, the last example offers a solution to my problem but it is a rather static example. The idea is to use my root object (Season in my particular case) to produce a JSON string in the format I want and then return it via render as JSON. Building up this String would be quite a big chunk of code in Java probably involving StringBuilder, but Groovy has this great method .collect for Collections. Here is the Groovy code. Try this in Java.



def selectedSeason = Season.get(1)
def seasonJSON = [
id: selectedSeason.id,
seasonNumber: selectedSeason.seasonNumber,
episodes: selectedSeason.episodes.collect{
[
id: it.id,
episodeNumber: it.episodeNumber,
formats: it.formats.collect{
[
id: it.id ,
name: it.name
]
}
]
}
]

render seasonJSON as JSON