Last updated by jshaffstall 1 year ago
Overview
This plugin integrates the Google AppEngine SDK and deployment tools with Grails.
This plugin only works with the latest Grails 1.3 RC2 release and above. If you are having trouble with the plugin click the 'Faq' tab above as it may have your answer
You need to tell it where your SDK is by setting APPENGINE_HOME or specifying "google.appengine.sdk" in BuildConfig.groovy.
The plugin adds the appengine SDK classes onto your classpath and packages them as part of the WAR, meaning you can reference
com.google.appengine.api.* packges.
To run the development environment and upload there is an
app-engine script:
grails run-app // run the dev environment on port 8080
grails -Dappengine.debug=true run-app // run the dev environment in a debug JVM on port 9999
grails app-engine package // package app ready for deployment to target/war
grails app-engine rollback // rollback last update
grails app-engine logs --file=logs.txt --days=10
Screencast
Checkout this
screencast for an introduction.
The screencast is slightly out of date so make sure to follow the documentation and not the screencast when trying the plugin
Step-by-Step Process
1) Register for a Google AppEngine Account
This can be done at
http://appengine.google.com2) Download and install Grails 1.3 RC2 or above
You can grab Grails from the
Download page
3) Create a Grails Project
grails create-app first-app
cd first-app
4) Match the Grails application name with the Google application
In the AppEngine web interface create an application that matches your Grails application name. If this is not possible create any name and then set the AppEngine application idenfier in Config.groovy:
google.appengine.application="petclinic-grails"
5.1) Uninstall the Tomcat plugin
Grails (1.3.5, at least) by default installs the Tomcat plugin in a new project. This will interfere with running the project via the local AppEngine server, so uninstall Tomcat first
grails uninstall-plugin tomcat
5.2) Install the AppEngine plugin
grails install-plugin app-engine
When prompted choose 'JPA' as the option for persistence.
6) Run the application
Start up the application by typing the following:
This will start the AppEngine development environment on port 8080.
7) Deploy the application
grails set-version 1
grails app-engine package
You then need to run the command:
$APPENGINE_HOME/bin/appcfg.sh update ./target/war
on MacOS and Linux or
%APPENGINE_HOME%/bin/appcfg.cmd update ./target/war
on MS Windows or
$APPENGINE_HOME/bin/appcfg.cmd update ./target/war
on Cygwin.
Persistence
The plugin will currently install support for either JDO or JPA based persistence into a Grails application.
In the case of JDO a
grails-app/conf/jdo-config.xml file is installed into the project when the plugin is installed.
The plugin also automatically configures a Spring
JdoTemplate which you can use to interact with JDO using Spring:
In the case of JPA a
grails-app/conf/persistence.xml file is installed instead.
The plugin also automatically configures a Spring
JpaTemplate which you can use to interact with JPA using Spring:
For example:
def jpaTemplate
def transactionTemplate
def save = {
transactionTemplate.execute( { status ->
def album = new Album(params)
if(!album.hasErrors() && album.validate() ) {
jpaTemplate.persist(album)
jpaTemplate.flush()
flash.message = "Album ${albumInstance.id} created"
redirect(action:show,id:album.id)
}
else {
status.setRollbackOnly()
render(view:'create',model:[album:album])
} } as TransactionCallback )
}Persistent classes can be placed in the grails-app/domain directory. The plugin will automatically enhance them using the DataNucleus tools.
Domain classes MUST be placed in packages otherwise Google's command line tools don't work!
To get GORM-like behavior with dynamic finders and so on you need to install the
GORM-JPA plugin (there currently isn't a GORM API for JDO, sorry!):
grails install-plugin gorm-jpa
Once this is installed you can using of the regular methods provided by the GORM API like save(), delete() and so on as well as dynamic finders.
Authentication
You can use Google's authentication by configuring the following properties in grails-app/conf/Config.groovy
google.appengine.sessionEnabled = true // default true
google.appengine.enableSsl = true // default true
google.appengine.security.useHttps = ["/secure", "/shoppingcart/*", "/admin"]
google.appengine.security.requireAdmin = ["/admin", "/notsecuredadmin"]
google.appengine.security.requireLogin = ["/admin", "/", "/yabbadabbadoo"]
Examples
There is currently an example Grails on AppEngine application that is a port of the Grails petclinic sample running at
http://petclinic-grails.appspot.com/The source code can be found in Github at
http://github.com/grails/grails/tree/c4d2c6e96708ae6ee15f2ac8cef1448052189ab3/grails/samples/petclinic-appengineVersion History
- 0.8.10 - Compatibility with Grails 1.3 RC2
- 0.8.7 - Now possible to use standard run-app command and fixed Log4j errors
- 0.8.5 - Testing classes corrections.
- 0.8.4 - Refactorized how to access to Persistence or Entity Manager Factory. Added some basic capabilities to unit tests appengine related logic.
- 0.8.3 - Fixes NamingException when using JPA, duplicate EntityManagerFactory error and correctly deploys using production environment settings
- 0.8.2 - Added support for authentication configuration, OpenEntityManagerInView/OpenPersistenceManagerInView support and fixed datastore-index bug
- 0.8.1 - Fixed 'grails app-engine log' command, improved authentication, added better error handling when running 'grails run-app'
- 0.8 - Added support for JPA persistence, fixes generate-all bug and automatically uninstalls hibernate plugin on install
- 0.7 - First official release
Bugs
It is true that there are some bugs with this plugin, but most have a solution at this time.
Example: The "DataNucleus Enhancer prevents application from building on Windows OS due to path length exceeding max path length on Windows." - However, there is a work-around for Windows and this wont stop use of the plugin.
This is great news! As you say that there is a work-around for Windows would you please publish that work-around for Windows here so that those using Windows and are experiencing this problem can benefit from that information?
For more information regarding workarounds on windows there is a writeup here:
Google AppEngine on WindowsGenerateViews.groovy (grails generate-views mypackage.MyDomainClass) fails due to a Hibernate dependency. For workaround see http://stackoverflow.com/questions/2981604/grails-1-3-1-error-executing-script-generateviews
Last updated by slippytoad 1 year ago
FAQ
Versioning
Google AppEngine expects non-decimal version numbers, whilst Grails' versioning system starts at 0.1. To get around this you should use non-decimal version numbers:
Permissions
The current preview release of the Google AppEngine SDK has a bug that doesn't allow it to run Groovy code when the full permissions restrictions are used. This will be fixed in the next release, but in the meantime the development environment runs without emulating the permissions restrictions of the actual AppEngine environment.
Index Creation
AppEngine requires that you specify indexes. By default Grails installs a grails-app/conf/datastore-index.xml file into your application that is set to auto-generate indexes during development.
However, realistically you should be manually managing your indexes as per
these instructions. If you don't you may get exceptions in production that don't occur in development.
Static Resources
AppEngine has a
bug in it that means it incorrectly deals with <welcome-file-list> definitions. In order to workaround this the app-engine plugin automatically installs a modified
src/templates/war/web.xml file that removes the
<welcome-file-list> definition.
Domain Classes
You must place domain classes into a package (i.e. not the default package), otherwise grails will complain that it 'could not resolve class for query'.
Inability to obtain ID after a save with gorm-jpa Plugin
If you are using the dynamic or static scaffolding of controllers with gorm-jpa, you will get a null pointer exception on saving an object if you immediately attempt to redirect to show it (as the scaffolded controller does). You need to add flush:true to your save to have immediate access to the ID. This is fully explained in
JIRA bug 1375App Engine SDK
If you upgrade to AppEngine SDK 1.3.2 and you see Exceptions starting your app locally (with grails run-app) try removing all the files in web-app/WEB-INF/lib first. It seems the plugin does not clear out AppEngine jar files on startup.