Session Notes – Grails Plugin System Part 1

Presenter: Graeme Rocher

Agenda

  • plugin quick start
  • technical vs. functional plugins
  • plugins for modularity
  • distribution and dependency management
  • plugin demo

Key Facts

  • grails itself is made up of a collection of plugins

    • hibernate, webflow, gsp, etc.
    • grails core is essentially a set of plugins (about a dozen)

  • there are 300+ plugins available now

    • what a plugin can do is wide and varied

  • plugins are easy to create

    • don’t need to spend a ton of time learning the internals of the framework to create a plugin

  • plugins are easy to distribute
  • everyone is a plugin developer
  • well over 25 million lines of user contributed code in the plugin repository

    • searchable

      • automatically makes any domain class searchable

    • taggable

      • adds apis to tag domain classes

    • rateable

      • ratings for domain classes

    • quartz

      • for scheduling tasks
      • interesting because it adds a new concept to grails — “jobs”
      • adds create-job command to command line, has a jobs directory, etc.

    • gwt
    • weceem cms

      • example of a functional plugin as opposed to just providing new apis
      • this plugin contains views, controllers, domains, etc. as part of the plugin

    • feeds (rss and atom feeds)
    • iwebkit (iphone)

Common Use Case

  • you have a tag library
  • you have two applications
  • you want to share functionality
  • create a plugin!
  • grails create-plugin pluginName creates the plugin skeleton
  • grails 1.2 creates intellij project files

Plugin Structure

  • more or less identical to a grails application structure
  • can run the plugins as standalone apps

    • developing a plugin is the same as developing an application

  • only real difference is there’s a plugin descriptor in the root of each plugin

    • contains info about plugin version, grails versions supported
    • can also exclude specific resources when the plugin is installed
    • also numerous plugin hooks that can be accessed (doWithWebDescriptor, doWithSpring, etc.)

  • using packages is important–should always uses packages in your applications

Plugin Quick Start — 5 steps

  • grails create-plugin myPlugin
  • cd myPlugin
  • grails create-tag-lib myTagLib
  • grails package-plugin
  • grails install-plugin

Plugin Extension Points

  • normal grails development

    • tag libraries, controllers, etc.
    • the build
    • theses are very trivial to do

  • requires additional knowledge

    • spring configuration
    • new apis

      • addition of additional properties/methods to domain classes and domain controllers

    • new concepts

Plugin Types

  • relate to the “split” above
  • functional plugins

    • taglibs, controllers, extend the build, etc.

  • technical plugins

    • see above–spring config, metaprogramming, etc.

Examples

  • functional plugins

    • weceem cms
    • nimble

      • provides user management, integration with facebook, etc.

  • technical plugins

    • gwt
    • functional test

  • both functional and technical

    • spring security
    • searchable

      • adds search to domain classes, but also provides a complete search UI to your application

Functional Plugins

  • easier to understand
  • just like building a normal grails application
  • silos of functionality

    • forums, blog, search, etc.

  • used to create modular applications

Demo: Building a Functional Plugin

  • example: twitter clone

    • two different teams–web UI team, mobile team
    • underlying functionality is the same

  • good candidate for a plugin–need to share the domain model between the two apps
  • can install plugins in other plugins

    • e.g. can install both the iwebkit and the twitter domain model plugin into the iphone version of the app
    • can specify plugins and versions in dependsOn block in the plugin descriptor
    • when you package up your plugin it will bundle up the plugins on which your plugin depends and include them

  • can use BootStrap.groovy within plugins
  • can configure local plugin repositories and can specify order in which plugin repositories are searched

Certain Things that Plugins Cannot Package by Default

  • BootStrap.groovy, UrlMappings.groovy, DataSource.groovy
  • can create something like FooUrlMappings.groovy and that will get packaged

Some Tips

  • inline plugins

    • if you’re modularizing your entire application, becomes impractical to repackage and reinstall every plugin as they change during development

  • url mappings
  • jar dependencies
  • testing
  • plugin distribution

Inline Plugins

  • use plugins without installing them
  • prevents package/install cycle
  • great for modular application development
  • go to grails-app/conf/BuildConfig.groovy and set grails.plugin.location.”pluginName”=”../path/to/plugin
  • BuildConfig.groovy

    • not generated automatically in 1.1.1
    • lets you configure various aspects of the build, locations of generated files, etc.

URL Mappings

  • normal UrlMappings.groovy file is excluded from the package plugin process
  • if you want to define url mappings as part of your plugin, create a file called something like MyPluginUrlMappings.groovy and that will be included

Plugin Dependencies

  • grails supports transitive installs and plugin dependencies using dependsOn
  • can use ranges of versions for dependencies, e.g. hibernate:”1.1 > *”
  • to implement a “soft” dependency use loadAfter

    • def loadAfter = [“hibernate”]
    • can also specify loadBefore

Plugin JAR Dependencies

  • you can put jar files in the lib directory of the project just like applications
  • even better, in grails 1.2 you can define dependencies in grails-app/conf/BuildConfig.groovy
  • grails.project.dependency.resolution = {
    inherits “global” // inherit grails’ default dependencies
    dependencies {
    runtime “org.apache.ant:ant:1.7.1”
    }
    }
  • different scopes can be involved–build, runtime, test, provided (needed during grails run-app but not during WAR deployment)
  • this means the jar files are NOT included in the plugin packaging

    • allows application into which the application is installed to resolve the dependencies

  • in a traditional java project, the jar dependency list is flat
  • in grails, you have dependencies of the app, of the framework, and of any plugins involved

Testing

  • done just like a normal application
  • sometimes it’s useful to have classes used only for testing and not distributed with the plugin
  • use pluginExcludes in the plugin descriptor to achieve this
  • class MyPlugin {
    def pluginExcludes = [
    “ant/path/here
    ]
    }

Plugin Distribution

  • central repository

    • grails release-plugin

  • custom repository

    • can configure custom repos in BuildConfig.groovy
    • can also set this in settings.groovy in your user home directory

  • Grails separates notion of repos used for discovery vs. distribution (e.g. http for discovery, https for distribution)
  • can specify the repository into which to release the plugin when you run grails release-plugin
  • custom repos use svn for distribution

    • can use a basic file server for discovery

  • plugins don’t necessarily have to be open source to be in the central repository

    • need to specify the license
    • would distribute jars instead of source

Summary

  • developing grails plugins is very simple
  • functional plugins are an easy way to modularize your application
  • in part 2 we’ll be looking at how to develop technical plugins

Q&A

  • as part of modularization is there any integration with osgi?

    • not yet, but looking into it–probably next year there will be something more concrete

  • are there particular plugins that you would highlight that follow best practices or as good models to follow?

    • depends on what you want to do
    • for a functional plugin check out weceem cms–complete end-to-end with views, js, etc.
    • for a technical plugin check out Build Test Data (creates mock data for you)
    • quartz plugin is a good example of a plugin that adds a new concept to grails, new command line arguments, etc.

      • exercises the artefact api

    • SpringWS plugin adds notion of an endpoint to Grails
    • Ratable, Commentable, Featurable, and Taggable are great examples of modifying domain classes on app load

Leave a Reply

Your email address will not be published. Required fields are marked *