Matt Woodward’s posterous

Matt Woodward’s posterous

Matthew Woodward  //  * CFML, Grails, and Java Developer
* Principal IT Specialist, US Senate
* Open BlueDragon Steering Committee Member
* All-Around Geek

Oct 21 / 6:24pm

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

0 comments

Leave a comment...