(Quick Reference)

2. Getting Started - Reference Documentation

Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith

Version: 1.4.0.M1

2. Getting Started

2.1 Downloading and Installing

The first step to getting up and running with Grails is to install the distribution. To do so follow these steps:
  • Download a binary distribution of Grails and extract the resulting zip file to a location of your choice
  • Set the GRAILS_HOME environment variable to the location where you extracted the zip
    • On Unix/Linux based systems this is typically a matter of adding something like the following export GRAILS_HOME=/path/to/grails to your profile
    • On Windows this is typically a matter of setting an environment variable under My Computer/Advanced/Environment Variables
  • Now you need to add the bin directory to your PATH variable:
    • On Unix/Linux base system this can be done by doing a export PATH="$PATH:$GRAILS_HOME/bin"
    • On windows this is done by modifying the Path environment variable under My Computer/Advanced/Environment Variables

If Grails is working correctly you should now be able to type grails in the terminal window and see output similar to the below:

bc. Welcome to Grails 1.0 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: /Developer/grails-1.0 No script name specified. Use 'grails help' for more info

2.2 Upgrading from previous versions of Grails

Although the Grails development team have tried to keep breakages to a minimum there are a number of items to consider when upgrading a Grails 1.0.x, 1.1.x, 1.2.x, or 1.3.x applications to Grails 1.4. The major changes are described in detail below.

Upgrading from Grails 1.3.x

Plugin Updates

Many plugins need to be updated for usage with Grails 1.4. The following is a list of minimum versions for some commonly used plugins:

  • spring-security-core - 1.1.3
  • resources - 1.0
  • searchable - 0.6
  • mongodb - 1.0.0.M6.1
  • redis - 1.0.0.M6
  • tomcat - 1.4.0.M1
  • hibernate - 1.4.0.M1
  • webflow - 1.4.0.M1

Other plugins may require updates and you may need to verify compatible with a particular Grails plugin.

Grails Console and Shell now required agent for reloading

Reloading for the Grails console and shell is now disabled by default unless you specifically enable the reload agent with the -agent flag:

$ grails -agent console

Abstract Inheritance Changes

In previous versions of Grails abstract classes in grails-app/domain were not treated as persistent. This is no longer the case and has a significant impact on upgrading your application. For example consider the following domain model in a Grails 1.3.x application:

abstract class Sellable {

} class Book extends Sellable {

}

In Grails 1.3.x you would get a BOOK table and the properties from the Sellable class would be stored within the BOOK table. However, in Grails 1.4.x you will get SELLABLE table and the default table-per-hierarchy inheritance rules apply with all properties of the Book stored in the SELLABLE table.

You have two options when upgrading in this scenario:

  1. Move the abstract Sellable class into the src/groovy package. If the Sellable class is in the src/groovy directory it will no longer be regarded a persistent
  2. Use the database migration plugin to apply the appropriate changes to the database (typically renaming the table to the root abstract class of the inheritance tree)

Criteria Queries Default to INNER JOIN

The previous default of LEFT JOIN for criteria queries across associations is now INNER JOIN.

Controller Public Methods

As of Grails 1.4, public methods of controllers are now treated as actions. If you were relying on the use of methods for privacy controls then this could result in unexpected behavior. To resolve this issue you should mark all methods of your application that are not to be exposed as private methods.

The redirect Method

The redirect method no longer commits the response. The result of this is code that relies of this behavior will break in 1.4. For example:

redirect action:"next"
if(response.committed) {
	// do something
}

In this case in Grails 1.3.x and below the response.committed property would return true and the if block will execute. In Grails 1.4 this is no longer the case and you should instead use the new isRedirect method of the request object:

redidrect action:"next"
if(request.redirected) {
	// do something
}

Content Negotiation

As of Grails 1.4 the withFormat method of controllers no longer takes into account the request content type (dictated by the CONTENT_TYPE header), but instead deals exclusively with the response content type (dictated by the ACCEPT header or file extension). This means that if your application has code that relies on reading XML from the request using withFormat this will no longer work:

def processBook() {
	withFormat {
		xml {
			// read request XML
		}
		html {
			// read request parameters
		}
	}
}

Instead you will need to use the withFormat method provided on the request object:

def processBook() {
	request.withFormat {
		xml {
			// read request XML
		}
		html {
			// read request parameters
		}
	}
}

