6

How do I get to the Config.groovy information from a domain object, or from a static scope? I'm using ConfigurationHolder.config.* now, but that and ApplicationHolder are deprecated so I'd like to 'do it right' ... but the grailsApplication object isn't available in a DO/static scope.

Wayne
  • 1,075
  • 1
  • 10
  • 21

4 Answers4

19

The Grails 2 replacement for the deprecated ApplicationHolder, ConfigurationHolder, etc. is grails.util.Holders, which provides the same functionality but in a way that is safe when several different webapps in the same container are sharing a single copy of the Grails JARs in a parent classloader (this being the case where the old holders broke down).

import grails.util.Holders

// ...

static void foo() {
  def configOption = Holders.config.myapp.option
}
Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • This was particularly helpful in the static triggers block of quartz scheduled jobs. Thanks! – Gary Jun 27 '13 at 14:39
  • This is also working in the hibernate mappings in domain to have thing configurable from external properties file. Thanks. – Eduard Aug 20 '13 at 14:10
8

I'd add the grailsApplication to the metaclass of domain classes - this is something I'm thinking about doing for 2.0 final. For now, put it in BootStrap.groovy, e.g.

class BootStrap {

   def grailsApplication

   def init = { servletContext ->
      for (dc in grailsApplication.domainClasses) {
         dc.clazz.metaClass.getGrailsApplication = { -> grailsApplication }
         dc.clazz.metaClass.static.getGrailsApplication = { -> grailsApplication }
      }      
   }
}

Then you can access the config from grailsApplication.config, and Spring beans via grailsApplication.mainContext.getBean('foo') or just grailsApplication.mainContext.foo.

Burt Beckwith
  • 75,342
  • 5
  • 143
  • 156
  • Good idea ... but, startup fails with "Caused by: org.hibernate.InstantiationException: could not instantiate test objectqdcore.UserCallFlow" (qdcore.UserCallFlow is a domain class), as it appears Hibernate is doing something before the Bootstrap runs. To get around that, I use safe deref (e.g., grailsApplication?.config?.qdcore?.servers?.upload?.url ) so that Hibernate is happy, the Bootstrap gets to run, and then grailsApplication is available. Thanks! – Wayne Aug 08 '11 at 17:09
  • But, even with safe deref in the DO (def grailsApplication; def config=grailsApplication?.config; def String usrv = config?.qdcore?.servers?.upload?.url) I'm getting null values, so I'm not using it right, quite yet - I'll post back when I get myself sorted out ;) – Wayne Aug 08 '11 at 17:46
  • What works in the DO is to use the static scope for grailsApplication, and the instance scope for the rest; e.g.,class UCF { static grailsApplication; def config=grailsApplication?.config; def String usrv = config?.qdcore?.servers?.upload?.url ...} I can't use static scope for the others, since then I get exceptions that "grailsApplication" is null when I try to get its config property. This is a bit twitchy, perhaps, but it works for this prototyping app! – Wayne Aug 08 '11 at 18:40
  • Burt, please do include grailApplication in DCs in Grails 2.0, would be a convenient, concise, & useful addition – virtualeyes Oct 06 '11 at 06:19
  • @Burt Beckwith, is the `grails.util.Holders` method, mentioned by Ian Roberts, the new preferred way to do this? – James McMahon Aug 21 '13 at 15:12
1

I really wanted to access config in static utilities only. After searching and reading most of the answers on SO, i came with simple solution(May be useful for somebody):

Add holder class under src/groovy:

class StaticContext {
    static def app;
}

initialize it in bootstrap init

class BootStrap {

    def grailsApplication

    def init = { servletContext ->
      StaticContext.app = grailsApplication
    }

    def destroy = {
    }
}

And access it in static utilities :

//In my case Solr URL in single ton
def solrUrl = StaticContext.app.config.solr.url
Thamme Gowda
  • 11,249
  • 5
  • 50
  • 57
1

In Grails 2.2.5 I found this would work:

  1. Configure your variable in grails-app/conf/Config.groovy, in the section appropiate for your environment. For example:

    environments {
    ...
      development {
      ...
        grails.config.myUrl = "http://localhost:3000"
        ...
    

    ...

  2. To access:

    import grails.util.Holders
    
    class myClass {
    ...
    
       def static myStaticMethod() {
          def myVar = Holders.config.grails.config.myUrl
    ...
    
AlejandroVD
  • 1,576
  • 19
  • 22