Skip to main content

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



Comments

Popular posts from this blog

Installing and Configuring NextPVR as a Replacement for Windows Media Center

If you follow me on Google+ you'll know I had a recent rant about Windows Media Center, which after running fine for about a year suddenly decided as of January 29 it was done downloading the program guide and by extension was therefore done recording any TV shows.

I'll spare you more ranting and simply say that none of the suggestions I got (which I appreciate!) worked, and rather than spending more time figuring out why, I decided to try something different.

NextPVR is an awesome free (as in beer, not as in freedom unfortunately ...) PVR application for Windows that with a little bit of tweaking handily replaced Windows Media Center. It can even download guide data, which is apparently something WMC no longer feels like doing.

Background I wound up going down this road in a rather circuitous way. My initial goal for the weekend project was to get Raspbmc running on one of my Raspberry Pis. The latest version of XBMC has PVR functionality so I was anxious to try that out as a …

Setting Up Django On a Raspberry Pi

This past weekend I finally got a chance to set up one of my two Raspberry Pis to use as a Django server so I thought I'd share the steps I went through both to save someone else attempting to do this some time as well as get any feedback in case there are different/better ways to do any of this.

I'm running this from my house (URL forthcoming once I get the real Django app finalized and put on the Raspberry Pi) using dyndns.org. I don't cover that aspect of things in this post but I'm happy to write that up as well if people are interested.

General Comments and Assumptions

Using latest Raspbian “wheezy” distro as of 1/19/2013 (http://www.raspberrypi.org/downloads)We’lll be using Nginx (http://nginx.org) as the web server/proxy and Gunicorn (http://gunicorn.org) as the WSGI serverI used http://www.apreche.net/complete-single-server-django-stack-tutorial/ heavily as I was creating this, so many thanks to the author of that tutorial. If you’re looking for more details on …

The Definitive Guide to CouchDB Authentication and Security

With a bold title like that I suppose I should clarify a bit. I finally got frustrated enough with all the disparate and seemingly incomplete information on this topic to want to gather everything I know about this topic into a single place, both so I have it for my own reference but also in the hopes that it will help others.Since CouchDB is just an HTTP resource and can be secured at that level along the same lines as you'd secure any HTTP resource, I should also point out that I will not be covering things like putting a proxy in front of CouchDB, using SSL with CouchDB, or anything along those lines. This post is strictly limited to how authentication and security work within CouchDB itself.CouchDB security is powerful and granular but frankly it's also a bit quirky and counterintuitive. What I'm outlining here is my understanding of all of this after taking several runs at it, reading everything I could find on the Internet (yes, the whole Internet!), and a great deal…