I recently moved one of my applications to Google AppEngine. What I found missing was an explanatory tutorial to get started. As I mostly work with C#, I kept running into issues simply because I wasn’t too familiar with the technologies used.
Thus I’m writing this easy to follow all-steps-included tutorial, to help people whom are in a similar position to quickly get started developing with Grails for Google AppEngine.
This tutorial will take you through setting up a simple Grails application running on Google AppEngine; using the app-engine and GORM-JPA plugins to Grails. If you run into trouble, I’ve added a trouble shooting section at the end.
First of make sure you have the latest version of the Google AppEngine SDK, and Grails 1.1.1 or better. If you want to deploy your application to Google AppEngine, make sure you have an active account.
I also added a Known Issues section at the end, it’s there to assist you if you run into trouble.
Lets get started.
Create a Grails Application
First create a Grails Application using the create-app command. For this tutorial we’re creating an application called AppEngineDemo; but the name is not important.
C:\Users\Morten\IdeaProjects>grails create-app Welcome to Grails 1.1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: c:\dev\grails-1.1.1 Base Directory: C:\Users\Morten\IdeaProjects Running script c:\dev\grails-1.1.1\scripts\CreateApp_.groovy Environment set to development Application name not specified. Please enter: AppEngineDemo
Install the App-Engine plugin
The app-engine plugin requires a environment variable to be set to the location in which the Google SDK is installed. I recommend you take a minute or two to read through the plugin information page. I’ll add some examples form running the installation on the command line.
Move to the newly created application and install the app-engine plugin to the application.
C:\Users\Morten\IdeaProjects>cd AppEngineDemo C:\Users\Morten\IdeaProjects\AppEngineDemo>grails install-plugin app-engine Welcome to Grails 1.1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: c:\dev\grails-1.1.1 Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo Running script c:\dev\grails-1.1.1\scripts\InstallPlugin.groovy Environment set to development Reading remote plugin list ... Reading remote plugin list ... Plugin list out-of-date, retrieving..
During the installation the plugin will ask you which persistence provider you want to use. We want to use the GORM-JPA plugin so select JPA for persistence.
Do you want to use JPA or JDO for persistence? (jpa, jdo) jpa
This will create a file called persistance.xml in your Grails conf directory. In this file we will specify which domain objects we can persist to the Google AppEngine data storage.
Install GORM-JPA plugin
The GORM-JPA plugin will allow us to use the convenient dynamic methods for persistence; for example save() or findby…()
It is a straight forward to install the plugin
C:\Users\Morten\IdeaProjects\AppEngineDemo>grails install-plugin gorm-jpa Welcome to Grails 1.1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: c:\dev\grails-1.1.1 Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo Running script c:\dev\grails-1.1.1\scripts\InstallPlugin.groovy Environment set to development Reading remote plugin list ...
Create a domain class
We want to create a domain class for the application, in this tutorial we will create a domain class called Note.
C:\Users\Morten\IdeaProjects\AppEngineDemo>grails create-domain-class Welcome to Grails 1.1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: c:\dev\grails-1.1.1 Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo Running script c:\dev\grails-1.1.1\scripts\CreateDomainClass.groovy Environment set to development Domain class name not specified. Please enter: Note Created DomainClass for Note Created Tests for Note
Next we generate the necessary controllers and views for the Note domain class.
C:\Users\Morten\IdeaProjects\AppEngineDemo>grails generate-all Note Welcome to Grails 1.1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: c:\dev\grails-1.1.1 Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo Running script c:\dev\grails-1.1.1\scripts\GenerateAll.groovy --- Generating views for domain class Note ... Generating controller for domain class Note ... Finished generation for domain class Note
Move the domain classes into a package
The storage platform used by Google AppEngine doesn’t allow you to have your persisted domain classes in the default package. Not to worry, this is also good practice. We move our Note domain class into the package called persisted.
package persisted;
import javax.persistence.*;
// import com.google.appengine.api.datastore.Key;
class Note implements Serializable {
Long id
}
Note the green code line in the above code.
Might as well add some code while were at it. The complete code for the Note domain class should be the following:
package persisted;
import javax.persistence.*;
// import com.google.appengine.api.datastore.Key;
class Note implements Serializable {
Long id
String message
}
Update the domain class with annotations
Now we must specify that the Note class can be persisted, and how it will be persisted. This is done using JPA annotations.
You might have noticed the @Entity, @Id, @GeneratedValue… lines in the above code. These are JPA annotations added by Grails when you created the domain class. Now we must specify one for our added Message property.
We just want to say that it should be persisted along with the class. For this we add the @Basic annotation above the line declaring the message property. This will tell the persistence layer that this property should be saved.
package persisted;
import javax.persistence.*;
// import com.google.appengine.api.datastore.Key;
@Entity
class Note implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id
@Basic
String message
}
A list of the JPA annotations and their usages can be found here.
Generate the views and controllers
Now it’s time to generate view and controllers for the Note class. This is done as normal, specifying which class to generate for.
C:\Users\Morten\IdeaProjects\AppEngineDemo>grails generate-all persisted.Note Welcome to Grails 1.1.1 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: c:\dev\grails-1.1.1 Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo Running script c:\dev\grails-1.1.1\scripts\GenerateAll.groovy Environment set to development [groovyc] Compiling 1 source file to C:\Users\Morten\.grails\1.1.1\projects\AppEngineDemo\classes [copy] Copying 1 file to C:\Users\Morten\.grails\1.1.1\projects\AppEngineDemo [groovyc] Compiling 1 source file to C:\Users\Morten\.grails\1.1.1\projects\AppEngineDemo\classes [copy] Copying 1 file to C:\Users\Morten\.grails\1.1.1\projects\AppEngineDemo Generating views for domain class persisted.Note ... Generating controller for domain class persisted.Note ... Finished generation for domain class persisted.Note C:\Users\Morten\IdeaProjects\AppEngineDemo>
Notice that I specified the package name for the class.
First time deployment to Google AppEngine
Create an application on Google AppEngine using Google’s AppEngine website. When you create your application you specify an name for it. You need to include this name in the grails-app/conf/config.groovy file in your application. Add the following line to the file:
google.appengine.application = "<your application name>"
To host your application on Google AppEngine you need to set the version to a number between 1-100. It has to be an integer, floats are not accepted.
then do the following:
grails set-version 1
grails app-engine package
$APPENGINE_HOME/bin/appcfg.sh update ./target/war
and now to deploy
grails app-engine deploy
Congratulations, your first, basic Google AppEngine application is now running.
Known Issues
Since Grails on Google AppEngine is pretty new, not to mention Java on Google AppEngine. There are still some issues to work through.
Staging dir not cleared
Before we start I just want to mention some known Issues. There is an issue where the staging dir is not removed, you have to delete this manually. You can find it under:
<user directory>\.grails\1.1.1\projects\<projectname>\stage
the 1.1.1 is the version Grails your using. This causes issues if you install the ui-performance plugin.
Rendering JSON
There is also an issue with rendering JSON. Rendering JSON can cause access exceptions when rendering entities fetched using the GORM. Please see this blog post for details.
Update: I recentlly wrote this post on Fun times with JSON rendering. Containing more details about JSON Rendering.
Generating controllers
You can run into issues generating controllers and views for your domain classes. The current workaround as far as I know is to install the hibernate plugin, generate the views or controllers, then uninstall the hibernate plugin. You can see the details here.
Command Line too long on Windows machines
If your on a Windows machine you might run into a problem where you cannot enhance your classes (preparing them for storage on the GoogleAppEngine data store). The problem is that the command line when enhancing them becomes too long. You can find more details in my previous blog posts on the subject.
Saving Entities with constraints
If you add constraints to your classes you can run into issues where Google AppEngine will try to save the entity using the wrong class. More details in this blog post.
Recommended reading
Here is link to the open JIRA issues for the AppEngine plugin.
If you find any errors in this tutorial or have ideas to improve it, please let me know.
Hope it helps!
#1 by Matt Newboult on August 24, 2009 - 09:14
Thanks for the example – do you have an example of an app with multiple relationships at the domain level. I’m struggling to understand how relationships should be mapped using jpa on the app engine.
Any help appreciated.
#2 by admin on August 24, 2009 - 10:00
Thanks for the feedback
But, sorry no relationship examples yet. I’m currently working on sending emails. I’ll make sure to make relationships top priority after emailing.
#3 by John on August 29, 2009 - 18:41
Are you sure you need annotations? I have tried without them and it seems to persists. (I can’t really test as there is no option to bounce the server, but I have tried uploading new code (adding more fields) and fields with annotations are kept.
#4 by admin on September 6, 2009 - 13:42
As far as I know you need annotations, else how does JPA know how to persist your entities. Last time I tried saving entities without annotations on Google AppEngine. It failed. Then again, they have done some updates since.
#5 by Royce Fullerton on November 16, 2009 - 11:46
Thank you for sharing this information. I am up and running but not sure where to go next. I am currently in the process of deciding whether to go with Java & JSP for my app engine application or to go through the learning process with Grails. I see someone shared a google app engine GORM plugin. Have you had anytime to play around with it? http://www.grails.org/plugin/appengine-gorm
I’m looking forward to learning more from your experiences, keep sharing!
#6 by Morten on November 16, 2009 - 12:13
@Royce Fullerton
Hi Royce! Glad I could help. I havn’t tried the GORM-plugin yet. The grails project took a downer when my laptop krashed. I’ve yet to get everything up and running again.
It looked interesting tho. While I havn’t had timeout problems while storing objects to the AppEngine database, I can see the need for it. The timeouts on AppEngine are non-forgiving.
One thing you should be aware of is that, right now, the appengine takes a long time to start up Grails. The initial requests to the AppEngine hosted runtime will most likely timeout due to the hardexecution limit. I have yet to test with the latests version of Grails though. Hopefully Grails loads faster, and I’ve heard rumors that Google is improving things on their end as well. But it is something to consider when making your choice.
#7 by Christian Naeger on November 25, 2009 - 17:01
Hi, I also experimented with grails on app-engine quite a while …. however, I could not find a working non-trivial example so far … as soon as it comes to one-to-many relationships in the domain classes there seem to be lots of problems …
#8 by Lim Chee Kin on November 29, 2009 - 18:10
Hi,
I am the author of appengine-gorm plugin, the motivation I wrote this plugin to support batch insert operation. As I am unable to make the one-to-many relationship by using annotation (@OneToMany) working in Google App Engine after so many attempts, I decided to manage the relationship manually instead of using the mapping. However, while I attempt to save the objects in the many side of the one-to-many relationship, I am facing request timeout of google app engine. Then, I find out that the low level API of datastore support persist many objects in one API call, so there is the born of this plugin. Hopefully, it is benefit you and others.
Lastly, I managed make the one-to-many relationship working manually and without the mapping. Please look at live demo app called GrailsFuse at http://grailsfuse.vobject.com/.
I welcome your feedback and comments. Please feel free to drop me an email at limcheekin at vobject dot com.
Thanks.
#9 by Morten on November 29, 2009 - 21:57
On that note I also rolled my own on one-to-many.
However, in the GORM-JPA plugin version 0.6, this should supposedly be fixed.
I havn’t managed to install it yet however. When I try installing it for Grails 1.2.0 it fails on dependencies.
Thanks for the update
#10 by Lim Chee Kin on November 30, 2009 - 04:33
@Morten
Thanks for the update for the release of GORM-JPA plugin version 0.6. Any clue on when the plugin going to release?
In my opinion, the appengine-gorm plugin still very handy for batch data operation in google app engine even after the issue of @OneToMany has been fixed in next release of GORM-JPA plugin. That’s the reason I chose to released the plugin.
#11 by Morten on November 30, 2009 - 09:58
@Lim Chee Kin
Not to worry I agree wholeheartily that the batch plugin is a handy plugin. I expect to be using it personally in a month or two.
#12 by Richard on December 9, 2009 - 05:30
Thanks for the great tutorial. Have not played with Grails for a couple of years and was interested in running something on Google App Engine.
I am having a problem when trying to run the command “grails generate-all persisted.Note”
I’m getting the following error:
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named transactions-optional
Any ideas on how to solve this?
#13 by Morten on December 13, 2009 - 20:15
@Richard
Hi Richard, without any other description I believe this error to be the one I talk about under known issues.
“You can run into issues generating controllers and views for your domain classes. The current workaround as far as I know is to install the hibernate plugin, generate the views or controllers, then uninstall the hibernate plugin.”
Let me know how it goes, and good luck
#14 by Chris de Groot on February 9, 2010 - 04:02
Hi Richard,
Many thanks for your tutorial. It was helpful to get started. I have one comment to make for others trying it though and that is *avoid Windows* as far as I can workout there are enough issues on Windows related to long paths that it does not work. I tried many combinations of Grails, GAE-SDK and the appengine plugin. I tried Linux and everything works fine in the different things I have tried.
PS: I find it interesting how many developers have moved to Macs or Linux. At least in the GAE/Grails world Windows appears an oddity.
Thanks C.
#15 by joe on February 13, 2010 - 03:53
Hi, and thanks for the tutorial. I tired a simple little test app using the tutorial. I created a domain and tried to create an integration test with a simple .save() and retrieve. My assertNotNull failed on the id retrieval “assertNotNull user.id” which i believe should be generated with:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id
#16 by Morten on February 15, 2010 - 09:43
@joe
Hi Joe!
Sorry for the late reply. Are you wrapping your save() in a transaction? I’ve noticed that unless I commit my transactions I cannot read the Id afterwards.
It has something todo with AppEngine prefeering to do the actual commit asynch, to avoid locking the url processing unless you really need the Id.
#17 by Ken on March 8, 2010 - 07:16
I keep running into HardDeadlineExceeded exceptions when using Grails under AppEngine. I can’t seem to get even a trivial application to behave reasonably.
Do you run into this? Are there examples of non-trivial applications or even trivial ones written in Grails that work reliably under App-Engine? What’s the secret?
Thanks!
#18 by Morten on March 17, 2010 - 11:12
Hi Ken!
This is a real issue when writing Grails Applications for Google AppEngine. I have yet to find a solution to it.
The problem is that the grails runtime takes a long time to warm up. Too long for appengine infact.
Some people have tried to create a job that access your application every minute, to keep the runtime warm.
However since AppEngine is load balanced, you cannot garantuee that the job will ask for a response from the same server.
End result, you just eat up your qouta.
Now rumors has it that Google have done some profiling for Grails on AppEngine and came up with some areas to “fix”. I saw a tweet from Graeme a while back when there might be a possilibty to have some work done in that area for Grails 1.3.x.
But yes, this is a blocker for using Grails in AppEngine and I have yet to solve it. If anyone else figures it out please do tell.
#19 by Morten on March 17, 2010 - 11:13
Also terribly sorry for the late reply.
#20 by Keith Conner on August 4, 2010 - 20:07
Morten,
I recently got excited about Grails and GAE (I know, behind the power curve). do you have any updates with the new plugin. also, jsut to chip in, but some people are advocating GAELYK for Groovy/ GAE because of the pitfalls of grails/gae. Are you still developing on the GAE? can you forward me an example of a site you have done?
Thanks,
Keith
#21 by Morten on August 4, 2010 - 20:51
To be honest, I moved away from Grails and started using the Python SDK. The biggest issue is that the initial startup of grails on AppEngine takes too long. GAELYK also suffers from this, but not as much.
#22 by cremersstijn on February 25, 2011 - 13:06
I’m currently experimenting with grails and google app engine. Has anybody succeeded in deploying grails to app engine? or should i switch to gaelyk?
#23 by Morten on February 25, 2011 - 15:52
Deployment shouldn’t be a problem. Then again I havn’t tried it in a while. GAELYK probably will give you better performance once up on AppEngine though.