POTD: Application configuration via Guice binding + Groovy

Often I write my applications with Guice. I also often want to make those applications configurable externally. For example I might inject username and password for that app to talk to another app, I might configure some timeout value, and so on. I make these configuration values available in Guice, so that I can access them wherever I need them. All of this is pretty common in many other places, I’d imagine.

Given that all I’m doing here is to pass configuration values from left to right, I thought it’d be nice if I can write configuration directly as a Guice module by using Guice binder EDSL. Then I won’t have to parse and translate these configuration any more.

And that became my project of the day.

This little library allows you to write Guice binding definitions in a text file:

timeout = 3
bind Payment named "customer" to VisaPayment

From your program, you use GroovyWiringModule to load this configuration file:

Module config = new GroovyWiringModule(new File("/etc/myapp.conf"));
Injector i = Guice.createInjector(
  Modules.override( ... my application's modules ...)

The end result is that the above script gets translated into the following binding:


Using Groovy as the host language for DSL has other benefits. If you are using system properties or environment variables to configure something, you are basically stuck with strings as the only representation of the configuration. With Groovy, I can create a relatively complex object and bind them, or even put some logic to further obtain values from elsewhere:

bind Payment toInstance new VisaPayment(
  cardNumber: "1234-5678-9012-3456",
  expiration: new Date(System.currentTimeInMillis()+TimeUnit.DAYS.toMillis(30),
  cvv: new URL("http://secret.server/cvv").text) 

With the functionality in Guice to override definitions in one module by another, I can also even override bindings defined in programs, for example to get more logging, add a filter, etc.

6 Comments Add yours

  1. Vivek says:

    Pretty cool. The Pattern I have using is injectable Configuration object constructed from a configuration file, I also use it during guide binding. Your approach is very handy, makes these bendable infections auto configurable.

    There is a typo – “annotatedWith(Names.named(“timeout”)).to(VisaPayment.class)” timeout should be “customer”.

  2. Emanuele says:

    Sweet! Did you post this in the Guice mailing list? I’m sure they would appreciate it! 🙂

  3. kohsuke says:

    Thanks, corrected.

  4. kohsuke says:

    All right, I guess I will post this and see what happens.

  5. Ross Judson says:

    The text DSL is neat, but losing type safety isn’t a fun part of that. 😉

    As one of the architects of HK2, why would you use Guice instead of HK2? And conversely, why use HK2 instead of Guice?

  6. kohsuke says:

    This is meant for configuration of apps, and in that context I don’t think there’s a loss of type safety here. You run the app and you’ll get any type errors reported.

    As for HK2 vs Guice, I don’t think a technical difference was a major part of decisions behind doing it, and right now I have no reasons to use HK2.

Leave a Reply

Your email address will not be published. Required fields are marked *