HSQLDB Has Been Replaced With H2

HSQLDB is still bundled with Grails but not configured as a default runtime dependency. Upgrade options include replacing HSQLDB references in DataSource.groovy with H2 references or adding HSQLDB as a runtime dependency for the application.

Adding HSQLDB as a runtime dependency can be done in BuildConfig.groovy with something like this:

grails.project.dependency.resolution = {
    inherits("global") {
    }
    repositories {
        grailsPlugins()
        grailsHome()
        grailsCentral()
    }

dependencies { // Add HSQLDB As A Runtime Dependency runtime 'hsqldb:hsqldb:1.8.0.10' } }

A default DataSource.groovy which is compatible with H2 might look like this:

dataSource {
    driverClassName = "org.h2.Driver"
    username = "sa"
    password = ""
}
// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop','update'
            url = "jdbc:h2:mem:devDb"
        }
    }
    test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:mem:testDb"
        }
    }
    production {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:prodDb"
        }
    }
}

Updated Underlying APIs

Grails 1.4 contains updated dependencies including Servlet 3.0, Tomcat 7, Spring 3.1, Hibernate 3.6 and Groovy 1.8. This means that certain plugins and applications that that depend on earlier versions of these APIs may no longer work. For example the Servlet 3.0 HttpServletRequest interface includes new methods, if a plugin implements this interface for Servlet 2.5 but not for Servlet 3.0 then said plugin will break. The same can be said of any Spring interface.

Removal of release-plugin

The built in release-plugin command for releases plugins to the central Grails plugin repository has been removed. The new release plugin should be used instead which provides an equivalent publish-plugin command

Removal of Deprecated Classes

The following deprecated classes have been removed: grails.web.JsonBuilder, grails.web.OpenRicoBuilder

Upgrading from Grails 1.2.x

Plugin Repositories

As of Grails 1.3, Grails no longer natively supports resolving plugins against secured SVN repositories. Grails 1.2 and below's plugin resolution mechanism has been replaced by one built on Ivy the upside of which is that you can now resolve Grails plugins against Maven repositories as well as regular Grails repositories.

Ivy supports a much richer setter of repository resolvers for resolving plugins with, including support for Webdav, HTTP, SSH and FTP. See the section on resolvers in the Ivy docs for all the available options and the section of plugin repositories in the user guide which explains how to configure additional resolvers.

If you still need support for resolving plugins against secured SVN repositories then the IvySvn project provides a set of Ivy resolvers for resolving against SVN repositories.

Upgrading from Grails 1.1.x

Plugin paths

In Grails 1.1.x typically a pluginContextPath variable was used to establish paths to plugin resources. For example:

<g:resource dir="${pluginContextPath}/images" file="foo.jpg" />

In Grails 1.2 views have been made plugin aware and this is no longer necessary:

<g:resource dir="images" file="foo.jpg" />

Additionally the above example will no longer link to an application image from a plugin view. To do so you need to change the above to:

<g:resource contextPath="" dir="images" file="foo.jpg" />

The same rules apply to the javascript and render

Tag and Body return values

Tags no longer return java.lang.String instances but instead return a StreamCharBuffer instance. The StreamCharBuffer class implements all the same methods as String, however code like this may break:

def foo = body()
if (foo instanceof String) {
    // do something
}

In these cases you should use the java.lang.CharSequence interface, which both String and StreamCharBuffer implement:

def foo = body()
if (foo instanceof CharSequence) {
    // do something
}

New JSONBuilder

There is a new version of JSONBuilder which is semantically different to earlier versions of Grails. However, if your application depends on the older semantics you can still use the now deprecated implementation by settings the following property to true in Config.groovy:

grails.json.legacy.builder=true

Validation on Flush

Grails now executes validation routines when the underlying Hibernate session is flushed to ensure that no invalid objects are persisted. If one of your constraints (such as a custom validator) is executing a query then this can cause an addition flush resulting in a StackOverflowError. Example:

static constraints = {
    author validator: { a ->
        assert a != Book.findByTitle("My Book").author
    }
}

The above code can lead to a StackOverflowError in Grails 1.2. The solution is to run the query in a new Hibernate session (which is recommended in general as doing Hibernate work during flushing can cause other issues):

static constraints = {
    author validator: { a ->
        Book.withNewSession {
            assert a != Book.findByTitle("My Book").author
        }
    }
}

