if (this.shadowParent != null) {
Thread.currentThread().setContextClassLoader(classLoaderForThisTestClass);
super.runBare();
}
else {
ShadowingClassLoader shadowingClassLoader = (ShadowingClassLoader) classLoaderCache.get(combinationOfContextLocationsForThisTestClass);
if (shadowingClassLoader == null) {
shadowingClassLoader = (ShadowingClassLoader) createShadowingClassLoader(classLoaderForThisTestClass);
classLoaderCache.put(combinationOfContextLocationsForThisTestClass, shadowingClassLoader);
}
try {
Thread.currentThread().setContextClassLoader(shadowingClassLoader);
String[] configLocations = getConfigLocations();
// Do not strongly type, to avoid ClassCastException.
Object cachedContext = contextCache.get(combinationOfContextLocationsForThisTestClass);
if (cachedContext == null) {
// Create the LoadTimeWeaver.
Class shadowingLoadTimeWeaverClass = shadowingClassLoader.loadClass(ShadowingLoadTimeWeaver.class.getName());
Constructor constructor = shadowingLoadTimeWeaverClass.getConstructor(ClassLoader.class);
constructor.setAccessible(true);
Object ltw = constructor.newInstance(shadowingClassLoader);
// Create the BeanFactory.
Class beanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName());
Object beanFactory = BeanUtils.instantiateClass(beanFactoryClass);
// Create the BeanDefinitionReader.
Class beanDefinitionReaderClass = shadowingClassLoader.loadClass(XmlBeanDefinitionReader.class.getName());
Class beanDefinitionRegistryClass = shadowingClassLoader.loadClass(BeanDefinitionRegistry.class.getName());
Object reader = beanDefinitionReaderClass.getConstructor(beanDefinitionRegistryClass).newInstance(beanFactory);
// Load the bean definitions into the BeanFactory.
Method loadBeanDefinitions = beanDefinitionReaderClass.getMethod("loadBeanDefinitions", String[].class);
loadBeanDefinitions.invoke(reader, new Object[]{configLocations});
// Create LoadTimeWeaver-injecting BeanPostProcessor.
Class loadTimeWeaverInjectingBeanPostProcessorClass = shadowingClassLoader.loadClass(LoadTimeWeaverInjectingBeanPostProcessor.class.getName());
Class loadTimeWeaverClass = shadowingClassLoader.loadClass(LoadTimeWeaver.class.getName());
Constructor bppConstructor = loadTimeWeaverInjectingBeanPostProcessorClass.getConstructor(loadTimeWeaverClass);
bppConstructor.setAccessible(true);
Object beanPostProcessor = bppConstructor.newInstance(ltw);
// Add LoadTimeWeaver-injecting BeanPostProcessor.
Class beanPostProcessorClass = shadowingClassLoader.loadClass(BeanPostProcessor.class.getName());
Method addBeanPostProcessor = beanFactoryClass.getMethod("addBeanPostProcessor", beanPostProcessorClass);
addBeanPostProcessor.invoke(beanFactory, beanPostProcessor);
// Create the GenericApplicationContext.
Class genericApplicationContextClass = shadowingClassLoader.loadClass(GenericApplicationContext.class.getName());
Class defaultListableBeanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName());
cachedContext = genericApplicationContextClass.getConstructor(defaultListableBeanFactoryClass).newInstance(beanFactory);
// Invoke the context's "refresh" method.
genericApplicationContextClass.getMethod("refresh").invoke(cachedContext);
// Store the context reference in the cache.
contextCache.put(combinationOfContextLocationsForThisTestClass, cachedContext);
}
// create the shadowed test
Class shadowedTestClass = shadowingClassLoader.loadClass(getClass().getName());
// So long as JUnit is excluded from shadowing we
// can minimize reflective invocation here
TestCase shadowedTestCase = (TestCase) BeanUtils.instantiateClass(shadowedTestClass);
/* shadowParent = this */
Class thisShadowedClass = shadowingClassLoader.loadClass(AbstractJpaTests.class.getName());
Field shadowed = thisShadowedClass.getDeclaredField("shadowParent");
shadowed.setAccessible(true);
shadowed.set(shadowedTestCase, this);
/* AbstractSpringContextTests.addContext(Object, ApplicationContext) */
Class applicationContextClass = shadowingClassLoader.loadClass(ConfigurableApplicationContext.class.getName());
Method addContextMethod = shadowedTestClass.getMethod("addContext", Object.class, applicationContextClass);
addContextMethod.invoke(shadowedTestCase, configLocations, cachedContext);
// Invoke tests on shadowed test case
shadowedTestCase.setName(getName());