Archive for July 5th, 2012

Updates for the Grails App Info plugin

Thursday, July 05th, 2012

The app-info plugin wasn’t working in Grails 2.0+ because of an incompatibility between the Hibernate Tools jar and the version of Hibernate that Grails uses. So I split out the Hibernate-related functionality from the plugin into a to-be-released app-info-hibernate plugin, and once they release an updated version of Hibernate Tools I’ll be able to finish and release that. This also affected the db-reverse-engineer plugin but I was able to fix that with a hackish solution since that runs as a script (I fork a new process with a separate classpath) but that approach wasn’t feasible for this plugin.

The original blog post is still mostly valid but I wanted to point out some new features and make an updated test application available.

You install the plugin like any other, by including a dependency for it in BuildConfig.groovy, e.g.

plugins {

   compile ':app-info:1.0.1'

The plugin depends on the dynamic-controller plugin to configure what features are available, so you need to configure the active mixins in Config.groovy (omit any you don’t need):

grails.plugins.dynamicController.mixins = [

   'com.burtbeckwith.grails.plugins.appinfo.Log4jControllerMixin' :

   'com.burtbeckwith.grails.plugins.appinfo.SpringControllerMixin' :

   'com.burtbeckwith.grails.plugins.appinfo.MemoryControllerMixin' :

   'com.burtbeckwith.grails.plugins.appinfo.PropertiesControllerMixin' :

   'com.burtbeckwith.grails.plugins.appinfo.ScopesControllerMixin' :

   'com.burtbeckwith.grails.plugins.appinfo.ThreadsControllerMixin' :

   '' :

This configures a dynamic AdminManagerController and I like to map its urls to /admin/manage, so I add these lines to UrlMappings.groovy:

"/admin/manage/$action?"(controller: "adminManage")
"/adminManage/$action?"(controller: "errors", action: "urlMapping")

"403"(controller: "errors", action: "accessDenied")
"404"(controller: "errors", action: "notFound")
"405"(controller: "errors", action: "notAllowed")
"500"(controller: "errors", action: "error")

The first is the expected mapping, and the second “un-maps” the one that gets auto-created by the "/$controller/$action?/$id?" rule. It does this by using the urlMapping action in ErrorsController (see the test app for the source) to send a 404 error code. Since I’m using a controller for this, I also map the standard error codes to be able to have custom GSPs for each.

If you’re using the spring-security-core plugin you can then guard access to all the plugin’s actions with one mapping:

grails.plugins.springsecurity.controllerAnnotations.staticRules = [
   '/adminmanage/**': ['ROLE_ADMIN']

The plugin also includes a configuration demonstrating the new support for adding extra menu items (see GPAPPINFO-19) so the test app includes the class in src/groovy, the mixin in grails-app/controllerMixins, and the views/myconfig/configs.gsp GSP. This is all plugged in with this configuration in Config.groovy:

grails.plugins.appinfo.additional = [
   "My Config": [
      configs: "Configs"

There’s also a new thread dump mixin (see GPAPPINFO-20) and this is enabled by configuring ThreadsControllerMixin (see the grails.plugins.dynamicController.mixins config map above). The menu item is “Thread Dump” in the Info menu.

You can download the test application (it uses Grails 2.0.4) here. Once it’s running navigate to http://localhost:8080/appinfodemo/admin/manage/ and authenticate as admin/password to try it out.

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.