Posts

Showing posts from 2012

Using database migrations plugin from within another plugin

The plugin infrastructure provides Grails with great power in how to structure the code base for their applications. For example, if you had to make customizations to your project for a particular client, you could place all your core code in a plugin and have a default and a custom application depending on that plugin. For whatever reason you decide in having a "core" plugin, you might encounter a few bumps in the process. One such bump involves the database migrations plugin. By default the database plugin expects the migration changelogs to be in grails-app/migrations. It is possible to change this location via the configuration config.grails.plugin.databasemigration.changelogLocation, but this requires knowing the location of plugin. So one solution is to put code like the following somewhere in your plugin: Note that in my case, I'm using the platform-core-plugin so it seems appropriate to put it in the doWithConfig closure of my Plugin definition file.

Modularize/partition Grails config files

If you find that your Config.groovy is getting large, you can split it into multiple files using the same mechanism that might already be using to include an external file. So your Config.groovy may already have something like the following defined: One might expect files in the conf directory that follow the convention of ending in Config.groovy of being automatically included but this in not the case. I imagine the reason is a question of precedence - and a lack of clarity thereof. If two files in the conf directory ending in Config.groovy defined the same property which one would win? So only the Config.groovy file is auto-read by Grails, and within this file you can define other Config files to include. It's not very convention over configuration, but you can understand why. The files to include can be defined in one of two lists. grails.config.locations and grails.config.default.locations. Files defined in grails.config.locations are parsed after the property definitions …

AngularJs and SpinJs (in Coffeescript)

SpinJs is a nice Javascript based way to creating a busy/loading spinner on your webpage. I'm going to quickly go through how you might integrated SpinJs with an AngularJs app so that the spinner appears when an Ajax request is sent, and disappears when the Ajax response is received. First we will create and add interceptors. AngularJs makes this task incredibly easy and elegant. We will add the interceptors at configuration time to the httpProvider. As you can see in the above we have only put annoying alerts whenever http requests are send or received. Users would not appreciate if we stopped here! Next we will define the logic to display and hide the spinner from SpinJs. We will define it as a Provider so that it will be available to us at Configuration time. All Providers are required to expose a $get() function, but as we don't need to create multiple instances, we return null. Other than that, the above should be pretty straight forward. We store a reference to the…

Multiple environment blocks in Grails config files

As your Grails app grows, so will your config file. At some stage you might decide to make it all neat and tidy - maybe split it out in to multiple Config files. In this process you might find yourself (quite naturally) calling the environment closure multiple times. Take this example Config.groovy: environments { development { theme = 'funky' } } .... // Lastly add external configs environments { production { grails.config.locations << "file:$userHome/.cfg/app-prod.groovy" } } In the above example, when you try access grailsApplication.config.theme you will not see the expected result (funky). The reason is that the second environments block has overwritten the first one. This is a known "bug" in the Groovy ConfigSlurper. There is an active Jira and even patch submitted but it might be a while before that fix gets in. In the meantime a workaround can be to put all your app specific configuration within the grails config. So…

Log4jdbc+Grails+Tomcat7

As your Grails application grows in size and popularity you will find yourself with performance and concurrency problems to overcome. As part of this process you will likely find yourself debugging the raw sql sent to the database. Hibernate comes with functionality to do this, but it is not very most user friendly. The most popular tool for sql debugging is P6spy, but an up and coming alternative is Log4jdbc. Log4jdbc works similar to P6Spy in that you replace your usual sql driver with one provided by the tool. //driverClassName = "org.h2.Driver" driverClassName = "net.sf.log4jdbc.DriverSpy" You then have to make a change to the database connection url. You must add log4jdbc to the protocol component. Log4jdbc should then be able to detect for which driver it is proxying for. jdbc:log4jdbc:mysql://localhost/mydatabase Next you need to add appropriately to the logging configuration of your Grails app. Log4jdbc provides lots of options. I like to use j…

How to include session id and username in Grails logs

