Archive for June, 2009

Patching a Running Server Using Groovy MOP

Monday, June 15th, 2009

We found a bug recently on the site (a Grails app we’re building) and quickly fixed it in SVN, but we’re not due for a release until next week. We’re in early beta and have only a few users, so it’s not that urgent that we fix this bug. But every time the bug is triggered we get several error emails thanks to the Log4j SMTP error appender we have configured, so it’s an annoying bug.

The problem is due to the assumption that all purchases use a credit card, but we currently only have “online affiliate” purchases. We have CreditCard and OnlinePaymentSource domain classes to model the payment sources; CreditCard has a type attribute (e.g. Visa, MasterCard, etc.) but OnlinePaymentSource doesn’t and the bug is in a GSP which calls getType() on an OnlinePaymentSource. The fix was simply to write a custom tag that renders a description of the card or online payment – the ‘type’ and last 4 digits of the card, or ‘Online’ for online purchases.

My colleague Kris suggested half-jokingly that we could use MOP to fix the problem before next week’s update:

OnlinePaymentSource.metaClass.getType = { -> 'Online' }

We have a web-based Groovy console that’s based on the standard Swing console (and similar to the Grails Console plugin but we don’t use the plugin since it’s 1.1-only and we’re still on 1.0.4 (and we’d already written our own)) that we use for site admin. So we decided to patch the code while running since we have so little traffic and a quick server restart would revert the changes if there’s a problem.

Once we made the fix I used the “switch user” feature of the Spring Security plugin to assume the identity of a user that had made a purchase and was able to view the page without causing an error page or annoying emails 🙂

We probably won’t be making changes like this often, but it’s nice knowing that it’s an option, especially for a more serious bug with a similarly straightforward fix. Of course there are changes that cannot be made using this approach – for example you can’t add a new value to an Enum, and MetaClass method overrides are ignored if the method is in a Java class and is called from another Java class. But it’s a great tool to have in the toolbox.

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