Jaco's team had a problems with making an embedded web server shut down properly. Something about the shutdown process was deadlocking, so one of their "ninja Yoda coders" rockstarred their way to a solution.
private void stopServer() {
try {
if (webServer != null) {
logger.debug("Shutdown webserver");
// This goes into a dead lock, therefore I've replaced it with
// some voodoo stuff.
logger.debug("Get listener field from web server.");
Field listenerField = WebServer.class.getDeclaredField("listener");
listenerField.setAccessible(true);
Thread listener = (Thread) listenerField.get(webServer);
listenerField.set(webServer, null);
logger.debug("Interrupt the listener thread.");
listener.interrupt();
webServer = null;
logger.debug("Shutdown webserver complete");
} else {
logger.debug("No webserver to shutdown");
}
} catch (Exception e) {
logger.error(LoggerCodes.RPC_SERVER_SHUTDOWN_FAILURE, e, LoggerUtility.parameters("class",
e.getClass().getSimpleName(), "message", e.getMessage()));
}
}
Allow me to translate the comment: "I don't know how to fix this so I did some bizarre nonsense to break things in a way that works."
So, let's trace through this Java code. It's not particularly magical, just… a collection of bad ideas.
The WebServer
class has a private field called listener
. So, we use getDeclaredField
- a reflection method- to get the associated Field
object for that private field. Once we have it, we can disable the private protections so that we can use this Field
object to peek past the private protections.
And that's what we do- we use listenerField.get(webServer)
to reach inside of the webServer
and fetch its private field. We use set
to set that private field to null. Since that listener is a thread, we can simply interrupt()
it to break its execution. That is the correct way to stop a thread in Java, which is the first correct thing this code has done.
As a helpful tip: if you find yourself solving a problem and reach for reflection, you've likely misidentified your problem. If you're using reflection to peek past private
protections, you've definitely misunderstood your problem.