Create your own Grails holder class
I mentioned in an earlier post
that using Grails *Holder classes should be avoided, and showed how to access the GrailsApplication, ApplicationContext, etc. from domain classes. But there are still cases where you need access to these objects and dependency injection and the approach I described aren’t sufficient. When all else fails you can always create your own holder class.
The reason this works in your application but not in Grails is that the static fields in your application are only accessed within your application. By using shared jars, multiple applications share static state held by shared classes, but this isn’t a problem for your code.
Since everything is reachable from the ApplicationContext and it’s easy to access, we’ll create a holder for that and expose the other objects from there.
Create a class called ApplicationContextHolder that implements ApplicationContextAware:
package com.yourcompany.yourapp
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
@Singleton
class ApplicationContextHolder implements ApplicationContextAware {
private ApplicationContext ctx
void setApplicationContext(ApplicationContext applicationContext) {
ctx = applicationContext
}
static ApplicationContext getApplicationContext() {
getInstance().ctx
}
}
and register it in resources.groovy so the ApplicationContext is injected (using the factoryMethod attribute since the class is a singleton):
import com.yourcompany.yourapp.ApplicationContextHolder
beans = {
applicationContextHolder(ApplicationContextHolder) { bean ->
bean.factoryMethod = 'getInstance'
}
}
Now you can use the ApplicationContext from anywhere to access Spring beans. We can go further though, adding utility methods to expose other classes held by holders:
static Object getBean(String name) {
getApplicationContext().getBean(name)
}
static GrailsApplication getGrailsApplication() {
getBean('grailsApplication')
}
static ConfigObject getConfig() {
getGrailsApplication().config
}
static ServletContext getServletContext() {
getBean('servletContext')
}
static GrailsPluginManager getPluginManager() {
getBean('pluginManager')
}
You can also add the ability to register mock beans for unit tests; here’s the complete class:
package com.yourcompany.yourapp
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import javax.servlet.ServletContext
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.codehaus.groovy.grails.plugins.GrailsPluginManager
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
@Singleton
class ApplicationContextHolder implements ApplicationContextAware {
private ApplicationContext ctx
private static final Map<String, Object> TEST_BEANS = [:]
void setApplicationContext(ApplicationContext applicationContext) {
ctx = applicationContext
}
static ApplicationContext getApplicationContext() {
getInstance().ctx
}
static Object getBean(String name) {
TEST_BEANS[name] ?: getApplicationContext().getBean(name)
}
static GrailsApplication getGrailsApplication() {
getBean('grailsApplication')
}
static ConfigObject getConfig() {
getGrailsApplication().config
}
static ServletContext getServletContext() {
getBean('servletContext')
}
static GrailsPluginManager getPluginManager() {
getBean('pluginManager')
}
// For testing
static void registerTestBean(String name, bean) {
TEST_BEANS[name] = bean
}
// For testing
static void unregisterTestBeans() {
TEST_BEANS.clear()
}
}
Note that the servletContext and pluginManager beans are available in a running application but not the Grails console.







An earlier comment on a post contextualized this by giving a specific use case: accessing a static string for URL mapping. While it is probably unreasonable to ask for an exhaustive set of use cases, posts like this may be improved by early consideration and guidance on “when would I use this?”
Why not let grails create-app create the ApplicationContextHolder?
Burt,
I tried creating ApplicationContextHolder.groovy under src/groovy, but the method setApplicationContext is never called. Its declared in resources.groovy. I am using 2.0.0.RC1, any thoughts what could be going wrong here?
Thanks
Correction – It does get set, however I am trying to read configurations in one my job triggers to establish repeat interval, and at that point, there is no grailsApplication, hence NULL config. It use to work fine, but now ConfigurationHolder gone, what is the suggested way to handle this use-case?
I have the same question. I have a quartz job and need to store the cron expression in my config file. I am trying to set it like this:
static triggers = {
cron name: ‘cronTrigger’, startDelay: 0, cronExpression: ACH.config.batch.cron.expression.validateDelegates
}
I get this error:
Cannot invoke method getBean() on null object
In my ApplicationContextHolder, getApplicationContext() is returning null. Anyone have a suggestion?
Can you use this in the _Events.groovy file? I am having problems getting the configuration.
Asked the grails user mailing list. config is accessible without needing any of the wiring above.
So how do you get at the config in static context without any of the above? Thanks.
Hi Burt, thanks for this post.
I tried to use your solution but I’m getting the following error:
“Cannot invoke method getBean() on null object”.
The error is triggered because the private variable “private ApplicationContext ctx” is null. I can’t understand when and how to set that up for the instance?