I have recently started a new project and I decided based on some of the application requirements and its rapid development that I would host it at Google AppEngine.  For a web framework I went with Grails due to the rapid prototyping that it makes possible.

I can’t really go to much into the functionality of the app,  however I thought I would share some of the experiences I’ve had building the application in the Google environment with Grails.  First off,  if you are going to be doing any serious work with Grails then you’ll need to get a copy of Intellij,  the experience developing with it is much better than others I tried (and improving even more in the 9.0M1 release).  The initial cut of the application was written using GORM and against a local database,  however after trying GORM-JPA (it is very early still though moving quickly), I decided that trying to take a RDBMS mapping over to AppEngine datastore was not going to be a productive route.  The first real lesson of AppEngine is understanding the data store,  it is strange but several of the applications I have worked on over the past 4-5 years have started to move away from traditional RDBMS.  I’m not about to get into the NoSQL argument, other than to say ultimately you need to sit down and understand the tools that are available.  AppEngine DataStore is a powerful storage engine (I’m purposefully not calling it a database),  though it does take a little getting used to.  If you are planning to take a look I would start with the recent Google IO presentation by Max Ross.

Since I have been working with HBase lately some of the concepts weren’t so alien, however it I did find that using JPA annotations actually lead me into incorrect thinking at times,  while adding the annotations I was immediately thinking in the RDBMS mapping terms.  Since I wanted to use the JPA annotations, but didn’t feel that GORM-JPA was quite ready I switched over and used the Grails JPA plugin,  in some ways this meant creating a DAO to allow me to interact with the store.  In the end I did this through the creation of a service which I used in the controllers,  it was pretty generic thanks to the nature of groovy – in the end I can see myself probably moving back to GORM later on,  though in the meantime having a closer relationship with the JPA interface allowed me to better understand how relationships were being managed by AppEngine.  GORM has a tendency to abstract you a little to much at times and coming to terms with a new type of storage engine means that abstraction leads to another level of indirection.  I can see that as time passes and the ins and outs of AppEngine Datastore become more like second nature then that indirection is something that is easy to handle,  though at the beginning I think it is easier to get used to the datastore without it there.

Plugins is one of the powerful aspects of Grails, however one of the problems you encounter in the AppEngine world is the file limit (currently 3,000). While adding a lot of UI plugins speeds up development you can quickly find that you have blown the file limit. Also make sure you watch the $USER_HOME/grails/1.1.1/projects/{yourproject}/stage directory, if you start removing things from your application (ie. unneeded JS) then you might well find that they are remaining in the stage directory.

If you are using YUI you can switch to their servers, so that you don’t have to hold all the YUI files,  first add the following to your BootStrap:

def init = {servletContext ->
JavascriptTagLib.LIBRARY_MAPPINGS.yui = []
}

Then in your main.gsp make sure you reference the CSS and JavaScript you need.

If you are using the grails-ui plugin 1.0.4 it is currently using the javax.rmi.UID class to generate UUIDs, this class is blacklisted by GAE/J and therefore you would need to change the GrailsUITagLibService.groovy and remove the import.  I found that I was able to use the UUID class to get a similar effect (see JIRA)

def getUniqueId = { 'gui_' + DigestUtils.md5Hex(UUID.randomUUID().toString()) }

Once you have the basics in place, then you will need security. Obviously Google provides API’s to allow this to exist, however often you need more complex security than is currently provided by the Google API. In Grails I naturally jumped for the Aecgi plugin, however after a few battles with its close connection with Hibernate (I get the feeling that plugin does a little too much and would be well served by being broken up into a several plugins rather than a lot of configuration in one plugin). Next up was Stark Security plugin – I have to admit it was a little new to me, however I was able to quickly implement this in grails and also get it functioning in GAE/J. Basically I needed to create the basic DAO stuff using the plugin then change it to use JPA methods (as seen below):

User.groovy