Introduction It can be very useful in debugging problems to include the session id and the logged in user's username in your logs. Of course you can do it manually in every applicable log, but there is another way, a more Spring/Grails like way. There is a feature in log4J called Mapped Diagnostic Context (MDC). This enables the storing of thread/request/context specific values in a map, that can be included in log output. To store something in this map you would write code like the following: import org.apache.log4j.MDC ... MDC.put("username", username) This entry in the MDC map can then be referenced in an application's log4J conversion pattern. To add the username defined above you would have a pattern like: %c{2} %X{username} %m%n Grails Example Let's now move to an example of how once could take advantage of MDC in Grails. Firstly, create a filter which will populate the MDC map. Such a filter could look like if you are using Spring Security: class MyFi…

Getting started with Grails functional tests using Geb + Spock

Introduction There are a number of different functional test frameworks that can be used with Grails. Each of which can be incorporated into the overall test infrastructure of your Grails app by including the relevant plugin:
Canoo WebtestG-FuncGebSelenium-RCWebDriver
Grails doesn't hold any opinion on which one to choose. This is fair, and gives developers choice, but it can also be a headache; one has to make the choice of which framework, and also do the necessary setup and configuration. The functional test framework of the day is currently Geb, which builds on top of another functional framework in WebDriver. Geb can be used with the test runners JUnit, TestNG, or Spock. Spock, like Geb is the tool dejour and they are commonly used together. The best thing about Spock tests is that they are easy to read.
New Dependencies in your BuildConfig To run your functional tests you need to include a number of libraries and plugins in your BuildConfig.groovy. Here is what you typica…

Excluding database migration changelog files from cobertura coverage in Grails

