The bug
OS: Windows 10
When starting the dedicated server with GUI from command line (i.e. without --nogui
command line argument) and then using Ctrl
+ C
to stop it, it properly disconnects all players but then gets stuck.
Reproduction steps
Download JDK 16 (or newer, depending on the latest Minecraft requirements)
Download the dedicated server from https://www.minecraft.net/en-us/download/server
Start the dedicated server from command line
java -jar ./server.jar
Once the server has finished starting, press
Ctrl
+C
in the command prompt / terminal (not the Minecraft server GUI!)
:info: In case players were connected you will see that they are properly disconnected
❌ Server shutdown gets stuck, the process does not exit
Code analysis
Minecraft 1.17, Mojang names
A thread dump shows that it gets stuck trying to dispose the GUI:
"Server thread" #29 prio=5 os_prio=0 cpu=4109.38ms elapsed=34.06s tid=0x0000017a411b17b0 nid=0x1478 in Object.wait() [0x000000719880e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@16/Native Method)
- waiting on <no object reference available>
at java.lang.Object.wait(java.base@16/Object.java:320)
at java.awt.EventQueue.invokeAndWait(java.desktop@16/EventQueue.java:1362)
- locked <0x00000000ae000878> (a java.awt.EventQueue$1AWTInvocationLock)
at java.awt.Window.doDispose(java.desktop@16/Window.java:1228)
at java.awt.Window.dispose(java.desktop@16/Window.java:1165)
at aay$$Lambda$4009/0x000000080138e780.run(Unknown Source)
at aay$$Lambda$4571/0x00000008015dcac8.accept(Unknown Source)
at java.util.ArrayList.forEach(java.base@16/ArrayList.java:1511)
at aay.f(SourceFile:157)
at aay.b(SourceFile:152)
at aas.f(SourceFile:320)
at net.minecraft.server.MinecraftServer.x(SourceFile:733)
at net.minecraft.server.MinecraftServer.a(SourceFile:274)
at net.minecraft.server.MinecraftServer$$Lambda$3902/0x0000000801381d08.run(Unknown Source)
at java.lang.Thread.run(java.base@16/Thread.java:831)
The reason for this might be that net.minecraft.server.gui.MinecraftServerGui.runFinalizers()
is not run from the AWT event dispatch thread. close()
which calls it should probably wrap the call to it inside javax.swing.SwingUtilities.invokeAndWait(Runnable)
.
The same also applies to net.minecraft.server.gui.MinecraftServerGui.showFrameFor(DedicatedServer)
which should create the GUI from the AWT event dispatch thread.
And for what it's worth net.minecraft.server.gui.StatsComponent
should probably not access any MinecraftServer
fields without synchronization either since there is no guarantee that it sees up to date values (since its tick()
method runs on the AWT event dispatch thread).
And net.minecraft.server.gui.PlayerListComponent.tick()
should call setListData
from the AWT event dispatch thread (use invokeLater
here).
The call to createCommandSourceStack()
from the command text field action listener might not be thread-safe either.
Linked issues
relates to 1
Comments 3
@@unknown, on macOS it might be Command
+ .
(see this superuser answer), and to make sure we are on the same page, you have to use it from the command line / terminal and not in the Minecraft server GUI.
Cannot reproduce although I was using macOS.