getting grails 2.0.0M1 config info in domain object, and static scope?
Asked Answered
C

4

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.

Conclusive answered 8/8, 2011 at 1:23 Comment(0)
P
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.

Poolroom answered 8/8, 2011 at 6:32 Comment(5)
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!Conclusive
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 ;)Conclusive
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!Conclusive
Burt, please do include grailApplication in DCs in Grails 2.0, would be a convenient, concise, & useful additionHeda
@Burt Beckwith, is the grails.util.Holders method, mentioned by Ian Roberts, the new preferred way to do this?Impetuosity
D
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
}
Distichous answered 28/5, 2013 at 10:34 Comment(2)
This was particularly helpful in the static triggers block of quartz scheduled jobs. Thanks!Tentage
This is also working in the hibernate mappings in domain to have thing configurable from external properties file. Thanks.Ogg
P
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.

Poolroom answered 8/8, 2011 at 6:32 Comment(5)
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!Conclusive
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 ;)Conclusive
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!Conclusive
Burt, please do include grailApplication in DCs in Grails 2.0, would be a convenient, concise, & useful additionHeda
@Burt Beckwith, is the grails.util.Holders method, mentioned by Ian Roberts, the new preferred way to do this?Impetuosity
E
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
Edible answered 28/5, 2013 at 10:10 Comment(0)
J
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
    ...
    
Jemimah answered 10/9, 2014 at 19:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.