This took me a while to figure out so I thought it was worth a quick post. As is clear from the Grails Cobertura plugin documentation it is possible to exclude certain classes or packages from the coverage reports. This is very useful where there are classes such as configuration files that are impossible or pointless to test, and impact negatively on the results of your code coverage. Take this example which excludes all your typical Grails config and resources files. coverage { exclusions = ["*Config*", "*Resources*"] } In the case of Cobertura changelog files, the natural action is to add an exclude based on the assumption that the changelog is a Class, like so: coverage { exclusions = ["*Config*", "*Resources*", "*changelog*"] } But that assumption turned out to be wrong. The changelog is actually the package name so you need to add the following to get the desired exclusions: coverage { exclusions = ["*Conf…

Database migrations in Grails

When you make changes to a domain class (like adding an extra field) in your Grails application, and then deploy to production, that change is usually propagated out to the corresponding table in the database. That you don't have to manually update the structure of your table is thanks to some Hibernate magic, but this magic in not always enough. It is (rightly so) conservative in nature, and it won't perform a potentially high risk change - such as the dropping of a column - automagically. So you are left with two options. The first is to perform these higher risk changes manually, and the second is to start using the database migrations plugin.
Introduction This plugin is part of a new set of integral plugins (like resources) maintained by the leaders of the Grails community. There are already some useful articles on using the database migration plugin, but one more can't hurt! Like many aspects of the Grails ecosystem, once you grok how to use this plugin, you will see…

Grails: testing rollback of transactional service methods

Grails is so easy to dive into, but one quickly starts to encounter apparently nebulous corner cases. One such case is the testing of transactional rollback or a service method. Take the following example: class SimpleService { saveMyDog(Dog dog){ dog.save() throw new RuntimeException("don't save my doggie") } } Service methods are bound to a transaction by default, so because of the RuntimeException being thrown, in the above method the dog should not be saved/persisted.Not transactional behaviour is database dependent. Be sure you're using InnoDB!Now lets test the rollback behaviour we expect from our method class SimpleServiceTests extends GroovyTestCase { def simpleService void testSaveMyDog(){ def existingDogCount = Dog.count() simpleService.saveMyDog(new Dog()) def dogCountStayedTheSame = existingDogCount == Dog.count() ? true : false assert dogCountStayedTheSame } } The above test fails. What ?? Our rollback doesn't work…

Working together: AngularJS and Coffeescript

While building my first AngularJS application, I followed the official tutorial, and also other useful examples I found on the web. The examples were all in javascript of course, which was fine in the beginning, but after a while I started to miss the elegance of Coffeescript's syntax. Changing an AngularJS app from javascript is not as straight forward as changing the syntax. The reason for this is the Coffeescript compiler's reverence for the global scope. All coffee script code is wrapped in a function to protect the global scope from pollution and conflict.Take the following javascript controller definition from the official tutorial as an example. If you simply convert this to Coffeescript you will get a PhoneListCtrl not found exception in your browser console. function PhoneListCtrl($scope) { $scope.phones = [ {"name": "Nexus S", "snippet": "Fast just got faster with Nexus S."}, {"name": "Motorola XO…

AngularJs: User friendly date display with AngularJs and MomentJs

Whether you checkout Twitter or any of the other uber popular web apps, you will find dates displayed are often in a very user friendly "from now" format. Examples of this format are "Just now", "A few minutes ago", and "2 days ago". In these three examples a date value is displayed as an approximation of the difference between the absolute date value and the current time. This "from now" format could be applied on the server, but it is generally better to apply this on the client side via javascript so that it can be continually updated to reflect the every passing time. 2 javascript examples I've come across for applying the "from now" format are John Resig's lightweight pretty date library, and the other is more built-out Moment.js. In this post I explain how to apply a sliver of the power of MomentJs in an AngularJs application.
AngularJs is a delightful Client side javascript framework. One of its features is ca…

Specifying memory constraints for grails application on cloudfoundry

If you have tried to use the Cloudfoundry plugin to deploy a grails application to Cloudfoundry.com you would use the following command: grails prod cf-push After answering yes to all the questions you might see a deployment error due to memory constraints. And a request to delete the application Should I delete the Application? You should answer no, leaving the application that failed to start still on cloudfoundry. Then specify environment variables to stipulate memory constraints like so: grails cf-env-add JAVA_OPTS "-XX:MaxPermSize=256m -XX:+CMSClassUnloadingEnabled" Cloudfoundry will automatically attempt to restart the application after the addition of the environmental variable. That should be it! Your grails app should be live on Cloudfoundry! If you want to see what variables are registered for your application just rungrails cf-envNote: you can also update the allocated memory of your application. Just use the following vmc command:vmc mem $appName

Backbone.js: cha cha changes - keep your client in sync

In rich client javascript applications it is often desirable to keep your client side representations up-to-date with any changes that happen on the server. This post describes a strategy for doing so when using Backbone.js. We could have every model take the responsibility for polling the server itself, but that would typically mean an awful lot of unnecessary requests. To reduce the number of requests, we can have the Collection do the polling. Yes, we lose being able to us HTTP's conditional GET, but sometimes we have to eschew high ideals in the real world! Thanks to this pull request being incorporated into backbonejs, doing this just got a little easier. Now we can provide a merge option to Collection.fetch() which will merge rather than discard duplicates. Note you also have to provide the add option or the reset would naturally be called removing any existing models from the collection. I'm also assuming all models have a lastUpdated attribute. Such an attribute is…

Grails Quartz Error

Some day, if you have many quartz jobs in Grails (though it only takes 2), you might stumble upon an error like this: context.GrailsContextLoader Error executing bootstraps: org.quartz.JobPersistenceException: The job (GRAILS_JOBS.com.saasplex.app.AppInstanceHourlyJob) referenced by the trigger does not exist. The reason for this - at least in my case - is that I had copy pasted to create a new Job. The old copy paste syndrome! In doing so, I ended up with two triggers with the same name. Trigger names must be unique across all Jobs.

Grails pro tip: front-end dev and the resources plugin

I love the resources plugin than now comes by default with Grails. So much so I've authored or contributed to a number of related plugins. One frustrating aspect to the resources plugin had been the random hashy filenames I was seeing in development for all my client side files. In order to drill down into a particular javascript file for example, I had to examine the content of each file until I found the right one. Tedious it was, but finally I bit the bullet and went about looking for a solution. I added the following to the development section of my Config file, and now I see all the respective file names: grails.resources.mappers.hashandcache.excludes = ['**/*.js','**/*.coffee'] Note: there is of course a means of completely disabling the resource processing, but would mean my coffeescript files would not be compiled.