I'm using Spring Security 5.7.3 The StackOverFlowError occurs with both two conditions: - Register an AuthenticationManager bean in SecurityConfig - Run the JUnit5 test

The stacktrace of StackOverFlowError is:

"main@1" prio=5 tid=0x1 nid=NA runnable
      StackOverFlowError
      ...
      at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
      at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
      at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
      at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
      at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
      at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:62)
      at ch.qos.logback.classic.spi.LoggingEvent.<init>(LoggingEvent.java:119)
      at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:419)
      at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
      at ch.qos.logback.classic.Logger.log(Logger.java:765)
      at org.apache.commons.logging.LogAdapter$Slf4jLocationAwareLog.warn(LogAdapter.java:447)
      at org.springframework.test.context.TestContextManager.logException(TestContextManager.java:550)
      at org.springframework.test.context.TestContextManager.handleBeforeException(TestContextManager.java:532)
      at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:296)
      at org.springframework.test.context.junit.jupiter.SpringExtension.beforeEach(SpringExtension.java:174)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$2(TestMethodTestDescriptor.java:163)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$951/0x0000000800ff54e0.invoke(Unknown Source:-1)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$6(TestMethodTestDescriptor.java:199)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$952/0x0000000800ff56f8.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:199)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachCallbacks(TestMethodTestDescriptor.java:162)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:129)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$260/0x0000000800c99578.accept(Unknown Source:-1)
      at java.util.ArrayList.forEach(ArrayList.java:1511)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$260/0x0000000800c99578.accept(Unknown Source:-1)
      at java.util.ArrayList.forEach(ArrayList.java:1511)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator$$Lambda$202/0x0000000800c86f60.accept(Unknown Source:-1)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
      at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
      at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
      at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
      at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
      at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
      at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

Obviously, the error occurs when catching the exception, which is

java.lang.IllegalStateException: Failed to unwrap proxied object

whose stacktrace is:

"main@1" prio=5 tid=0x1 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at org.springframework.test.util.AopTestUtils.getUltimateTargetObject(AopTestUtils.java:97)
      at org.springframework.boot.test.mock.mockito.SpringBootMockResolver.resolve(SpringBootMockResolver.java:35)
      at org.mockito.internal.util.MockUtil.resolve(MockUtil.java:118)
      at org.mockito.internal.util.MockUtil.isMock(MockUtil.java:108)
      at org.mockito.internal.util.DefaultMockingDetails.isMock(DefaultMockingDetails.java:32)
      at org.springframework.boot.test.mock.mockito.MockReset.get(MockReset.java:106)
      at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:82)
      at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.resetMocks(ResetMocksTestExecutionListener.java:70)
      at org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener.beforeTestMethod(ResetMocksTestExecutionListener.java:57)
      at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:293)
      at org.springframework.test.context.junit.jupiter.SpringExtension.beforeEach(SpringExtension.java:174)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachCallbacks$2(TestMethodTestDescriptor.java:163)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$951/0x0000000800ff54e0.invoke(Unknown Source:-1)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$6(TestMethodTestDescriptor.java:199)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$952/0x0000000800ff56f8.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:199)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachCallbacks(TestMethodTestDescriptor.java:162)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:129)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$260/0x0000000800c99578.accept(Unknown Source:-1)
      at java.util.ArrayList.forEach(ArrayList.java:1511)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$260/0x0000000800c99578.accept(Unknown Source:-1)
      at java.util.ArrayList.forEach(ArrayList.java:1511)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$256/0x0000000800c98a88.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$255/0x0000000800c98868.invoke(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/0x0000000800c98450.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator$$Lambda$202/0x0000000800c86f60.accept(Unknown Source:-1)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
      at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
      at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
      at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
      at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
      at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
      at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
      at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

The minimum project to cause the bug is here: https://github.com/QuanQuan-CHO/Spring-Security-StackOverFlowError-Example A very similar question is here: https://stackoverflow.com/questions/67546793/why-is-spring-boot-2-4-5-with-junit5-and-mocked-beans-is-throwing-stackoverflowe

Comment From: sjohnr

Thanks for reaching out, @QuanQuan-CHO!

In your minimal sample, I see an @Bean definition for AuthenticationManager that uses an autowired AuthenticationConfiguration.

I believe I've seen a suggestion similar to this on stackoverflow. What's happening in this case is that a bean cycle is formed between the local AuthenticationManagerBuilder and the parent AuthenticationManager configured by Spring Security. It appears to work because the application runs and can be used, but the cycle is still there as demonstrated by the test.

Generally, I don't think I'd recommend getting an AuthenticationManager in this way, as I believe you will only be able to authenticate using the global configuration (with @Bean UserDetailsService and @Bean PasswordEncoder, etc.) which may not be what you want. However, if this is sufficient for your use case, you can add static to the @Bean method to remove the bean cycle, because the order in which things are built will change and your bean will be declared first. (It looks like this is also what was suggested on the stackoverflow question you mentioned.)

@Configuration
@EnableWebSecurity
public class SecurityConfig{
    @Bean
    public static AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
}

I'm going to close this issue for now, as the sample configuration causes a bean cycle. If you feel I've missed anything, let me know and we can re-open if necessary.