Upgrading from Grails 1.0.x

Groovy 1.6

Grails 1.1 and above ship with Groovy 1.6 and no longer supports code compiled against Groovy 1.5. If you have a library that is written in Groovy 1.5 you will need to recompile it against Groovy 1.6 before using it with Grails 1.1.

Java 5.0

Grails 1.1 now no longer supports JDK 1.4, if you wish to continue using Grails then it is recommended you stick to the Grails 1.0.x stream until you are able to upgrade your JDK.

Configuration Changes

1) The setting grails.testing.reports.destDir has been renamed to grails.project.test.reports.dir for consistency.

2) The following settings have been moved from grails-app/conf/Config.groovy to grails-app/conf/BuildConfig.groovy:

    • grails.config.base.webXml
    • grails.project.war.file (renamed from grails.war.destFile)
    • grails.war.dependencies
    • grails.war.copyToWebApp
    • grails.war.resources

3) The grails.war.java5.dependencies option is no longer supported, since Java 5.0 is now the baseline (see above).

4) The use of jsessionid (now considered harmful) is disabled by default. If your application requires jsessionid you can re-enable its usage by adding the following to grails-app/conf/Config.groovy:

grails.views.enable.jsessionid=true

5) The syntax used to configure Log4j has changed. See the user guide section on Logging for more information.

Plugin Changes

Since 1.1, Grails no longer stores plugins inside your PROJECT_HOME/plugins directory by default. This may result in compilation errors in your application unless you either re-install all your plugins or set the following property in grails-app/conf/BuildConfig.groovy:

grails.project.plugins.dir="./plugins"

Script Changes

1) If you were previously using Grails 1.0.3 or below the following syntax is no longer support for importing scripts from GRAILS_HOME:

Ant.property(environment:"env")
grailsHome = Ant.antProject.properties."env.GRAILS_HOME"

includeTargets << new File ( "${grailsHome}/scripts/Bootstrap.groovy" )

Instead you should use the new grailsScript method to import a named script:

includeTargets << grailsScript("_GrailsBootstrap")

2) Due to an upgrade to Gant all references to the variable Ant should be changed to ant.

3) The root directory of the project is no long on the classpath, the result is that loading a resource like this will no longer work:

def stream = getClass().classLoader.getResourceAsStream("grails-app/conf/my-config.xml")

Instead you should use the Java File APIs with the basedir property:

new File("${basedir}/grails-app/conf/my-config.xml").withInputStream { stream ->
    // read the file
}

Command Line Changes

The run-app-https and run-war-https commands no longer exist and have been replaced by an argument to run-app:

grails run-app -https

Data Mapping Changes

1) Enum types are now mapped using their String value rather than the ordinal value. You can revert to the old behavior by changing your mapping as follows:

static mapping = {
    someEnum enumType:"ordinal"
}

2) Bidirectional one-to-one associations are now mapped with a single column on the owning side and a foreign key reference. You shouldn't need to change anything, however you may want to drop the column on the inverse side as it contains duplicate data.

REST Support

Incoming XML requests are now no longer automatically parsed. To enable parsing of REST requests you can do so using the parseRequest argument inside a URL mapping:

"/book"(controller:"book",parseRequest:true)

Alternatively, you can use the new resource argument, which enables parsing by default:

"/book"(resource:"book")

2.3 Creating an Application

To create a Grails application you first need to familiarize yourself with the usage of the grails command which is used in the following manner:

grails [command name]

In this case the command you need to execute is create-app:


grails create-app helloworld

This will create a new directory inside the current one that contains the project. You should now navigate to this directory in terminal:


cd helloworld

2.4 A Hello World Example

To implement the typical "hello world!" example run the create-controller command:


grails create-controller hello

This will create a new controller (Refer to the section on Controllers for more information) in the grails-app/controllers directory called helloworld/HelloController.groovy.

If no package is specified with create-controller script, Grails automatically uses the application name as the package name.

Controllers are capable of dealing with web requests and to fulfil the "hello world!" use case our implementation needs to look like the following:

package helloworld
class HelloController {
    def world = {
        render "Hello World!"
    }
}

Job done. Now start-up the container with another new command called run-app:


grails run-app

This will start-up a server on port 8080 and you should now be able to access your application with the URL: http://localhost:8080/helloworld

The result will look something like the following screenshot:

This is the Grails intro page which is rendered by the web-app/index.gsp file. You will note it has a detected the presence of your controller and clicking on the link to our controller we can see the text "Hello World!" printed to the browser window.

2.5 Getting Set-up in an IDE

IntelliJ IDEA

IntelliJ IDEA and the JetGroovy plug-in offer good support for Groovy & Grails developer. Refer to the section on Groovy and Grails support on the JetBrains website for a feature overview.

To integrate Grails with IntelliJ run the following command to generate appropriate project files:

grails integrate-with --intellij

NetBeans

A good Open Source alternative is Sun's NetBeans, which provides a Groovy/Grails plugin that automatically recognizes Grails projects and provides the ability to run Grails applications in the IDE, code completion and integration with Sun's Glassfish server. For an overview of features see the NetBeans Integration guide on the Grails website which was written by the NetBeans team.

Eclipse

We recommend that users of Eclipse looking to develop Grails application take a look at SpringSource Tool Suite, which offers built in support for Grails including automatic classpath management, a GSP editor and quick access to Grails commands. See the STS Integration page for an overview.

TextMate

Since Grails' focus is on simplicity it is often possible to utilize more simple editors and TextMate on the Mac has an excellent Groovy/Grails bundle available from the Texmate bundles SVN.

To integrate Grails with TextMate run the following command to generate appropriate project files:

grails integrate-with --textmate

Alternatively TextMate can easily open any project with its command line integration by issuing the following command from the root of your project:

mate .

2.6 Convention over Configuration

Grails uses "convention over configuration" to configure itself. This typically means that the name and location of files is used instead of explicit configuration, hence you need to familiarize yourself with the directory structure provided by Grails.

Here is a breakdown and links to the relevant sections:

2.7 Running an Application

Grails applications can be run with the built in Tomcat server using the run-app command which will load a server on port 8080 by default:

grails run-app

You can specify a different port by using the server.port argument:

grails -Dserver.port=8090 run-app

More information on the run-app command can be found in the reference guide.

2.8 Testing an Application

The create-* commands in Grails automatically create integration tests for you within the test/integration directory. It is of course up to you to populate these tests with valid test logic, information on which can be found in the section on Testing. However, if you wish to execute tests you can run the test-app command as follows:

grails test-app

Grails also automatically generates an Ant build.xml which can also run the tests by delegating to Grails' test-app command:

ant test

This is useful when you need to build Grails applications as part of a continuous integration platform such as CruiseControl.

2.9 Deploying an Application

Grails applications are deployed as Web Application Archives (WAR files), and Grails includes the war command for performing this task:

grails war

This will produce a WAR file under the target directory which can then be deployed as per your container's instructions.

NEVER deploy Grails using the run-app command as this command sets Grails up for auto-reloading at runtime which has a severe performance and scalability implication

When deploying Grails you should always run your containers JVM with the -server option and with sufficient memory allocation. A good set of VM flags would be:

-server -Xmx512M

2.10 Supported Java EE Containers

Grails runs on any Servlet 2.5 and above container and is known to work on the following specific container products:
  • Tomcat 7
  • Tomcat 6
  • SpringSource tc Server
  • Eclipse Virgo
  • GlassFish 3
  • GlassFish 2
  • Resin 4
  • Resin 3
  • JBoss 6
  • JBoss 5
  • Jetty 7
  • Jetty 6
  • IBM Websphere 7.0
  • IBM Websphere 6.1
  • Oracle Weblogic 10.3
  • Oracle Weblogic 10
  • Oracle Weblogic 9

Some containers have bugs however, which in most cases can be worked around. A list of known deployment issues can be found on the Grails wiki.

2.11 Generating an Application

To get started quickly with Grails it is often useful to use a feature called Scaffolding to generate the skeleton of an application. To do this use one of the generate-* commands such as generate-all, which will generate a controller and the relevant views:

grails generate-all Book

2.12 Creating Artefacts

Grails ships with a few convenience targets such as create-controller, create-domain-class and so on that will create Controllers and different artefact types for you.
These are merely for your convenience and you can just as easily use an IDE or your favourite text editor.
For example to create the basis of an application you typically need a domain model:

grails create-domain-class book

This will result in the creation of a domain class at grails-app/domain/Book.groovy such as:

class Book {
}

There are many such create-* commands that can be explored in the command line reference guide.