import org.datanucleus.jpa.annotations.Extension
import org.springframework.security.GrantedAuthority
import org.springframework.security.userdetails.UserDetails
import javax.persistence.*

/**
* This class is the default UserDetails implementation for the Stark Security plugin.
* Since instances of this class will be used by the underlying Spring Security framework across
* Hibernate sessions, we can't have any lazy loading in here (see special handling of roles below).
*/
@Entity
class User implements UserDetails {

@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
@Extension (vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
String id

@Column
String username

@Column
String password

List<String> roles = new ArrayList<String>();

GrantedAuthority[] getAuthorities() {
return roles.collect { new Role(authority:it) } as GrantedAuthority[]
}

boolean isAccountNonLocked() {
return true
}

def setAccountNonLocked(boolean nonLocked) {}

boolean isCredentialsNonExpired() {
return true
}

def setCredentialsNonExpired(boolean nonExpired) {}

boolean isAccountNonExpired() {
return true
}

def setAccountNonExpired(boolean acctNonExpired) {}

boolean isEnabled() {
return true
}

def setEnabled(boolean enabled) {}
}

Role.groovy


class Role implements GrantedAuthority {

String authority

static final ANONYMOUS = 'IS_AUTHENTICATED_ANONYMOUSLY'
// Add your roles here so you can reference them, for instance:
static final ADMIN = 'ROLE_ADMIN_USER'

// This list holds all roles, convenient when you're declaring controller methods
// that should be available to everybody (see AccessController for instance).  When
// you add roles to your system, make sure you add them to this list as well.
static final ALL_ROLES = [ANONYMOUS,ADMIN]

int compareTo(Object o) {
if (o instanceof Role) {
return this.authority.compareTo(o.authority)
}
return 0
}

String toString() {
return authority
}
}

Also once in AppEngine it is a little more sensitve to reflection, with the standard plugin I got:

java.lang.IllegalAccessException: Reflection is not allowed on private int java.util.ArrayList.size

This was down to line 217 of the StarkSecurityGrailsPlugin.groovy having:

if (authFilters.size < 1) {

When it should have been

if (authFilters.size() < 1) {

I opened a JIRA for this one.  Also you might find that plugins embed javascript (such as the Grails UI plugin),  in which case you will want to change the StarkSecurityConfig.groovy to allow access to these files:


authorizations = [
'/': Role.ALL_ROLES,
'/js/**': Role.ALL_ROLES,
'/css/**': Role.ALL_ROLES,
'/images/**': Role.ALL_ROLES,
'/plugins/**': Role.ALL_ROLES,
'/j_acegi_logout': Role.ALL_ROLES
]

Another problem was changing the log4j not to write to the file system (you’ll get a restricted class exception). This is done with:

'null' name:'stacktrace'

While building the system up,  I also discovered the problems of not setting the seralizationUIDs on classes that might end up in session (ie. Role),  make sure you set it on the class or you will need to flush you local cookies after deployment.

Also I found a nasty little problem in the formRemote tag,  basically it would operate in the development server but not on AppEngine itself,  in the end I dug around I found that the JavascriptTagLib.groovy made some assumptions about a variable being a map which it wasn’t (in fact it was a String in this case).  Due to Groovy’s ability to reflect private values (which just feels dangerous),  you would end up with:


<span>[deve11/5.334872088869876828]</span>.<stderr>: java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on private final char[] java.lang.String.value

I ended up having to pull the JavascriptTagLib.groovy into the project and make the fix there, and opened another JIRA in grails for it.

So there it is – a brief little walkthrough getting Grails operating in Google AppEngine. GAE/J feels a little clunky at times and it probably does suffer from being a little rushed out of the door.  However,  after you start to get your head around the restrictions it does start to become a good platform.  Over time I’m sure we are going to see further improvements in the Google Platform,  and while I am still working with the Amazon style Infrastructure as s Service world starting to look more closely at Platform as a Service has opened my eyes to some of its benefits.  The days of managing your database and server could soon be gone – though I think it will be a specific type of application that benefits most.