2 Getting Started - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith
Version: 2.0.4
Table of Contents
2 Getting Started
2.1 Installation Requirements
Before installing Grails you will need as a minimum a Java Development Kit (JDK) installed version 1.6 or above. Download the appropriate JDK for your operating system, run the installer, and then set up an environment variable calledJAVA_HOME
pointing to the location of this installation. If you're unsure how to do this, we recommend the video installation guides from grailsexample.net:
These will show you how to install Grails too, not just the JDK.On some platforms (for example OS X) the Java installation is automatically detected. However in many cases you will want to manually configure the location of Java. For example:export JAVA_HOME=/Library/Java/Home
export PATH="$PATH:$JAVA_HOME/bin"
2.2 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
- Then add the
bin
directory to yourPATH
variable: - On Unix/Linux based systems this can be done by adding
export PATH="$PATH:$GRAILS_HOME/bin"
to your profile - On Windows this is done by modifying the
Path
environment variable underMy Computer/Advanced/Environment Variables
grails -version
in the terminal window and see output similar to this:
Grails version: 2.0.0
2.3 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 2.0. The major changes are described in more detail below, but here's a brief summary of what you might encounter when upgrading from Grails 1.3.x:environment
bean added by Spring 3.1, which will be auto-wired into properties of the same name.- Logging by convention packages have changed, so you may not see the logging output you expect. Update your logging configuration as described below.
- HSQLDB has been replaced with H2 as default in-memory database. If you use the former, either change your data source to H2 or add HSQLDB as a runtime dependency.
- The
release-plugin
command has been removed. You must now install the Release plugin and use itspublish-plugin
command instead. - The
redirect()
method no longer commits the response, soisCommitted()
will returnfalse
. If you use that method, then callrequest.isRedirected()
instead. - The
redirect()
method now uses the grails.serverURL config setting to generate the redirect URL. You may need to remove the setting, particularly from the development and test environments. withFormat()
no longer takes account of the request content type. If you want to do something based on the request content type, userequest.withFormat()
.- Adaptive AJAX tags using Prototype will break. In this situation you must install the new Prototype plugin.
- If you install Resources (or it is installed automatically), tags like
<g:javascript>
won't write anything to the page until you add the<r:layoutResources/>
tags to your layout. - Resources adds a '/static' URL, so you may have to update your access control rules accordingly.
- Some plugins may fail to install because one or more of their dependencies can not be found. If this happens, the plugin probably has a custom repository URL that you need to add to your project's
BuildConfig.groovy
. - The behaviour of abstract domain classes has changed, so if you use them you will either have to move the abstract classes to 'src/groovy' or migrate your database schema and data.
- Criteria queries default to INNER_JOIN for associations rather than OUTER_JOIN. This may affect some of your result data.
- Constraints declared for non-existent properties will now throw an exception.
beforeValidate()
may be called two or more times during a request, for example once on save() and once just before the view is rendered.- Public methods in controllers will now be treated as actions. If you don't want this, make them protected or private.
- The new unit testing framework won't work with the old
GrailsUnitTestCase
class hierarchy. Your old tests will continue to work, but if you wish to use the new annotations, do not extend any of the*UnitTestCase
classes. - Output from Ant tasks is now hidden by default. If your scripts are using
ant.echo()
,ant.input()
, etc. you might want to use alternative mechanisms for output. - Domain properties of type java.net.URL may no longer work with your existing data. The serialisation mechanism for them appears to have changed. Consider migrating your data and domain models to String.
- The Ivy cache location has changed. If you want to use the old location, configure the appropriate global setting (see below) but be aware that you may run into problems running Grails 1.3.x and 2.x projects side by side.
- With new versions of various dependencies, some APIs (such as the Servlet API) may have changed. If you have code that implements any of those APIs, you will need to update it. Problems will typically manifest as compilation errors.
- The following deprecated classes have been removed:
grails.web.JsonBuilder
andgrails.web.OpenRicoBuilder
.
Upgrading from Grails 1.3.x
Changes to web.xml template
If you have customized the web.xml provided bygrails install-templates
then you will need to update this customized template with the latest version provided by Grails. Failing to do so will lead to a ClassNotFoundException for the org.codehaus.groovy.grails.web.util.Log4jConfigListener
class.Groovy 1.8 Changes
Groovy 1.8 is a little stricter in terms of compilation so you may be required to fix compilation errors in your application that didn't occur under Grails 1.3.x.Groovy 1.8 also requires that you update many of the libraries that you may be using in your application. Libraries known to require an upgrade include:- Spock
- Geb
- GMock (upgrade unavailable as of this writing)
New 'environment' bean
Spring 3.1 adds a new bean with the name 'environment'. It's of typeEnvironment
(in package org.springframework.core.env
) and it will automatically be autowired into properties with the same name. This seems to cause particular problems with domain classes that have an environment
property. In this case, adding the method:
void setEnvironment(org.springframework.core.env.Environment env) {}
HSQLDB Has Been Replaced With H2
HSQLDB is still bundled with Grails but is 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.If you want to run an application with different versions of Grails, it's simplest to add HSQLDB as a runtime dependency, which you can do in BuildConfig.groovy:grails.project.dependency.resolution = {
inherits("global") {
}
repositories {
grailsPlugins()
grailsHome()
grailsCentral()
} dependencies {
// Add HSQLDB as a runtime dependency
runtime 'hsqldb:hsqldb:1.8.0.10'
}
}
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" } } }
byte[]
domain class properties. HSQLDB's default BLOB size is large and so you typically don't need to specify a maximum size. But H2 defaults to a maximum size of 255 bytes! If you store images in the database, the saves are likely to fail because of this. The easy fix is to add a maxSize
constraint to the byte[]
property:class MyDomain { byte[] data static constraints = { data maxSize: 1024 * 1024 * 2 // 2MB } }
data
column set to BINARY(2097152)
by Hibernate.Abstract Inheritance Changes
In previous versions of Grails abstract classes ingrails-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 {}
Sellable
class would be stored within the BOOK
table. However, in Grails 2.x you will get a 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:
- Move the abstract
Sellable
class into the src/groovy package. If theSellable
class is in thesrc/groovy
directory it will no longer be regarded as persistent. - 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.Invalid Constraints Now Thrown an Exception
Previously if you defined a constraint on a property that doesn't exist no error would be thrown:class Person { String name static constraints = { bad nullable:false // invalid property, no error thrown } }
Logging By Convention Changes
The packages that you should use for Grails artifacts have mostly changed. In particular:service
->services
controller
->controllers
tagLib
->taglib
(case change)bootstrap
->conf
dataSource
->conf
log
property into artefacts at compile time.jQuery Replaces Prototype
The Protoype Javascript library has been removed from Grails core and now new Grails applications have the jQuery plugin configured by default. This will only impact you if you are using Prototype with the adaptive AJAX tags in your application, e.g. <g:remoteLink/> etc, because those tags will break as soon as you upgrade.To resolve this issue, simply install the Prototype plugin in your application. You can also remove the prototype files from yourweb-app/js/prototype
directory if you want.The Resources Plugin
The Resources plugin is a great new feature of Grails that allows you to manage static web resources better than before, but you do need to be aware that it adds an extra URL at/static
. If you have access control in your application, this may mean that the static resources require an authenticated user to load them! Make sure your access rules take account of the /static
URL.Controller Public Methods
As of Grails 2.0, public methods of controllers are now treated as actions in addition to actions defined as traditional Closures. If you were relying on the use of methods for privacy controls or as helper methods 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 actions asprivate
methods.Command Object Constraints
As of Grails 2.0, constrained properties in command object classes are no longer nullable by default. Nullable command object properties must be explicitly configured as such in the same way that nullable persistent properties in domain classes are configured.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 2.0. For example:redirect action: "next" if (response.committed) { // do something }
response.committed
property would return true and the if
block will execute. In Grails 2.0 this is no longer the case and you should instead use the new isRedirected()
method of the request
object:redirect action: "next" if (request.redirected) { // do something }
grails.serverURL
configuration option if it's set. Previous versions of Grails included default values for all the environments, but when upgrading to Grails 2.0 those values more often than not break redirection. So, we recommend you remove the development and test settings for grails.serverURL
or replace them with something appropriate for your application.Content Negotiation
As of Grails 2.0 the withFormat method of controllers no longer takes into account the request content type (dictated by theCONTENT_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 } } }
withFormat
method provided on the request
object:def processBook() { request.withFormat { xml { // read request XML } html { // read request parameters } } }
Unit Test Framework
Grails 2 introduces a new unit testing framework that is simpler and behaves more consistently than the old one. The old framework based on theGrailsUnitTestCase
class hierarchy is still available for backwards compatibility, but it does not work with the new annotations.Migrating unit tests to the new approach is non-trivial, but recommended. Here are a set of mappings from the old style to the new:
- Remove
extends *UnitTestCase
and add a@TestFor
annotation to the class if you're testing a core artifact (controller, tag lib, domain class, etc.) or@TestMixin(GrailsUnitTestMixin)
for non-core artifacts and non-artifact classes. - Add
@Mock
annotation for domain classes that must be mocked and usenew MyDomain().save()
in place ofmockDomain()
. - Replace references to
mockRequest
,mockResponse
andmockParams
withrequest
,response
andparams
. - Remove references to
renderArgs
and use theview
andmodel
properties for view rendering, orresponse.text
for all others. - Replace references to
redirectArgs
withresponse.redirectedUrl
. The latter takes into account the URL mappings as is a string URL rather than a map ofredirect()
arguments. - The
mockCommandObject()
method is no longer needed as Grails automatically detects whether an action requires a command object or not.
grails.test.mixin.TestFor
grails.test.mixin.TestMixin
grails.test.mixin.Mock
grails.test.mixin.support.GrailsUnitTestMixin
grails.test.mixin.domain.DomainClassUnitTestMixin
grails.test.mixin.services.ServiceUnitTestMixin
grails.test.mixin.web.ControllerUnitTestMixin
grails.test.mixin.web.FiltersUnitTestMixin
grails.test.mixin.web.GroovyPageUnitTestMixin
grails.test.mixin.web.UrlMappingsUnitTestMixin
grails.test.mixin.webflow/WebFlowUnitTestMixin
Command Line Output
Ant output is now hidden by default to keep the noise in the terminal to a minimum. That means if you useant.echo
in your scripts to communicate messages to the user, we recommend switching to an alternative mechanism.For status related messages, you can use the event system:event "StatusUpdate", ["Some message"] event "StatusFinal", ["Some message"] event "StatusError", ["Some message"]
grailsConsole
script variable, which gives you access to an instance of GrailsConsole. In particular, you can log information messages with log()
or info()
, errors and warnings with error()
and warning()
, and request user input with userInput()
.Custom Plugin Repositories
Many plugins have dependencies, both other plugins and straight JAR libraries. These are often located in Maven Central, the Grails core repository or the Grails Central Plugin Repository in which case applications are largely unaffected if they upgrade to Grails 2. But sometimes such dependencies are located elsewhere and Grails must be told where they can be found.Due to changes in the way Grails handles the resolution of dependencies, Grails 2.0 requires you to add any such custom repository locations to your project if an affected plugin is to install properly.Ivy Cache Location Has Changed
The default Ivy cache location for Grails has changed. If the thought of yet another cache of JARs on your disk horrifies you, then you can change this in yoursettings.groovy
:grails.dependency.cache.dir = "${userHome}/.ivy2/cache"
URL Domain Properties
If your domain model has any properties of typejava.net.URL
, they may cease to work once you upgrade to Grails 2. It seems that the default mapping of URL
to database column has changed with the new version of Hibernate. This is a tricky problem to solve, but in the long run it's best if you migrate your URL
properties to strings. One technique is to use the database migration plugin to add a new text column and then execute some code in BootStrap
(using Grails 1.3.x or earlier) to fetch each row of the table as a domain instance, convert the URL
properties to string URLs, and then write those values to the new column.Updated Underlying APIs
Grails 2.0 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 depend on earlier versions of these APIs may no longer work. For example the Servlet 3.0HttpServletRequest
interface includes new methods, so 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 Command
The built inrelease-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. The plugin resolution mechanism in Grails 1.2 and below 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 set of repository resolvers for resolving plugins, 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 resolvers for SVN repositories.Upgrading from Grails 1.1.x
Plugin paths
In Grails 1.1.x typically apluginContextPath
variable was used to establish paths to plugin resources. For example:<g:resource dir="${pluginContextPath}/images" file="foo.jpg" />
<g:resource dir="images" file="foo.jpg" />
<g:resource contextPath="" dir="images" file="foo.jpg" />
Tag and Body return values
Tags no longer returnjava.lang.String
instances but instead return a Grails StreamCharBuffer
instance. The StreamCharBuffer
class implements all the same methods as String
but doesn't extend String
, so code like this will break:def foo = body() if (foo instanceof String) { // do something }
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 ofJSONBuilder
which is semantically different from the one used in earlier versions of Grails. However, if your application depends on the older semantics you can still use the deprecated implementation by setting 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) executes a query then this can cause an additional flush, resulting in aStackOverflowError
. For example:static constraints = { author validator: { a -> assert a != Book.findByTitle("My Book").author } }
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 was compiled with Groovy 1.5 you must recompile it against Groovy 1.6 or higher 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 settinggrails.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 fromgrails.war.destFile
)grails.war.dependencies
grails.war.copyToWebApp
grails.war.resources
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
Plugin Changes
As of version 1.1, Grails no longer stores plugins inside yourPROJECT_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")
grailsScript
method to import a named script:includeTargets << grailsScript("_GrailsBootstrap")
Ant
should be changed to ant
.3) The root directory of the project is no longer on the classpath, so loading a resource like this will no longer work:def stream = getClass().classLoader.getResourceAsStream(
"grails-app/conf/my-config.xml")
basedir
property:new File("${basedir}/grails-app/conf/my-config.xml").withInputStream { stream -> // read the file }
Command Line Changes
Therun-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" }
REST Support
Incoming XML requests are now no longer automatically parsed. To enable parsing of REST requests you can do so using theparseRequest
argument inside a URL mapping:"/book"(controller:"book",parseRequest:true)
resource
argument, which enables parsing by default:"/book"(resource:"book")
2.4 Creating an Application
To create a Grails application you first need to familiarize yourself with the usage of thegrails
command which is used in the following manner:grails [command name]
grails create-app helloworld
This will create a new directory inside the current one that contains the project. Navigate to this directory in your console:cd helloworld
2.5 A Hello World Example
Let's now take the new project and turn it into the classic "Hello world!" example. First, change into the "helloworld" directory you just created and start the Grails interactive console:
$ cd helloworld
$ grails
You should see a prompt that looks like this:What we want is a simple page that just prints the message "Hello World!" to the browser. In Grails, whenever you want a new page you just create a new controller action for it. Since we don't yet have a controller, let's create one now with the create-controller command:
grails> create-controller hello
Don't forget that in the interactive console, we have auto-completion on command names. So you can type "cre" and then press <tab> to get a list of all create-*
commands. Type a few more letters of the command name and then <tab> again to finish.The above command will create a new controller in the grails-app/controllers/helloworld
directory called HelloController.groovy
. Why the extra helloworld
directory? Because in Java land, it's strongly recommended that all classes are placed into packages, so Grails defaults to the application name if you don't provide one. The reference page for create-controller provides more detail on this.We now have a controller so let's add an action to generate the "Hello World!" page. The code looks like this:package helloworldclass HelloController { def index() { render "Hello World!" } }
grails> run-app
This will start an embedded server on port 8080 that hosts your application. You should now be able to access your application at the URL http://localhost:8080/helloworld/ - try it!
If you see the error "Server failed to start for port 8080: Address already in use", then it means another server is running on that port. You can easily work around this by running your server on a different port using -Dserver.port=9090 run-app
. '9090' is just an example: you can pretty much choose anything within the range 1024 to 49151.
The result will look something like this:This is the Grails intro page which is rendered by the grails-app/view/index.gsp
file. It detects the presence of your controllers and provides links to them. You can click on the "HelloController" link to see our custom page containing the text "Hello World!". Voila! You have your first working Grails application.One final thing: a controller can contain many actions, each of which corresponds to a different page (ignoring AJAX at this point). Each page is accessible via a unique URL that is composed from the controller name and the action name: /<appname>/<controller>/<action>. This means you can access the Hello World page via /helloworld/hello/index, where 'hello' is the controller name (remove the 'Controller' suffix from the class name and lower-case the first letter) and 'index' is the action name. But you can also access the page via the same URL without the action name: this is because 'index' is the default action . See the end of the controllers and actions section of the user guide to find out more on default actions.
2.6 Using Interactive Mode
Grails 2.0 features an interactive mode which makes command execution faster since the JVM doesn't have to be restarted for each command. To use interactive mode simple type 'grails' from the root of any projects and use TAB completion to get a list of available commands. See the screenshot below for an example:For more information on the capabilities of interactive mode refer to the section on Interactive Mode in the user guide.2.7 Getting Set Up in an IDE
IntelliJ IDEA
IntelliJ IDEA offer good support for Groovy and Grails developers. Refer to the section on Groovy and Grails support on the JetBrains website for a feature overview.IntelliJ IDEA comes in two flavours; the open source "Community Edition" and the commercial "Ultimate Edition". Both offers support for Groovy, but only Ultimate Edition offers Grails support.With Ultimate Edition, there is no need to use thegrails integrate-with --intellij
command, as Ultimate Edition understands Grails projects natively. Just open the project with File -> New Project -> Create project from existing sources
.You can still use Community Edition for Grails development, but you will miss out on all the Grails specific features like automatic classpath management, GSP editor and quick access to Grails commands.
To integrate Grails with Community Edition run the following command to generate appropriate project files:grails integrate-with --intellij
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.NetBeans
NetBeans 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 the Glassfish server. For an overview of features see the NetBeans Integration guide on the Grails website which was written by the NetBeans team.TextMate
Since Grails' focus is on simplicity it is often possible to utilize more simple editors and TextMate on the Mac has excellent Groovy/Grails bundles available from the Texmate bundles GitHub.To integrate Grails with TextMate run the following command to generate appropriate project files:grails integrate-with --textmate
mate .
2.8 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:grails-app
- top level directory for Groovy sourcesconf
- Configuration sources.controllers
- Web controllers - The C in MVC.domain
- The application domain.i18n
- Support for internationalization (i18n).services
- The service layer.taglib
- Tag libraries.utils
- Grails specific utilities.views
- Groovy Server Pages - The V in MVC.scripts
- Gant scripts.src
- Supporting sourcesgroovy
- Other Groovy sourcesjava
- Other Java sourcestest
- Unit and integration tests.
2.9 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
server.port
argument:grails -Dserver.port=8090 run-app
$ grails grails> run-app | Server running. Browse to http://localhost:8080/helloworld | Application loaded in interactive mode. Type 'exit' to shutdown. | Downloading: plugins-list.xml grails> exit | Stopping Grails server grails> run-app | Server running. Browse to http://localhost:8080/helloworld | Application loaded in interactive mode. Type 'exit' to shutdown. | Downloading: plugins-list.xml
2.10 Testing an Application
Thecreate-*
commands in Grails automatically create unit or integration tests for you within the test/unit
or 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.To execute tests you run the test-app command as follows:grails test-app
2.11 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
target
directory which can then be deployed as per your container's instructions.Unlike most scripts which default to the development
environment unless overridden, the war
command runs in the production
environment by default. You can override this like any script by specifying the environment name, for example:grails dev war
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 implicationsWhen 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 -XX:MaxPermSize=256m
2.12 Supported Java EE Containers
Grails runs on any container that supports Servlet 2.5 and above 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
2.13 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 thegenerate-*
commands such as generate-all, which will generate a controller (and its unit test) and the associated views:grails generate-all Book
2.14 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 just 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
grails-app/domain/Book.groovy
such as:class Book { }
create-*
commands that can be explored in the command line reference guide.To decrease the amount of time it takes to run Grails scripts, use the interactive mode.