Giter Site home page Giter Site logo

Comments (3)

WillHolbrook avatar WillHolbrook commented on July 1, 2024

Part of this behavior comes from the method inferDestroyMethodIfNecessary() in the class org/springframework/beans/factory/support/DisposableBeanAdapter.java

from spring-boot.

wilkinsona avatar wilkinsona commented on July 1, 2024

Spring Boot 2.7.x is no longer supported. Please upgrade to Spring Boot 3.2.x or later as soon as possible.

I've upgrade the sample to 3.2.x and the problem still occurs. Unfortunately, I don't think there's anything that we can do about it in Spring Boot or Spring Framework as the locks that are involved are out of our control. When running with 2.7.x, they are:

"AWT-EventQueue-0" #30 prio=6 os_prio=31 cpu=295.87ms elapsed=12.08s tid=0x00007f815f15c400 nid=0x12407 in Object.wait()  [0x0000700011d85000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x000000061dcd9410> (a java.lang.Thread)
	at java.lang.Thread.join([email protected]/Thread.java:1313)
	- locked <0x000000061dcd9410> (a java.lang.Thread)
	at java.lang.Thread.join([email protected]/Thread.java:1381)
	at java.lang.ApplicationShutdownHooks.runHooks([email protected]/ApplicationShutdownHooks.java:107)
	at java.lang.ApplicationShutdownHooks$1.run([email protected]/ApplicationShutdownHooks.java:46)
	at java.lang.Shutdown.runHooks([email protected]/Shutdown.java:130)
	at java.lang.Shutdown.exit([email protected]/Shutdown.java:173)
	- locked <0x00000007ffb020b8> (a java.lang.Class for java.lang.Shutdown)
	at java.lang.Runtime.exit([email protected]/Runtime.java:115)
	at java.lang.System.exit([email protected]/System.java:1864)
	at org.example.SampleConfiguration$2.windowClosing(SampleConfiguration.java:29)
	at java.awt.AWTEventMulticaster.windowClosing([email protected]/AWTEventMulticaster.java:357)
	at java.awt.Window.processWindowEvent([email protected]/Window.java:2085)
	at javax.swing.JFrame.processWindowEvent([email protected]/JFrame.java:298)
	at java.awt.Window.processEvent([email protected]/Window.java:2044)
	at java.awt.Component.dispatchEventImpl([email protected]/Component.java:5001)
	at java.awt.Container.dispatchEventImpl([email protected]/Container.java:2324)
	at java.awt.Window.dispatchEventImpl([email protected]/Window.java:2780)
	at java.awt.Component.dispatchEvent([email protected]/Component.java:4833)
	at java.awt.EventQueue.dispatchEventImpl([email protected]/EventQueue.java:775)
	at java.awt.EventQueue$4.run([email protected]/EventQueue.java:720)
	at java.awt.EventQueue$4.run([email protected]/EventQueue.java:714)
	at java.security.AccessController.executePrivileged([email protected]/AccessController.java:776)
	at java.security.AccessController.doPrivileged([email protected]/AccessController.java:399)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege([email protected]/ProtectionDomain.java:86)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege([email protected]/ProtectionDomain.java:97)
	at java.awt.EventQueue$5.run([email protected]/EventQueue.java:747)
	at java.awt.EventQueue$5.run([email protected]/EventQueue.java:745)
	at java.security.AccessController.executePrivileged([email protected]/AccessController.java:776)
	at java.security.AccessController.doPrivileged([email protected]/AccessController.java:399)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege([email protected]/ProtectionDomain.java:86)
	at java.awt.EventQueue.dispatchEvent([email protected]/EventQueue.java:744)
	at java.awt.EventDispatchThread.pumpOneEventForFilters([email protected]/EventDispatchThread.java:203)
	at java.awt.EventDispatchThread.pumpEventsForFilter([email protected]/EventDispatchThread.java:124)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy([email protected]/EventDispatchThread.java:113)
	at java.awt.EventDispatchThread.pumpEvents([email protected]/EventDispatchThread.java:109)
	at java.awt.EventDispatchThread.pumpEvents([email protected]/EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.run([email protected]/EventDispatchThread.java:90)
"SpringApplicationShutdownHook" #24 prio=5 os_prio=31 cpu=3.04ms elapsed=10.32s tid=0x00007f815f9c8800 nid=0x1e75f waiting for monitor entry  [0x0000700011e88000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.lang.Shutdown.exit([email protected]/Shutdown.java:172)
	- waiting to lock <0x00000007ffb020b8> (a java.lang.Class for java.lang.Shutdown)
	at java.lang.Runtime.exit([email protected]/Runtime.java:115)
	at java.lang.System.exit([email protected]/System.java:1864)
	at org.example.SampleConfiguration$2.windowClosing(SampleConfiguration.java:29)
	at java.awt.AWTEventMulticaster.windowClosing([email protected]/AWTEventMulticaster.java:357)
	at java.awt.Window.processWindowEvent([email protected]/Window.java:2085)
	at javax.swing.JFrame.processWindowEvent([email protected]/JFrame.java:298)
	at java.awt.Window.processEvent([email protected]/Window.java:2044)
	at org.example.SampleConfiguration$1.close(SampleConfiguration.java:19)
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0([email protected]/Native Method)
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke([email protected]/NativeMethodAccessorImpl.java:77)
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke([email protected]/DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke([email protected]/Method.java:568)
	at org.springframework.beans.factory.support.DisposableBeanAdapter.invokeCustomDestroyMethod(DisposableBeanAdapter.java:325)
	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:259)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:587)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:559)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:1163)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:520)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:1156)
	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1120)
	at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1086)
	at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:1032)
	- locked <0x0000000600228dc0> (a java.lang.Object)
	at org.springframework.boot.SpringApplicationShutdownHook.closeAndWait(SpringApplicationShutdownHook.java:145)
	at org.springframework.boot.SpringApplicationShutdownHook$$Lambda$461/0x000000013c258ab0.accept(Unknown Source)
	at java.lang.Iterable.forEach([email protected]/Iterable.java:75)
	at org.springframework.boot.SpringApplicationShutdownHook.run(SpringApplicationShutdownHook.java:114)
	at java.lang.Thread.run([email protected]/Thread.java:840)

The picture's similar with 3.2.x.

In AWT-EventQueue-0, Runtime.exit has locked 0x00000007ffb020b8 and is then waiting for all shutdown hook threads to have completed. In SpringApplicationShutdownHook, a shutdown hook thread, Runtime.exit is waiting to lock 0x00000007ffb020b8. It will never be able to do so as it's a shutdown hook thread and the lock won't be freed until all shutdown hook threads have been completed.

The shutdown hook thread is calling Runtime.exit as it's closing the application context. mainFrame is exposed as a bean so its close() method is called as part of closing the application context. It then calls System.exit despite exit processing already being underway. There's then a deadlock in the JVM as the two threads compete with each other.

In addition to the workaround that you have already described, two further alternatives are:

  • Configure your SpringApplication not to register its shutdown hook (app.setRegisterShutdownHook(false)). You'd then probably want to close the context when the application's main window is closed
  • Configure your mainFrame bean so that its close() method isn't used as a destroy method: @Bean(destroyMethod="")

from spring-boot.

WillHolbrook avatar WillHolbrook commented on July 1, 2024

@wilkinsona Thank you I really appreciate the feedback! I think setting the destroy method to "" is a much better solution sorry for the hassle

from spring-boot.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.