Skip to content

Commit 8c51315

Browse files
committed
Avoid potential refresh deadlock with registerShutdownHook
Closes gh-31811
1 parent e8cd26b commit 8c51315

File tree

1 file changed

+34
-11
lines changed

1 file changed

+34
-11
lines changed

spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -645,8 +645,12 @@ public void refresh() throws BeansException, IllegalStateException {
645645
* active flag as well as performing any initialization of property sources.
646646
*/
647647
protected void prepareRefresh() {
648-
// Switch to active.
649648
this.startupDate = System.currentTimeMillis();
649+
650+
// Remove shutdown hook during refresh phase.
651+
removeShutdownHook();
652+
653+
// Switch to active.
650654
this.closed.set(false);
651655
this.active.set(true);
652656

@@ -966,6 +970,9 @@ protected void finishRefresh() {
966970

967971
// Publish the final event.
968972
publishEvent(new ContextRefreshedEvent(this));
973+
974+
// Restore shutdown hook if registered before.
975+
restoreShutdownHook();
969976
}
970977

971978
/**
@@ -1024,6 +1031,28 @@ public void run() {
10241031
}
10251032
}
10261033

1034+
private void removeShutdownHook() {
1035+
if (this.shutdownHook != null) {
1036+
try {
1037+
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
1038+
}
1039+
catch (IllegalStateException ex) {
1040+
// ignore - VM is already shutting down
1041+
}
1042+
}
1043+
}
1044+
1045+
private void restoreShutdownHook() {
1046+
if (this.shutdownHook != null) {
1047+
try {
1048+
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
1049+
}
1050+
catch (IllegalStateException | IllegalArgumentException ex) {
1051+
// ignore - VM is already shutting down or hook already registered
1052+
}
1053+
}
1054+
}
1055+
10271056
/**
10281057
* Close this application context, destroying all beans in its bean factory.
10291058
* <p>Delegates to {@code doClose()} for the actual closing procedure.
@@ -1034,17 +1063,11 @@ public void run() {
10341063
@Override
10351064
public void close() {
10361065
synchronized (this.startupShutdownMonitor) {
1037-
doClose();
10381066
// If we registered a JVM shutdown hook, we don't need it anymore now:
1039-
// We've already explicitly closed the context.
1040-
if (this.shutdownHook != null) {
1041-
try {
1042-
Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
1043-
}
1044-
catch (IllegalStateException ex) {
1045-
// ignore - VM is already shutting down
1046-
}
1047-
}
1067+
// We're already explicitly closing the context.
1068+
removeShutdownHook();
1069+
1070+
doClose();
10481071
}
10491072
}
10501073

0 commit comments

Comments
 (0)