Updates for the Grails App Info plugin

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' :

   'app.info.custom.example.MyConfigControllerMixin' :

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 app.info.custom.example.MyConfig class in src/groovy, the app.info.custom.example.MyConfigControllerMixin 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.

10 Responses to “Updates for the Grails App Info plugin”

  1. Lim Chee Kin says:

    Hi Burt,

    Thanks for creating the plugin, I tried to run the appinfodemo application with Grails 2.1.0 after running “grails upgrade” and access to http://localhost:8080/appinfodemo/. The browser display HTTP 500 error with java.lang.IllegalStateException and the following message:
    No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

    I suspect the error is caused by dynamic-controller plugin so I created a simple test application at http://grails-activiti-plugin.googlecode.com/files/dynamic-controller-test.zip to test the plugin, it should able to access to http://localhost:8080/dynamic-controller-test/foo/test, but the browser display HTTP Error 404.

    Please advice. Hope to hear from you soon!

    Best regards,
    Chee Kin

  2. Lim Chee Kin says:

    Hi Burt,

    Please ignore the reported issue of appinfodemo application, the same issue didn’t happened when I “grails run-app” the second time, I am unable to simulate the same issue again.

    As for the dynamic-controller-test application, the problem persist. I may miss something and I will dig into the source code of your app-info plugin to find it out.

    In short, you may ignore these two comments. Sorry for any inconvenient being caused.

    Best regards,
    Chee Kin

  3. Sophia says:

    Hi Burt

    Why is the HibernateControllerMixin not in the controllerMixins package anymore? How do I go about seeing my Hibernate stats?

    Kind regards,

  4. Markus says:

    Hi Burt

    Thank you for this fantastic plugin – very interesting stuff to see and even better the possibility to change things at runtime (especially the logging part). Kudos to you!

    However, the plugin is running fine only on the embedded Tomcat (e.g. inside GGTS). But when I deploy my application to WebSphere 7 Express, the mechanism with the dynamic-controller seems to fail.

    I followed your suggested approach as you explained above and the result is:

    http://myserver:8080/myapp/admin/manage/ works fine (I see all three menus and their menu items)
    – but the menu items links to urls like http://myserver:8080/myapp/dynamicDelegate/applicationInfo which of course will result in a 404 (after adding ‘/dynamicDelegate/**’: [‘ROLE_ADMIN’] to grails.plugins.springsecurity.controllerAnnotations.staticRules).

    Do you have any idea what is going wrong here? All other stuff of my grails application I made to run on WebSphere without any major problems (WAS 6.1 was a pain, but 7.0 is ok).

    Thanks in advance,

  5. Markus says:

    Forgot to say that when I manually navigate e.g. to http://myserver:8080/myapp/admin/manage/applicationInfo the page load correctly. But it’s not possible to change e.g. a log level, because the page makes a POST again to /myapp/dynamicDelegate/… which will result again in a 404 (but silently ignored).

    I hope there is a easy way to fix this?

    Best regards,

  6. Markus says:

    I was able to find a workaround. Just added another line to UrlMappings.groovy:

    “/dynamicDelegate/$action?”(controller: “adminManage”)

    Everything seem to work. But not sure if this has any side effects.
    Btw I’m using Grails 2.2.1 and appInfo 1.0.2


  7. Vaani says:

    On running grails 2.3 M1 release with app-info plugin seeing the NPE in SpringSecurityCoreGrailsPlugin.

    Error Error generating web.xml file
    at SpringSecurityCoreGrailsPlugin$_closure1.doCall(SpringSecurityCoreGrailsPlugin.groovy:151)
    at _GrailsPackage_groovy$_run_closure5.doCall(_GrailsPackage_groovy:74)

    Anything required to change in grail spring security plugin? We are using version


  8. George Chitishvili says:

    Hello Burt,

    Thank you for greate plugin, but unfortunately I can not make it run on Grails-2.3.2.

    Each Request for “adminManage” (oder “admin/manage”) ist forwarded to “404 notFound” as if Mixins

    Could you please upgrade the “appinfodemo” Grails-Project for newer Versions of Grails.

    Thank You in advance.

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