Grails: Injecting Config Parameters

Asume we have a configuration value of type String and we want to use it at multiple places, e.g. in grails services and controllers.

The standard way seems to be an entry in Config.groovy

a.deeply.nested.value = "a.deeply.nested value!"

and then this ugly piece of code to acces the configuration:

class Ugly(Controller|Service) {
    def grailsApplication

    String NESTED_VALUE = grailsApplication.config.a.deeply.nested.value

    // ...
}

Which is already better than using grailsApplication.config.... spread around the controller.

I don’t like this very much because of the extra dependency (grailsApplication) and the config object we may have to setup just to write a simple test for our code. Each additional dependency makes testing harder. And this just because of a simple configuration value.

Is there a better way? Let’s google….

I found a couple of different solutions that don’t need grailsApplication.

 

Springs @Value annotation

 

I found this here.

Using the @Value annotation works out of the box (using grails 2.2.3):

class LessUglyController {
    @Value('${a.deeply.nested.value}')
    String NESTED_VALUE

    // ...
}

This looks better. We get rid of grailsApplication and we can strip grailsApplication.config from our configuration path. Testing gets easier without the grailsApplication dependency.

But.. personally I’m not happy with the annotation “noise” and having the config value in a string. IntelliJ doesn’t do auto completion here ;-)

 

using resources.groovy

 

This is standard grails stuff. Adding an entry for a service works without problem:

resources.groovy:

someService(SomeService) {
    NESTED_VALUE = application.config.a.deeply.nested.value
}

and the service

class SomeService {
    String NESTED_VALUE

    // ...
}

But I didn’t get it working for a controller until I found an enlightening answer to a question on stackoverflow.

The trick is, that we have to specify the full classname with package to overide a controller bean.

resources.groovy:

'com.wordpress.softnoise.SomeController'(SomeController) {
    NESTED_VALUE = application.config.a.deeply.nested.value
}

Note the quotes arround the canonical name.

The controller looks like the service above:

class SomeController {
    String NESTED_VALUE
    // ...
}

Both version with no noise at all :-) Not too bad.

Now, there is still a better version using Config.groovy

 

using beans in Config.groovy

 

Uhh, using Config.groovy to inject a value from Config.groovy into a spring bean? Yes, and it is even documented in the grails documentation here.

We can simply put this into Config.groovy to inject the value into the service bean.

beans {
    someService {
        NESTED_VALUE = a.deeply.nested.value
    }
}

This also works for controllers we just have to use the same trick as in resources.groovy:

beans {
    'com.wordpress.softnoise.SomeController' {
            NESTED_VALUE = a.deeply.nested.value
    }
}

That is nice, no extra noise in the bean and the config path doesn’t leave the Config.groovy file.

 

conclusion

 

I think the easiest and best solution is the beans configuration in Config.groovy.

No more grailsApplication.config. :-)

Intellij IDEA, Cucumber and German Spell Checking

Now that Intellij IDEA (12.1.3 in my case) supports auto completion & syntax highlighting for cucumber features not only in english but also in any other language that is available for gherkin it would be nice to have native spell checking as well.

To use your native language with cucumber you just have to place a language comment at the first line of your feature file. For example see this super useful feature description:

# language: de

Funktionalität: deutsche Feature-Beschreibungen
  Um cucumber in unserer Muttersprache zu benutzten
  möchte ich als Szenario-Schreiber
  die deutschen Schlüsselwörter benutzen

  Szenario: deutsche Schlüsselwörter & Steps
    Angenommen ich schreibe eine Feature-Beschreibung
    Wenn ich die deutschen Gherkin-Schlüsselwörter benutze
    Dann werden die deutschen Steps aufgerufen

To get spell checking for an additional language in IntelliJ we need to add a dictionary for that language. This is done in a few simple steps:

  • first, we need a dictionary for our language. This is a plain text file with a lot of words, each on a single line. I found a german dictionary on sourceforge.
  • second, we need to make sure it is encoded in utf–8. The german.dic file was encoded in latin–1. If it is not encode in utf–8 use your text editor of choice (e.g. Notepadd++ or TextWrangler or …) and convert it to utf–8 (no BOM).
  • third, create a folder (e.g. dictionaries) where you want to save the dic file
  • fourth, tell IntelliJ about the dictionary folder following the documentation, which is in short:
    1. open the Settings dialog
    2. type ‘spell’ into the search box and select Spelling
    3. switch to the Dictionaries tab
    4. and add the folder to the Custom Dictionaries Folder list

You should see now the dictionary under Dictionaries as a user dictionary and the checkbox enabled.

That’s it, no more typos in the features :-)