Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ApplicationContext fails to load in TestNG test if previous test is annotated with @DirtiesContext [SPR-12918] #17517

Closed
spring-projects-issues opened this issue Apr 15, 2015 · 30 comments

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

David Blake opened SPR-12918 and commented

Upgrading from Spring Framework 4.0.5 to 4.1.6 (or 4.1.0) causes Test class #2 to fail with the following exception if Test class #1 is annotated with @DirtiesContext at the class level (see example code in the comments section for details).

java.lang.IllegalStateException: Failed to load ApplicationContext
	at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
	at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
	at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
	at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.springTestContextPrepareTestInstance(AbstractTestNGSpringContextTests.java:145)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
	at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
	at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
	at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
	at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
	at org.testng.TestRunner.privateRun(TestRunner.java:767)
	at org.testng.TestRunner.run(TestRunner.java:617)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
	at org.testng.SuiteRunner.run(SuiteRunner.java:240)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
	at org.testng.TestNG.run(TestNG.java:1057)
	at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'schedulerContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.hp.ipg.framework.config.amqp.AmqpFrameworkConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.hp.ipg.framework.queue.RabbitMQManagementClient com.hp.ipg.framework.config.amqp.AmqpFrameworkConfig.rabbitMQManagementClient; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'rabbitMQManagementClient': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.hp.ipg.framework.HttpClientFactory com.hp.ipg.framework.client.Client.httpClient; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpClientFactoryUntrusted': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.core.env.Environment com.hp.ipg.framework.HttpClientFactory.env; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' is defined
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1566)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:125)
	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
	at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:109)
	at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:261)
	at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
	at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
	... 29 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.hp.ipg.framework.config.amqp.AmqpFrameworkConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.hp.ipg.framework.queue.RabbitMQManagementClient com.hp.ipg.framework.config.amqp.AmqpFrameworkConfig.rabbitMQManagementClient; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'rabbitMQManagementClient': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.hp.ipg.framework.HttpClientFactory com.hp.ipg.framework.client.Client.httpClient; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpClientFactoryUntrusted': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.core.env.Environment com.hp.ipg.framework.HttpClientFactory.env; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' is defined
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:523)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:512)
	at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:227)
	at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:80)
	at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:56)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.determineQualifiedTransactionManager(TransactionAspectSupport.java:377)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:361)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:271)
	at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:70)
	at com.hp.ipg.services.SchedulerService.deletePriorBuildTriggersAndJobs(SchedulerService.java:119)
	at com.hp.ipg.services.config.SchedulerContext.configureTriggerAndJobState(SchedulerContext.java:51)
	at com.hp.ipg.services.config.SchedulerContext.init(SchedulerContext.java:37)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:349)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:300)
	at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133)
	... 46 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.hp.ipg.framework.queue.RabbitMQManagementClient com.hp.ipg.framework.config.amqp.AmqpFrameworkConfig.rabbitMQManagementClient; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'rabbitMQManagementClient': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.hp.ipg.framework.HttpClientFactory com.hp.ipg.framework.client.Client.httpClient; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpClientFactoryUntrusted': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.core.env.Environment com.hp.ipg.framework.HttpClientFactory.env; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' is defined
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
	... 81 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'rabbitMQManagementClient': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.hp.ipg.framework.HttpClientFactory com.hp.ipg.framework.client.Client.httpClient; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpClientFactoryUntrusted': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.core.env.Environment com.hp.ipg.framework.HttpClientFactory.env; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' is defined
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:496)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$100(AutowiredAnnotationBeanPostProcessor.java:115)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:526)
	... 83 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.hp.ipg.framework.HttpClientFactory com.hp.ipg.framework.client.Client.httpClient; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpClientFactoryUntrusted': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.core.env.Environment com.hp.ipg.framework.HttpClientFactory.env; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' is defined
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
	... 93 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpClientFactoryUntrusted': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.core.env.Environment com.hp.ipg.framework.HttpClientFactory.env; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' is defined
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:496)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$100(AutowiredAnnotationBeanPostProcessor.java:115)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:526)
	... 95 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.core.env.Environment com.hp.ipg.framework.HttpClientFactory.env; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' is defined
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
	... 103 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' is defined
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1168)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:281)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:496)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$100(AutowiredAnnotationBeanPostProcessor.java:115)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:526)
	... 105 more

Affects: 4.1 GA

