Groovy on Grails: June 2009 Archives

  • Grails is amazing at many things, but as of v1.1.1 logging configuration and documenting logging configuration is sadly not one of them. The logger has unclear default behavior that must be overridden, and several redundant complex types of syntax that can be used. To make matters worse, it's changed pretty recently and the changes were not forward compatible. This means that Google brings up a lot of useless information.

I had simple logging requirements. For production troubleshooting I want a daily log of everything (even framework code) at the INFO level. The solution was simple, but it took me lots of blind hacking to figure out. Here's what I ended up doing:

First, replace the existing log4j block in grails-app/conf/Config.groovy with this:

log4j = {
    appenders {
        appender new org.apache.log4j.DailyRollingFileAppender(name:"file", fileName:"my_grails_app.log",
                datePattern: '\'_\'yyyy-MM-dd', layout:pattern(conversionPattern: '%d{ISO8601}\t%p\t%c:%L\t%m%n'))
        console name:'stdout', layout:pattern(conversionPattern: '%d{ISO8601}\t%p\t%c:%L\t%m%n')
    }
    root {
        info 'stdout', 'file'
        additivity = true
    }
}

Next, if you don't want lots of logging when you run grails test-app change your environment configuration like this to override the default logging we set up in the previous step:

environments {
    development { ... }
    test {
        ...
        log4j = {
            root {
                error 'stdout'
                additivity = true
            }
        }
        ...
    }
    production { ... }
}

That's really it. You'll now have a daily rolling log where stacktrace.log used to be created and logging will be suppressed in test.

0 Votes

I encountered a curious bug today. A form which allows the user to edit an object and use check boxes to specify relationships to child objects stopped saving the state when some of them were checked. I assumed it was a data issue since only some of the child objects were impacted. As it turns out, using fieldValue in the definition of IDs for the check boxes was to blame. Specifically it's habit of formatting integers was to blame.

Here are the details on my situation. I had an edit page for objects of type Car and an array of check boxes to associate the Car object with its equipped accessories which were of type Accessory. The accessory I most recently added, 'Dashboard Jesus' would never stay checked.

After some fumbling around I noticed that my instantiation of the list of check boxes using a collection of Accessory objects, which used the object IDs for the check box names, had commas in it! My most recent ID has broken the 1000 barrier on my ID sequence. This caused the ID for Dashboard Jesus, and hence the HTML element ID, to be represented as 1,000.

Lessons learned:

  • fieldValue may format your data (including adding commas to an integer) so never, ever use it for anything other than the contents of a field.
  • Stuff in grails may format your IDs if you're not careful. To catch bugs early bump your sequence to a number grater than 1000. This may be possible in grails, but it seems complicated. I solved the problem simply by using a database tool to bump up my sequence value after Grails set up the database.
0 Votes

It's time for another cryptic grails v1.1.1 stack trace.

I ran into this one when committing a bit change which made the root cause difficult to track down. After much fist shaking and rage, I discovered the issue in my grails-app/conf/Config.groovy file. I had a configuration parameter that I had forgotten to quote which contained a / character.

I fixed the syntax error in Config.groovy and the problem went away.

Here's the stack trace to help confirm you've run into the same issue.

groovy.lang.MissingMethodException: No signature of method: groovy.util.ConfigObject.div() is applicable for argument types: (groovy.util.ConfigObject) values: [[:]]
    at Config.run(Config.groovy:41)
    at GrailsPackagegroovy$runclosure1.doCall(GrailsPackagegroovy:45)
    at GrailsPackagegroovy$runclosure2closure10.doCall(GrailsPackagegroovy:87)
    at _GrailsPackagegroovy$runclosure2closure10.doCall(GrailsPackagegroovy)
    at _GrailsSettingsgroovy$runclosure10.doCall(GrailsSettingsgroovy:274)
    at GrailsSettingsgroovy$runclosure10.call(GrailsSettingsgroovy)
    at GrailsPackagegroovy$runclosure2.doCall(GrailsPackagegroovy:86)
    at GrailsBootstrapgroovy$runclosure7.doCall(GrailsBootstrapgroovy:140)
    at GrailsTestgroovy$runclosure7.doCall(GrailsTestgroovy:249)
    at GrailsTestgroovy$runclosure7.doCall(GrailsTestgroovy)
    at GrailsTestgroovy$runclosure1closure19.doCall(GrailsTestgroovy:110)
    at _GrailsTestgroovy$runclosure1.doCall(GrailsTestgroovy:96)
    at TestApp$runclosure1.doCall(TestApp.groovy:66)
    at gant.Gant$dispatchclosure4.doCall(Gant.groovy:324)
    at gant.Gant$dispatchclosure6.doCall(Gant.groovy:334)
    at gant.Gant$dispatchclosure6.doCall(Gant.groovy)
    at gant.Gant.withBuildListeners(Gant.groovy:344)
    at gant.Gant.this$2$withBuildListeners(Gant.groovy)
    at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
    at gant.Gant.dispatch(Gant.groovy:334)
    at gant.Gant.this$2$dispatch(Gant.groovy)
    at gant.Gant.invokeMethod(Gant.groovy)
    at gant.Gant.processTargets(Gant.groovy:495)
    at gant.Gant.processTargets(Gant.groovy:480)
Failed to compile configuration file: No signature of method: groovy.util.ConfigObject.div() is applicable for argument types: (groovy.util.ConfigObject) values: [[:]]

0 Votes

About this Archive

This page is an archive of entries in the Groovy on Grails category from June 2009.

Groovy on Grails: May 2009 is the previous archive.

Groovy on Grails: July 2009 is the next archive.

Find recent content on the main index or look in the archives to find all content.