I was in London last week on vacation with my family and was lucky that there was a London GGUG meetup during my visit. David Dawson
discussed modularizing Grails applications by refactoring them into multiple plugins (you can see the video of his talk here
). One thing that he mentioned was the idea of plugins that can be run like standalone applications since the structures of Grails applications and plugins are so similar, and I thought it would be interesting to look at the process of converting an application to a plugin or a plugin to an application.
The approaches I’ll discuss here include a lot of bias on my part about how I like to create apps and plugins, so YMMV. I also won’t go into partial conversions since David covered this well in his talk.
So to convert an application to a plugin, the general workflow would be something like
- Create the plugin descriptor, FooGrailsPlugin.groovy. The easiest way to do this is to run
grails create-plugin pluginnameand copy the generated file from there - delete everything from
application.propertiesexcept theapp.grails.versionproperty - if you have jars in the lib directory that are available in a Maven repo, delete them and replace with
BuildConfig.groovydependencies - change any plugin and jar dependencies that are needed for development and testing but not when the plugin is installed to not be exported, by adding
export = false - If you need the
_Install.groovy,_Uninstall.groovy, or_Upgrade.groovyscripts (you probably don’t) grab those from the dummy plugin from step 1 (but delete any you don’t need, they’re all optional) - delete
ApplicationResources.groovyif you aren’t using it and don’t depend on resources plugin - move code from
BootStrap.groovyinit()toFooGrailsPlugin.doWithApplicationContextand/orFooGrailsPlugin.doWithDynamicMethodsanddestroy()to FooGrailsPlugin.onShutdown, and deleteBootStrap.groovy - add a dependency for the
releaseplugin inBuildConfig.groovy - delete everything but the log4j configuration from
Config.groovy - delete
UrlMappings.groovyunless you have exported mappings; only keep the added ones - move bean definitions from
resources.groovytoFooGrailsPlugin.doWithSpringand deleteresources.groovy - delete
grails-app/i18nmessage bundle files unless you added messages; only keep the added ones - delete everything from
grails-app/viewsthat you don't use (in particularerror.gsp,index.gsp, andlayouts/main.gsp) - delete everything from
web-appthat you don't use (including WEB-INF xml and tld files) - now would be a great time to write those tests you've been meaning to get to
- create one or more test applications to install the plugin into to ensure that it works as a plugin; consider scripting this
- write documentation for how to use the plugin; at a minimum a README file, but Grails gdoc files
would be much better (run grails doc --initto get started)
Converting a plugin to an application is similar, except for the most part reversed:
- Create a dummy application with
grails create-app appnameto copy missing files from- Move
BootStrap.groovy,Config.groovy,UrlMappings.groovy, andApplicationResources.groovyintograils-app/conf, merging if needed - Move
resources.groovyintograils-app/conf/spring - Move message bundle files to
grails-app/i18n, merging if needed - Move missing GSPs to
grails-app/views - Move static resources from
web-app - Move xml and tld files from
web-app/WEB-INF
- Move
- Move code from
FooGrailsPlugin.doWithApplicationContextandFooGrailsPlugin.doWithDynamicMethodstoBootStrap.groovyinit(), and code fromFooGrailsPlugin.onShutdowntodestroy() - Move bean definitions from
FooGrailsPlugin.doWithSpringtoresources.groovy - Delete the plugin descriptor
- Restore missing properties in
application.properties - Delete the
_Install.groovy,_Uninstall.groovy, and_Upgrade.groovyscripts - Remove the dependency for the
releaseplugin fromBuildConfig.groovy - Now would be a great time to write those tests you've been meaning to get to
- If you make changes in the plugin's
doWithWebDescriptor, rungrails install-templatesand add them tosrc/templates/war/web.xml - If you add custom artifacts, or were supporting development-environment code or config changes in
onChangeand/oronConfigChange, these aren't directly doable in an application. Use the pluginator
plugin for these, and also for dynamic web.xmlchanges that require runtime logic
I've probably skipped a few steps and definitely omitted a lot of detail, but this should cover most of the process for each type of conversion.



