Getting Groovy (and Grails)

Explorations in Groovy and Grails Development

The Gr8 Conference: The Grails Plug-in System – Plug in to Productivity

with one comment

After Graeme’s talk on building a Twitter clone in Grails, we took a short break and then returned to another presentation by Graeme – this time on the process of writing plug-ins for Grails. The core message of this presentation was that you don’t need to be a Grails guru to write plug-ins. Even if you’re just writing applications for your own use, you should consider using plug-ins to modularize them.

Grails Plugins
Grails is designed to wire together different libraries and to make them easy to use. Out of the box, Grails uses plugins: controllers, gsp, GORM for Hibernate persistence. etc. In total there are  10-11 plug-ins in the default Grails applications you get when generating them using create-app to provide the core grails experience. In this sense, Grails can be seen as a “platform for runtime configuration”.

There is a Grails runtime with the concept of a grailsapplication (with a class that models that), along with an application content and then a bunch of plugins. For example the quartz plugin (for scheduling tasks) actually adds a new notion called a “job” to Grails to the grailsapplication object. So you can extend the grailsapplication object.

The Extension Points:
There are a number of different extension points that you can leverage when building a Grails plugin.
Build system – additional command line scripts.
Spring application context – for sensible defaults and configs. Spring has concept of message driven beans that plugins can auto configure.
Dynamic method registration – Adding methods automatically to certain classes of objects. For example, GORM adds save, list, delete and other persistence methods to domain objects.
Auto reloading – for example the JMS plugin listens for change events to services and reconfigures message driven bean on changes.
Container config (web.xml) – Grails generates the web.xml. Can participate in the generation
Adding new artifacts – Can add new artifacts and artifact types. New concept like a job in quartz, or just create controllers (like the searchable plugin does).

What is a Plugin?
– Just like a normal Grails project
– The only difference is the presence of a <pluginname>GrailsPlugin.groovy file
– Use “grails create-plugin [plug-in name]” to create one – that’s it!

A plugin is just a regular Grails project and can be developed like one.
The plugin descriptor:
class LoggingGrailsPlugin {
def version = 0.4
def dependsOn = [core: “1.0 > *”]
}

Packaging your Plug-in
It’s also easy to package up a plugin:
grails package-plugin
cd ../my-project
grails install-plugin ../logging/grails-blog-0.4.zip
or remotely like:
grails install-plugin http://myserver/grails-blog-0.4.zip

Plugins and application modularity
Grails app plus . . .
– messaging, security, search, blog, wiki, maps, etc
All main app does is to provide a set of plugins

Adding Basic Artifacts
– A plugin can add new tag libs, controllers and services simply by creating them in the plugin project
– Since a plugin project is just like any project, you can just create and run one

Turning the twitter app into a plugin:
– Start by factoring out the domain into a plugin

grails create-plugin twitter-domain

Look at the TwitterDomainGrailsPlugin.groovy it creates

Copy domain to plugin and delete
Then cd into twitter-domain and grails package-plugin it

grails create-plugin twitter-iphone
grails install -domain ../twitter-domain/grails-twitter-domain-1.0.zip

add [dependson:TwitterDomain: “0.1” , iWebKit: “0.4”]

Note: When create plugin project, doesn’t auto install any of the grails plugins like Hibernate, so may need to grails install-plugin Hibernate – otherwise it’ll say “can’t find property “save””.

Note: dependencies are transitive, so install twitter-iphone, if it depends on iWebKit, it’ll install that automatically.

More advanced use cases (beyond the basics)
Can provide bean defs in def doWithSpring – e.g. setting “time to live” higher in production for EhCacheFactoryBean
See the Grails user guide for a description of the Spring Domain Specific Language
Plugins allow you to manipulate the underlying Spring context based on the environment, the conventions and the state of other plugins.

Can enhance behavior with doWithDynamicMethods to add to the application.domainClasses.each {} and then (for example_ domainClass.metaClass.constructor can be overwritten)
or add domainClass.metaClass.static.load = {long id -> template.load(delegate.getClass() , id)}
See the metaprograming guide on the Groovy website.

There are some issues re: template rendering and static resources in plugins, so they do require just a little more thought than an app – but not much.

Plugins already available
– Test: Selenium, fitnesse, code coverage, etc
– Rich Grails: Flex, GWT, GrailsUI (YahooUI), etc
– Secure Grails: Spring, JSecurity, OpenID, etc
– Integrate Grails, Search, Jasper Reports, JMS, etc

Check them out at http://grails.org/plugins – can comment, search, etc.

Summary
– Plugins are crucial to the grails story
– Everyone is a plugin developer – not just the gurus
– Plugins help to create modular applications
– Plugins automate configuration through convention over configuration

Advertisements

Written by peterbell

May 21, 2009 at 5:37 pm

Posted in gr8, Grails

One Response

Subscribe to comments with RSS.

  1. […] Last year I posted a fairly comprehensive series of articles on the blog (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) summarizing the content from Gr8 in Copenhagen. This year I opted instead to write an […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: