(Quick Reference)

15.1 Creating and Installing Plugins - Reference Documentation

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

Version: 2.3.8

15.1 Creating and Installing Plugins

Creating Plugins

Creating a Grails plugin is a simple matter of running the command:

grails create-plugin [PLUGIN NAME]

This will create a plugin project for the name you specify. For example running grails create-plugin example would create a new plugin project called example.

Make sure the plugin name does not contain more than one capital in a row, or it won't work. Camel case is fine, though.

The structure of a Grails plugin is very nearly the same as a Grails application project's except that in the root of the plugin directory you will find a plugin Groovy file called the "plugin descriptor".

The only plugins included in a new plugin project are Tomcat and Release. Hibernate is not included by default.

Being a regular Grails project has a number of benefits in that you can immediately test your plugin by running:

grails run-app

Plugin projects don't provide an index.gsp by default since most plugins don't need it. So, if you try to view the plugin running in a browser right after creating it, you will receive a page not found error. You can easily create a grails-app/views/index.gsp for your plugin if you'd like.

The plugin descriptor name ends with the convention GrailsPlugin and is found in the root of the plugin project. For example:

class ExampleGrailsPlugin {
   def version = "0.1"

… }

All plugins must have this class in the root of their directory structure. The plugin class defines the version of the plugin and other metadata, and optionally various hooks into plugin extension points (covered shortly).

You can also provide additional information about your plugin using several special properties:

  • title - short one-sentence description of your plugin
  • version - The version of your plugin. Valid values include example "0.1", "0.2-SNAPSHOT", "1.1.4" etc.
  • grailsVersion - The version of version range of Grails that the plugin supports. eg. "1.2 > *" (indicating 1.2 or higher)
  • author - plugin author's name
  • authorEmail - plugin author's contact e-mail
  • description - full multi-line description of plugin's features
  • documentation - URL of the plugin's documentation

Here is an example from the Quartz Grails plugin:

class QuartzGrailsPlugin {
    def version = "0.1"
    def grailsVersion = "1.1 > *"
    def author = "Sergey Nebolsin"
    def authorEmail = "nebolsin@gmail.com"
    def title = "Quartz Plugin"
    def description = '''\
The Quartz plugin allows your Grails application to schedule jobs\
to be executed using a specified interval or cron expression. The\
underlying system uses the Quartz Enterprise Job Scheduler configured\
via Spring, but is made simpler by the coding by convention paradigm.\
'''
    def documentation = "http://grails.org/plugin/quartz"

… }

Installing Local Plugins

To make your plugin available for use in a Grails application run the maven-install command:

grails maven-install

This will install the plugin into your local Maven cache. Then to use the plugin within an application declare a dependency on the plugin in your grails-app/conf/BuildConfig.groovy file:

compile ":quartz:0.1"

Notes on excluded Artefacts

Although the create-plugin command creates certain files for you so that the plugin can be run as a Grails application, not all of these files are included when packaging a plugin. The following is a list of artefacts created, but not included by package-plugin:

  • grails-app/conf/BootStrap.groovy
  • grails-app/conf/BuildConfig.groovy (although it is used to generate dependencies.groovy)
  • grails-app/conf/Config.groovy
  • grails-app/conf/DataSource.groovy (and any other *DataSource.groovy)
  • grails-app/conf/UrlMappings.groovy
  • grails-app/conf/spring/resources.groovy
  • Everything within /web-app/WEB-INF
  • Everything within /web-app/plugins/**
  • Everything within /test/**
  • SCM management files within **/.svn/** and **/CVS/**

If you need artefacts within WEB-INF it is recommended you use the _Install.groovy script (covered later), which is executed when a plugin is installed, to provide such artefacts. In addition, although UrlMappings.groovy is excluded you are allowed to include a UrlMappings definition with a different name, such as MyPluginUrlMappings.groovy.

Customizing the plugin contents

You can specify what to exclude in addition to the default excludes by adding elements to the pluginExcludes descriptor property (described below). In addition, there are two ways to configure the contents of the plugin ZIP or JAR file.

One is to create an event handler for the CreatePluginArchiveStart event, which is fired after all of the plugin files have been copied to the staging directory. By adding an event handler you can add, modify, or delete files as needed. Add the handler to _Events.groovy in the scripts directory, for example

eventCreatePluginArchiveStart = { stagingDir ->
   // update staging directory contents here
}

You can customize the location of the staging directory with the grails.project.plugin.staging.dir attribute in BuildConfig.groovy or as as system property.

Note that there is also a CreatePluginArchiveEnd event which is fired after the ZIP or JAR is packaged.

You can also do this work in a Closure in BuildConfig.groovy with the property grails.plugin.resources which is analogous to the grails.war.resources property, e.g.

grails.plugin.resources = { stagingDir ->
   // update staging directory contents here
}

Specifying Plugin Locations

An application can load plugins from anywhere on the file system, even if they have not been installed. Specify the location of the (unpacked) plugin in the application's grails-app/conf/BuildConfig.groovy file:

// Useful to test plugins you are developing.
grails.plugin.location.shiro =
        "/home/dilbert/dev/plugins/grails-shiro"

// Useful for modular applications where all plugins and // applications are in the same directory. grails.plugin.location.'grails-ui' = "../grails-grails-ui"

This is particularly useful in two cases:

  • You are developing a plugin and want to test it in a real application without packaging and installing it first.
  • You have split an application into a set of plugins and an application, all in the same "super-project" directory.

The Artifactory repository for Grails now includes all the dependencies for published plugins. So, if you are using inline plugins that have dependencies, it is necessary to do a secondary resolve because these dependencies might not be in the repository. Therefore, you should set legacyResolve to true in your BuildConfig.groovy if you are using inline plugins with dependencies.