@@ -38,30 +38,26 @@ import org.grails.plugins.IncludingPluginFilter
3838import org.grails.spring.RuntimeSpringConfiguration
3939import org.grails.spring.beans.factory.OptimizedAutowireCapableBeanFactory
4040import org.grails.web.context.ServletEnvironmentGrailsApplicationDiscoveryStrategy
41- import org.grails.web.converters.configuration.ConvertersConfigurationHolder
4241import org.grails.web.servlet.context.GrailsConfigUtils
4342import org.slf4j.Logger
4443import org.slf4j.LoggerFactory
4544import org.springframework.beans.CachedIntrospectionResults
4645import org.springframework.beans.MutablePropertyValues
4746import org.springframework.beans.factory.config.BeanDefinition
47+ import org.springframework.beans.factory.config.ConfigurableBeanFactory
4848import org.springframework.beans.factory.config.ConstructorArgumentValues
4949import org.springframework.beans.factory.support.BeanDefinitionRegistry
50- import org.springframework.beans.factory.support.DefaultListableBeanFactory
5150import org.springframework.beans.factory.support.RootBeanDefinition
5251import org.springframework.boot.test.ConfigFileApplicationContextInitializer
5352import org.springframework.context.ApplicationContext
5453import org.springframework.context.ConfigurableApplicationContext
5554import org.springframework.context.annotation.AnnotationConfigUtils
56- import org.springframework.mock.web.MockServletContext
5755import org.springframework.test.annotation.DirtiesContext
5856import org.springframework.test.context.MergedContextConfiguration
5957import org.springframework.test.context.TestContextManager
60- import org.springframework.web.context.support.GenericWebApplicationContext
58+ import org.springframework.util.ClassUtils
6159
62- import javax.servlet.ServletContext
6360import java.lang.reflect.Modifier
64-
6561/**
6662 * A TestPlugin for TestRuntime that builds the GrailsApplication instance for tests
6763 *
@@ -72,6 +68,7 @@ import java.lang.reflect.Modifier
7268@CompileStatic
7369class GrailsApplicationTestPlugin implements TestPlugin {
7470 protected final Logger log = LoggerFactory . getLogger(getClass());
71+ protected static final boolean isServletApiPresent = ClassUtils . isPresent(" javax.servlet.ServletContext" , GrailsApplicationTestPlugin . classLoader)
7572
7673 static boolean disableClearSpringTestContextManagerCache = Boolean . getBoolean(" grails.test.runtime.disable_clear_spring_tcf_cache" )
7774 String [] requiredFeatures = [' metaClassCleaner' ]
@@ -89,17 +86,15 @@ class GrailsApplicationTestPlugin implements TestPlugin {
8986 }
9087
9188 void initGrailsApplication (final TestRuntime runtime , final Map callerInfo ) {
92- ServletContext servletContext = createServletContext(runtime, callerInfo)
89+ Object servletContext = createServletContext(runtime, callerInfo)
9390 runtime. putValue(" servletContext" , servletContext)
9491
95- GenericWebApplicationContext mainContext = createMainContext(runtime, callerInfo, servletContext)
92+ ConfigurableApplicationContext mainContext = createMainContext(runtime, callerInfo, servletContext)
9693
9794 GrailsApplication grailsApplication = (GrailsApplication )runtime. getValueIfExists(" grailsApplication" )
9895
99- if (servletContext != null ) {
100- Holders . setServletContext(servletContext);
101- Holders . addApplicationDiscoveryStrategy(new ServletEnvironmentGrailsApplicationDiscoveryStrategy (servletContext));
102- GrailsConfigUtils . configureServletContextAttributes(servletContext, grailsApplication, mainContext. getBean(GrailsPluginManager . BEAN_NAME , GrailsPluginManager ), mainContext)
96+ if (isServletApiPresent && servletContext != null ) {
97+ configureServletEnvironment(servletContext, grailsApplication, mainContext)
10398 }
10499
105100 if (! grailsApplication. isInitialised()) {
@@ -109,9 +104,25 @@ class GrailsApplicationTestPlugin implements TestPlugin {
109104 applicationInitialized(runtime, grailsApplication)
110105 }
111106
112- protected GenericWebApplicationContext createMainContext (final TestRuntime runtime , final Map callerInfo , final ServletContext servletContext ) {
113- GenericWebApplicationContext context = new GenericWebApplicationContext (new OptimizedAutowireCapableBeanFactory (), servletContext);
114- DefaultListableBeanFactory beanFactory = context. getDefaultListableBeanFactory()
107+ @CompileDynamic
108+ protected void configureServletEnvironment (servletContext , GrailsApplication grailsApplication , ConfigurableApplicationContext mainContext ) {
109+ Holders . setServletContext(servletContext);
110+ Holders . addApplicationDiscoveryStrategy(new ServletEnvironmentGrailsApplicationDiscoveryStrategy (servletContext));
111+ GrailsConfigUtils . configureServletContextAttributes(servletContext, grailsApplication, mainContext. getBean(GrailsPluginManager . BEAN_NAME , GrailsPluginManager ), mainContext)
112+ }
113+
114+ protected ConfigurableApplicationContext createMainContext (final TestRuntime runtime , final Map callerInfo , final servletContext ) {
115+ ConfigurableApplicationContext context
116+
117+ if (isServletApiPresent && servletContext != null ) {
118+ context = (ConfigurableApplicationContext )ClassUtils . forName(" org.springframework.web.context.support.GenericWebApplicationContext" ). newInstance( new OptimizedAutowireCapableBeanFactory (), servletContext);
119+ }
120+ else {
121+ context = (ConfigurableApplicationContext )ClassUtils . forName(" org.springframework.context.support.GenericApplicationContext" ). newInstance( new OptimizedAutowireCapableBeanFactory ());
122+ }
123+
124+
125+ ConfigurableBeanFactory beanFactory = context. getBeanFactory()
115126
116127 prepareContext(context, beanFactory, runtime, callerInfo);
117128 customizeContext(context, beanFactory, runtime, callerInfo);
@@ -121,17 +132,17 @@ class GrailsApplicationTestPlugin implements TestPlugin {
121132 return context
122133 }
123134
124- protected void prepareContext (ConfigurableApplicationContext applicationContext , DefaultListableBeanFactory beanFactory , TestRuntime runtime , Map callerInfo ) {
135+ protected void prepareContext (ConfigurableApplicationContext applicationContext , ConfigurableBeanFactory beanFactory , TestRuntime runtime , Map callerInfo ) {
125136 registerGrailsAppPostProcessorBean(applicationContext, beanFactory, runtime, callerInfo)
126137
127- AnnotationConfigUtils . registerAnnotationConfigProcessors(beanFactory);
138+ AnnotationConfigUtils . registerAnnotationConfigProcessors(( BeanDefinitionRegistry ) beanFactory);
128139
129140 ConfigFileApplicationContextInitializer contextInitializer = new ConfigFileApplicationContextInitializer ();
130141 contextInitializer. initialize(applicationContext);
131142 }
132143
133144 @CompileDynamic
134- protected void registerGrailsAppPostProcessorBean (ConfigurableApplicationContext applicationContext , DefaultListableBeanFactory beanFactory , TestRuntime runtime , Map callerInfo ) {
145+ protected void registerGrailsAppPostProcessorBean (ConfigurableApplicationContext applicationContext , ConfigurableBeanFactory beanFactory , TestRuntime runtime , Map callerInfo ) {
135146 Closure doWithSpringClosure = {
136147 GrailsApplication grailsApplication = (GrailsApplication )runtime. getValueIfExists(" grailsApplication" )
137148
@@ -159,13 +170,14 @@ class GrailsApplicationTestPlugin implements TestPlugin {
159170 beanFactory. registerBeanDefinition(" grailsApplicationPostProcessor" , beandef);
160171 }
161172
162- protected void customizeContext (ConfigurableApplicationContext applicationContext , DefaultListableBeanFactory beanFactory , TestRuntime runtime , Map callerInfo ) {
173+ protected void customizeContext (ConfigurableApplicationContext applicationContext , ConfigurableBeanFactory beanFactory , TestRuntime runtime , Map callerInfo ) {
163174
164175 }
165176
166- protected ServletContext createServletContext (final TestRuntime runtime , final Map callerInfo ) {
167- MockServletContext servletContext = new MockServletContext ()
168- return servletContext
177+ protected Object createServletContext (final TestRuntime runtime , final Map callerInfo ) {
178+ if (isServletApiPresent) {
179+ return ClassUtils . forName(" org.springframework.mock.web.MockServletContext" ). newInstance()
180+ }
169181 }
170182
171183 protected void customizeGrailsApplication (final GrailsApplication grailsApplication , final TestRuntime runtime , final Map callerInfo ) {
@@ -273,7 +285,14 @@ class GrailsApplicationTestPlugin implements TestPlugin {
273285 ((DefaultGrailsApplication )runtime. getValue(' grailsApplication' ))?. clear()
274286 }
275287 runtime. removeValue(" loadedCodecs" )
276- ConvertersConfigurationHolder . clear()
288+ if (ClassUtils . isPresent(" org.grails.web.converters.configuration.ConvertersConfigurationHolder" , getClass(). classLoader)) {
289+ clearConvertersHolder()
290+ }
291+ }
292+
293+ @CompileDynamic
294+ void clearConvertersHolder () {
295+ ClassUtils . forName(" org.grails.web.converters.configuration.ConvertersConfigurationHolder" , getClass(). classLoader). clear()
277296 }
278297
279298 void shutdownApplicationContext (TestRuntime runtime ) {
@@ -296,8 +315,10 @@ class GrailsApplicationTestPlugin implements TestPlugin {
296315 DeferredBindingActions . clear()
297316
298317 runtime. removeValue(" grailsApplication" )
299-
300- Holders . setServletContext null
318+
319+ if (isServletApiPresent) {
320+ Holders . setServletContext null
321+ }
301322 runtime. removeValue(" servletContext" )
302323
303324 Promises . promiseFactory = null
0 commit comments