Recently in Groovy on Grails Category

With the release of Grails 1.3.1 we decided that it was finally time to stop our ‘copy all the jars to lib’ process and use the awesome dependency manager.

As with any move from static lib directory to a smarter dependency manager we ran into some puzzling issues. One engineer set it all up and it worked great on our build system, but then about 50% of our engineers ran into some strange issues including this one which prevented any grails scripts from running:

...
SLF4J: This version of SLF4J requires log4j version 1.2.12 or later. See also http://www.slf4j.org/codes.html#log4j_version
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/john_doe/.ivy2/cache/org.slf4j/slf4j-log4j12/jars/slf4j-log4j12-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/john_doe/.ivy2/cache/org.slf4j/nlog4j/jars/nlog4j-1.2.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
...

Hacking around randomly seemed to fix it in every case. Here’s the crude process we ended up following to resolve these strange issues:

  1. Purge the local caches by deleting ~/.ivy and ~/.grails
  2. Reboot (Yes this fixed the problem for someone… go figure)
  3. Run grails upgrade over and over until it started working

What is the root cause? I have no idea. Perhaps our dependency on the public repositories is to blame: one should never trust a free third party service.

0 Votes

Today I managed to set up my grails environment in such a way that it triggered deadlocks quite easily when stressed with a simple jmeter script. While this was unintentional, it did give me an opportunity to diffuse some ticking time bombs.

A few of the deadlocks were caused by some of the creative ways that my project uses the Groovy on Grails APIs for rendering pages from GSP code stored in a database, and with some tweaks most of those were resolved.

Some other deadlocks, though, seem to be the fault of Groovy itself. A quick google search turned up over 300 hits relating to deadlocks in the Groovy bug tracker:

http://www.google.com/search?hl=en&q=site:jira.codehaus.org+%2Bgroovy+%2Bdeadlock

This is when I had a sad.

I know that as an open source project if a bug really bothers me, I should submit a patch, which I am likely to do, but even if I find fixes for some of the deadlocks I’m facing, I’ll either have to wait for the changes to make it into the Groovy codebase, Groovy to release, grails to pick up the changes, etc. or I’ll have to hack the patch into my application and hope for the best.

Hopefully I’ll find some magic work around that does not tickle these bugs :)

Update: Someone must have seen this blog entry, or maybe they’re just cool. Anyway, they fixed this problem wicked fast: http://jira.codehaus.org/browse/GRAILS-6398 Grails continues to rock as a result.

0 Votes

Sometimes you will need to switch up configuration in a hurry. For example, you may need to switch the database connection URL in order to use your warm standby database. This can be a pain in Grails because the convient-during-development Config.groovy is compiled both by grails run-app and grails war.

The simplest way to change configuration without rebuilding and redeploying your Grails application is to make use of an externalized configuration file. Although would appear to be very straight forward based on the docs, you will need to jump through a couple undocumented hoops to get it working in all environments.

  1. Create your override configuration file in the grails-app/conf folder. I called mine override.conf. For now you can leave it empty.
  2. Enable this external configuration file by pasting this into the top of your grails-app/conf/Config.groovy file:
grails.config.locations = [ "classpath:override.properties"  ]
This is where the docs end. When you start up grails you’ll see the following error message:
Unable to load specified config location classpath:override.properties : class path resource [override.properties] cannot be opened because it does not exist
1. Grails uses different paths in run-app mode and when being run as a war. We’re going to need to add a step post compilation to ensure our configuration file is available at all times. We’ll do this by modifying _Events.groovy (or Events.groovy if you’ve been migrating your grails app since v1.1). Open scripts/_Events.groovy, or create it if it does not exist. 1. Add the following to _Events.groovy (or merge it in if you already have an eventCompileEnd defined):
eventCompileEnd = {
    ant.copy(todir:classesDirPath) {
      fileset(file:"${basedir}/grails-app/conf/override.properties")
    }
}
  1. Try setting a new property and fire up grails as usual. For example, if you want to set the database URL, you’d add this to your grails-app/conf/override.properties file:
dataSource.url=jdbc:postgresql://example.host/somedb:shutdown=true

Source: Some Grails - user mailing list post by Ian Roberts

0 Votes

The Problem

The other day I was doing some bulk file operations on a grails project. I was moving some classes in bulk from a plug-in into an application. After I made the move I ran into a puzzling issue: grails kept restarting in a loop. Each time the plugin scanner ran (every 5 seconds after startup), grails would complain that it needed to compile 1 file. This went on for a few minutes until my app ran out of PermGen and crashed. To make matters worse, grails would not tell me which file it was recompiling even with logging set to trace!

This seems to be a classic grails issue that is rare, but frustrating.

The Cause

The likely cause is a groovy file outside the correct package or with a file name that does not match the case name. The latter can happen when tinkering around between case sensitive and case insensitive file systems as is common when developing with OS X.

The Fix

To fix it you need to find the messed up class and fix it. The below method is crude, but works.

  1. If your app crashes quickly due to PermGen issues, provide more PermGen space. You’ll need at least 2 or 3 minutes of run time for this to work. Use the JVM argument -XX:MaxPermSize=1024m if you have to.
  2. Let your app run for a few minutes. Let it recompile that file a few times.
  3. If your app has not already crashed, stop it
  4. Now to find the compiled class file. Go to the directory where grails claims to be compiling the file. In my case it was in ~/.grails/1.2.0/projects/fooApp/classes
  5. Run this shell command to see when most of the files were updated: find ./ | xargs ls -al The vast majority of the listed files should all have an updated time within the same minute. In my case it was 15:17 Lets fileter those out and see what’s left behind.
  6. Run another find command and see the newer files: find ./ | xargs ls -al | grep -v 15:17. I saw a few files and headers that had to be ignored, but in the middle I found the class name which was compiled from a .groovy file of a different name.
  7. Go back to your app code and resolve the conflicted state of your groovy file(s)
  8. Quit cursing under your breath and go have a beer if you need one
0 Votes

Maybe you just upgraded Groovy on Grails, or maybe you’re doing a fresh install. Either way you may be confronted with this curious error message:

$ grails test
Exception in thread "main" java.lang.NoClassDefFoundError: org/codehaus/groovy/grails/cli/support/GrailsStarter

What’s wrong? You have a grails mismatch. Your GRAILS_HOME environment variable is not pointing to the same place as the grails in your PATH. Make them agree and try your grails command again.

0 Votes