Issue Links:

  • INT-3543 Fix tests do not close ApplicationContext between test methods
  • #10800 AbstractTransactionalTestNGSpringContextTests not working as expected when an EJB with TransactionAttribute.REQUIRES_NEW is encountered
  • #15172 getBean(Object.class) fails when introspecting Environment bean
  • #15166 Do not serialize ApplicationContext creation in the TestContext framework
  • #17012 DefaultListableBeanFactory should allow efficient access to current bean names
  • #19400 No bean of type ConfigurableEnvironment in AbstractTestNGSpringContextTests
  • #17525 Autowiring against a closed ApplicationContext should consistently fail

Referenced from: commits 3c5a9b4

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

Sam Brannen commented

I'm afraid the supplied stack trace does not provide much to go on, other than the fact that you are using TestNG.

Can you please provide the details of your setup?

Are tests #1 and #2 different test classes or different test methods within the same class?

Have you tried a different version of Spring, for example 4.1.0?

Where is @DirtiesContext applied, at the method level or class level and on which method/class?

Exactly which TestExecutionListener classes are configured for your test class (and all of its parent classes)? In other words, please provide every declaration of @TestExecutionListeners in the affected test class hierarchy.

Thanks for any feedback you can provide!

Sam

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

Sam Brannen commented

In any case, without knowing the details of your configuration, it sounds like you might be closing the ApplicationContext programmatically which is not supported.

The reason I suspect this is that a NoSuchBeanDefinitionException with the message "No bean named 'environment' is defined" is thrown whenever an attempt is made to autowire an object (e.g., your test instance) using a closed ApplicationContext.

See my comments here for details.

Of course, I cannot verify this assumption without seeing your test code. So please confirm whether you are closing the context programmatically.

Thanks,

Sam

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

David Blake commented

The Test #1 and test #2 are different test classes in separate source files. Test class #1 is annotated with @DirtiesContext at the class level. I need that due to using mokito mocks in test class #1 and therefore want Test class #2 context to be regenerated.

I am not explicitly closing the ApplicationContext programmaticall, just using @DirtyContext in Test class #1.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

David Blake commented

I can try going back from 4.1.6 until I see which version the issue came in on if that is helpful. I will try the 4.1.0 you suggested first.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

Sam Brannen commented

OK. Thanks for the feedback. I'll see if I can reproduce the issue.

In the meantime, if you could answer my question above regarding TestExecutionListener configuration, I'd appreciate it.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

David Blake commented

Thanks for your assistance Sam. I will get you the requested information..

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

Sam Brannen commented

This is potentially related to #15172, #17012, and INT-3543.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

David Blake commented

I don't have any TestExecutionListener config items in the test code, but I do extend AbstractTestNGSpringContextTests which is authored by you I noticed.

AbstractTestNGSpringContextTests

@TestExecutionListeners({
    ServletTestExecutionListener.class,
    DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class})
