It’s not really Play managing the hot reloading but rather the Play SBT plugin.

A Play application’s main method is in play.core.server.NettyServer. The method receives a reloader of type SBTLink and each time a request hits the server, the application delegates the task of checking if there have been any code changes to the reloader.

If there has been a code change then the existing classloader is removed and replaced with a new one which includes the updated bytecode. The application is restarted but, of course, the JVM is not.

Play is not designed to provision dynamic swapping of Jars at runtime. For this, you would need to look at things like OSGi (which I would not personally recommend after a few years of working with it).