2

I have three environments blocks in my Grails config file similar to this:

environments {
    production {
        grails.serverURL = "https://www.mysite.com"
    }
    development {
        grails.serverURL = "http://localhost:8080/${appName}"
    }
    test {
        grails.serverURL = "http://localhost:8080/${appName}"
    }
}

... // more code

environments {
    production {
        authnet.apiId = "123456"
        authnet.testAccount = "false"
    }
    development {
        authnet.apiId = "654321"
        authnet.testAccount = "true"
    }
    test {
        authnet.apiId = "654321"
        authnet.testAccount = "true"
    }
}

... // more code

environments {
    production {
        email.sales = 'sales@mysite.com'
    }
    development {
        email.sales = 'test@mysite.com'
    }
    test {
        email.sales = 'test@mysite.com'
    }
}

Somewhere in a controller:

println grailsApplication.config.grails.serverURL
println grailsApplication.config.authnet.apiId
println grailsApplication.config.email.sales

It prints out:

http://localhost:8080/myapp
[:]
test@mysite.com

So for some reason the app can't get data from some environments blocks. The stuff outside of environments blocks is fine. I noticed this issue with several different apps, different configs etc. Tried getting it with both grailsApplication and ConfigurationHolder. Is it a Grails bug or I'm doing something wrong? I'm running Grails 1.3.6

Slavko
  • 486
  • 3
  • 6
  • 12

2 Answers2

4

Your redefineing your configuration info several times. SInce your writing groovy code that gets executed instead of XML configuration your changes don't get automatically merged, multiple configuration blocks overwrite each other. You need to define everything in one block like

environments {
    development {
        grails.serverURL = "http://localhost:8080/${appName}"
        authnet.apiId = "654321"
        authnet.testAccount = "true"
    }
    test {
        grails.serverURL = "http://localhost:8080/${appName}"
        authnet.apiId = "654321"
        authnet.testAccount = "true"
    }
    production {
        grails.serverURL = "https://www.mysite.com"
        authnet.apiId = "123456"
        authnet.testAccount = "false"
        }
Jared
  • 39,513
  • 29
  • 110
  • 145
  • Yes, that's what I ended up doing. Just wanted to keep those things separate for the sake of organization. Still it's unclear why two blocks work just fine but the third (or actually the second) one fails. – Slavko Jul 19 '11 at 17:54
  • @Slavko, same thing happened to me FWIW(i.e. stopped working with 3 blocks). I think the grails doco (1.3.7) is a bit light on in this area (IMHO). – Jon Burgess Nov 09 '11 at 03:48
0

You're running using the development environment, therefore you are selecting the host and port from the development settings. By default,

grails run-app

runs the application using the development environment. To run it in production, either build a war file using the command grails war, and deploy it in a servlet container, or use:

grails prod run-app

See http://www.grails.org/Environments for more information.

Stuart Watt
  • 5,242
  • 2
  • 24
  • 31
  • Because the environment means that only stuff in `development { ... }` becomes part of your configuration. The other stuff is only applied if you run in a production or test environment. That seems to be exactly what you are observing. – Stuart Watt Jul 19 '11 at 18:24
  • OK, I now think I understand the issue. Could be clearer in the question, maybe. I guess you mean, why does the setting for authnet.apiId end up broken? Interestingly, it is set to a map. That cannot be a coincidence. Is something accidentally overwriting that value? – Stuart Watt Jul 19 '11 at 18:33
  • No, nothing is overwriting the value, the name is unique. Grails is always returning an empty map when it's unable to find the param. – Slavko Jul 19 '11 at 18:38
  • Much longer discussion of this issue at: http://grails.1312388.n4.nabble.com/multiple-environments-blocks-in-Config-groovy-td3276017.html. In a nutshell, it seems likely to be a Groovy ConfigSlurper bug. I'd try the non-closure-based approach at the end of http://groovy.codehaus.org/ConfigSlurper and see if it works better – Stuart Watt Jul 19 '11 at 19:38
  • Thanks. You can also use a construction like foo.development.email.support = "test@example.com" foo.production.email.support = "support@example.com" with a properly configured ConfigurationHolder, but the closure version looks cleaner to me. – Slavko Jul 19 '11 at 19:51