public abstract class AbstractTestNGSpringContextTests implements IHookable, ApplicationContextAware {

HPUnitTest Class

@ContextConfiguration(classes = ServicesUnitTestConfig.class)
@ActiveProfiles("unit")
public abstract class HPUnitTest extends AbstractTestNGSpringContextTests {

Test Class #1

@DirtiesContext
@Test(groups = { "L1", "Service Tests", "Queue" })
public class AccountSummaryServiceTest extends HPUnitTest {

Test Class #2

@Test(groups = { "L1", "Service Tests" })
public class SchedulerServiceTest extends HPUnitTest {

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

Sam Brannen commented

This issue is potentially related to #10800.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

Sam Brannen commented

Out of curiosity, what happens if you configure your three test classes as follows?

HPUnitTest Class

@ContextConfiguration(classes = ServicesUnitTestConfig.class)
@ActiveProfiles("unit")
public abstract class HPUnitTest extends AbstractTestNGSpringContextTests {

Test Class #1

@DirtiesContext
@Test(suiteName = "AccountSummaryService", groups = {"L1", "Service Tests", "Queue"})
public class AccountSummaryServiceTest extends HPUnitTest {

Test Class #2

@Test(suiteName = "SchedulerService", groups = {"L1", "Service Tests"})
public class SchedulerServiceTest extends HPUnitTest {

Note the use of unique values for suiteName.

Please let me know the outcome of your tests with the above configuration.

Cheers,

Sam

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

David Blake commented

Tried the suggested changes and it failed the same way.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 15, 2015

David Blake commented

Rebuilt with 4.1.0 and it fails with a similar call stack though the 4.1.6 call stack has extra details logged so it looks like the trace logging was improved over time. Overall it is the same illegalStateException - Failed to load ApplicationContext error.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 16, 2015

Sam Brannen commented

Thanks for helping investigate.

Since those attempts failed as well, I think this issue may not be directly related to spring-test especially since there were no (or not many) changes to Spring's TestNG and @DirtiesContext support from 4.0.5 to 4.1. In any case, we will continue to investigate the cause.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 16, 2015

David Blake commented

Based on what we've seen so far with testing this, I'm curious what changes have happened in org.springframework.beans.factory between 4.0.5 and 4.1.0. I'm currently stepping through the working code with 4.0.5 to try and better understand what makes that work for my case. I'll also try going back to 4.1.0 and do the same there for the failing case. I'll post what I find if anything.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 16, 2015

David Blake commented

Here is what I'm seeing as a difference between the working 4.0.5 case and the 4.1.0 failing case.

In the stack trace in this issue's Description, notice the call to the method deletePriorBuildTriggersAndJobs(). That is ours and is annotated with @Transactional(propagation = REQUIRED). When I put a breakpoint on the method definition and step into code there is a difference for the working and non-working case.

Non-working 4.1+ case

Stepping into the call stack results in going into Spring's org.springframework.transaction package and eventually into Spring's org.springframework.beans.factory package and eventually fails.

Working 4.0.5 case

Stepping into the call stack does not go into Spring's org.springframework.transaction package but instead goes to the first line of the method deletePriorBuildTriggersAndJobs() which is ours.

Summary

It appears that 4.0.5 to 4.1+ introduces extra processing or at least different processing for @Transactional annotations that fail after a test is run with @DirtiesContext at the class level.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 17, 2015

Sam Brannen commented

Thank you for taking the time to perform additional analysis!

We will take your findings into account.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 17, 2015

Sam Brannen commented

Interim testing work has been committed in GitHub commit 3c5a9b4:

Introduce class-level @DirtiesContext tests for TestNG

Prior to this commit, ClassLevelDirtiesContextTests existed for
verifying the expected behavior of @DirtiesContext declared at the
class level in conjunction with JUnit and SpringJUnit4ClassRunner.

This commit introduces analogous tests for TestNG in the new
ClassLevelDirtiesContextTestNGTests class.

Furthermore, ContextCacheTestUtils and TrackingTestNGTestListener have
been introduced to reduce code duplication across the test suite.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 19, 2015

Sam Brannen commented

This issue is potentially related to #15166, in the sense that parallel construction of an application context results in a null Environment being autowired into an @Configuration class.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 24, 2015

David Blake commented

I see that version 4.1.7 is due around May 20th. Do we currently know if a fix for this issue will be possible by that date?

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 19, 2015

David Blake commented

Update to previous comment. Version 4.1.7 has been pushed out to mid July according to the dashboard. I am still interested in a fix for this issue and currently don't have a way to work around this. Let me know if I can help assist with anything.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 20, 2015

Juergen Hoeller commented

So with 4.0.5, it looks like your @Transactional rule on deletePriorBuildTriggersAndJobs() hasn't kicked in at all before, despite your use of the AspectJ transaction aspect. That actually seems like a bug in its own right... As of 4.1, for some reason, the transaction processing does kick in as requested. So for that part, I'd rather declare 4.0.5 at fault and 4.1 to be correct. From that perspective, does it work for you if you remove the @Transactional declaration completely?

Now, with the transaction actually kicking in there, it tries to resolve a transaction manager and apparently encounters an incompletely initialized ApplicationContext. This may happen on startup as well as on shutdown, but it's more likely to happen for access after shutdown... Is there possibly some asynchronous task involved, trying to access the context after its shutdown? Or some concurrent test runs that interfere in terms of the state of a shared ApplicationContext?

Juergen

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 20, 2015

David Blake commented

From that perspective, does it work for you if you remove the @Transactional declaration completely?

Yes, if I remove the @Transactional it works. It also works if I remove the @DirtiesContext from around Test class #1.

Is there possibly some asynchronous task involved, trying to access the context after its shutdown? Or some concurrent test runs that interfere in terms of the state of a shared ApplicationContext?

There is nothing, I know of, that our code is doing to either close the ApplicationContext or asynchronously access the context. The failure is not happening during a specific Test but instead during what appears to be the initialization of the second Test class in preparation for running the second group of Test. The first Test class has the @DirtiesContext. When it completes doesn't that annotation cause the ApplicationContext to be reset? Then when it starts the second test class processing it causes the ApplicationContext to be reloaded, I believe, even before starting to execute our tests that are part of the second class.

Does this answer your questions completely? I'd be happy to expand further.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 22, 2015

David Blake commented

Removing the reference to the bean, Environment, that is the cause of the failure to load the ApplicationContext also fixes the issue and could be a possible workaround for us if we can replace that functionality with something else.

Seems the failure of the Environment has been an issue in the past and is curiously the only bean of around 300 that get loaded in our system that is a problem currently. Just an observation.

import org.springframework.core.env.Environment; @Autowired
Environment env;

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 22, 2015

Sam Brannen commented

There is nothing, I know of, that our code is doing to either close the ApplicationContext or asynchronously access the context.

That's odd, because it really sounds like that would be the case based on the error you're encountering.

The failure is not happening during a specific Test but instead during what appears to be the initialization of the second Test class in preparation for running the second group of Test.

Again, this sounds to me like there is some overlap in the execution of the tests in terms of test execution lifecycle callbacks.

Have you tried out my unique suite name per test class proposal (see comments above) on all of your TestNG-based tests?

The first Test class has the @DirtiesContext. When it completes doesn't that annotation cause the ApplicationContext to be reset?

Yes, the corresponding ApplicationContext should be closed after such a test class has completed.

Then when it starts the second test class processing it causes the ApplicationContext to be reloaded, I believe, even before starting to execute our tests that are part of the second class.

That is correct, but still... it sounds like the ordering is not correct.

Could you please execute your tests with DEBUG logging enabled for the org.springframework.test.context logging category and supply us the output?

See my detailed comments in #10800 for the kind of problems that can occur if the TestNG test execution order is incorrectly configured.

Regards,

Sam

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 24, 2015

David Blake commented

Could you please execute your tests with DEBUG logging enabled for the org.springframework.test.context logging category and supply us the output?
Could you provide instructions or a link on how to enable DEBUG logging in springframework code? Is there a log4J property file or something for that?

Have you tried out my unique suite name per test class proposal (see comments above) on all of your TestNG-based tests?
Yes I documented that in a previous comment. Fails with the same stack trace. I have minimized the failure case down to two test classes each with 8 tests. I am going to further minimize it down to just two test classes and two test methods. Would this help with your concern about order? Anyway, less is better for failure reproduction imho.

One thing further. I can see in the spring tools UI while I'm running the tests that the first test class completes all 8 tests successfully and the call stack shows it going into testing code to initialize the context. During this the beans are reloaded, there are ~300 in my projects, and it always fails trying to lookup the Environment springframework bean which is autowired into one of our classes. The failure occurs "before" test class two methods are executed. I removed this autowired reference from our code and hardcoded the values we were getting from that just for testing and everything works fine without that.

I will 1. turn on debug when I know how. and 2. will further simplify the test run needed to show the failure.

thanks for your inputs and assistance.

David Blake

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 25, 2015

Sam Brannen commented

To enable DEBUG logging for the org.springframework.test.context category, you could create a log4j.properties (in the root of the classpath for your tests) similar to the following:

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%-5p] [%c] - %m%n

log4j.rootCategory=ERROR, console

log4j.logger.org.springframework.beans=INFO
log4j.logger.org.springframework.context=INFO
log4j.logger.org.springframework.test.context=DEBUG

If you already have log4j.properties or log4j.xml configuration in place, just adapt it accordingly.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented May 25, 2015

Sam Brannen commented

Yes I documented that in a previous comment. Fails with the same stack trace.

Yes, I recall that. ;)

This time I was asking if you declared a unique suiteName for every concrete TestNG-based test class in your application.

I have minimized the failure case down to two test classes each with 8 tests. I am going to further minimize it down to just two test classes and two test methods. Would this help with your concern about order?

YES. That would be very beneficial, especially if you can provide us a scaled down project that reproduces the issue. That way we could get our hands on something that is actually breaking and debug it ourselves.

Thanks in advance!

Sam

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jun 17, 2015

David Blake commented

Our code base was modified which resulted in the removal of the Environment bean being autowired which fixes the problem we were having. Due to the complexity of our code base I was unable to get any further minimal test to duplicate the issue.

Now that we are past this we have run into another issue that follows a similar theme in that Spring Framework 4.0.5 works with TestNG and @DirtiesContext but after updating to 4.1.6 we are getting some detached entity persisting object errors with tests that worked fine in 4.0.5 and work with 4.1.6 if I remove the @DirtiesContext annotation from around the previous test class that executed.

I will submit this as a different defect unless you want it to remain part of this one.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Nov 5, 2016

Sam Brannen commented

Please note that #19400 may be duplicate of this issue.

Loading

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Jan 12, 2019

Bulk closing outdated, unresolved issues. Please, reopen if still relevant.

Loading

@sbrannen sbrannen self-assigned this Jan 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants