tags:

views:

38

answers:

0

Using ContextLoaderListener to attach parent ApplicationContext to Grails ApplicationContext does not work in Integration Tests

To make our grails application work with the rest of our existing spring application, we followed the advice in http://grails.1312388.n4.nabble.com/Grails-and-existing-Spring-web-app-integration-issues-td1339360.html and used a custom ContextLoaderListener, so our application context is the parent of the Grails Application context.

However, when we run Grails Integration tests this way, ContextLoaderListener does not get invoked, and so the beans in our ApplicationContext are not available.

The following is how we attach "our" app context to the grails app context:

In \src\templates\war\web.xml:

<listener>
     <listener-class>com.mycompany.grails.CustomGrailsContextLoaderListener</listener-class>
</listener>

And the implementation of the ContextLoaderListener:

     
    public class CustomGrailsContextLoaderListener extends ContextLoaderListener {
         @Override
         protected ContextLoader createContextLoader() {
              return new CustomGrailsContextLoader();
         }
    }

    public class CustomGrailsContextLoader extends GrailsContextLoader {
        @Override
        protected ApplicationContext loadParentContext(ServletContext arg0) throws BeansException {
            return SpringAccess.initializeAndGetApplicationContext();
        }
    }

Where SpringAccess.initializeAndGetApplicationContext(); does what the name implies

What is the right way to attach an external application context to the grails app context, and have it available in both the running application and in the integration tests?

Update: I found a way to do this after stepping through lots of Grails code in a debugger, but for obvious reasons this solution rubs me the wrong way... it seems like there should be a cleaner method.

In resources.groovy, I added:

if(Environment.TEST == Environment.getCurrent()) {
    GrailsApplication application = ApplicationHolder.getApplication()
    ConfigurableApplicationContext parent = (ConfigurableApplicationContext)application.getParentContext();
    parent.setParent(SpringAccess.initializeAndGetApplicationContext());
}