Я создал сервер с сервером с развертыванием сервлетов, следуя методам в документации:
http://undertow.io/documentation/servlet/deployment.html
Теперь я пытаюсь остановить сервер и приложение в сервлете.
Вызов server.stop()
делает сервер недоступным на указанном порту, но когда я снова вызываю server.start()
, приложение сразу же доступно (если оно было остановлено, потребовалось бы некоторое время для запуска снова). Я также вижу, что память сервера не освобождается при вызове server.stop
. Я пробовал различные комбинации, включая вызов deploymentManager.undeploy()
с одинаковым эффектом.
Я искал документацию для каких-либо подсказок и подошел пустой. Интересно, есть ли у кого-нибудь какие-либо подсказки? Ниже приведен исходный код в его текущем состоянии (обратите внимание, что я не разработчик Java, поэтому будет много яркости):
package org.locee;
import io.undertow.Undertow;
import io.undertow.Undertow.Builder;
import io.undertow.Handlers;
import io.undertow.util.Headers;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.DeploymentManager;
import io.undertow.server.handlers.PathHandler;
import io.undertow.server.HttpHandler;
import static io.undertow.servlet.Servlets.defaultContainer;
import javax.servlet.ServletException;
public class LoceeUndertowServer {
private DeploymentManager deploymentManager;
private Undertow undertowServer;
private DeploymentInfo servletInfo;
private int port;
private String host;
public LoceeUndertowServer( DeploymentInfo servletInfo, int port, String host ) {
this.servletInfo = servletInfo;
this.port = port;
this.host = host;
}
public void start() throws ServletException {
deploymentManager = defaultContainer().addDeployment( servletInfo );
deploymentManager.deploy();
HttpHandler httpHandler = deploymentManager.start();
PathHandler pathHandler = Handlers.path( Handlers.redirect( "/" ) ).addPrefixPath( "/", httpHandler );
Builder builder = Undertow.builder();
builder.addHttpListener( port, host );
builder.setHandler( pathHandler );
undertowServer = builder.build();
undertowServer.start();
}
public void shutdown() throws ServletException {
deploymentManager.undeploy();
defaultContainer().removeDeployment( servletInfo );
undertowServer.stop();
}
public void restart() throws ServletException {
shutdown();
start();
}
}
Вы сохраняете то, что известно как сильная ссылка на компоненты Undertow и все, что они также непосредственно ссылаются. Ссылки хранятся в следующих полях:
private DeploymentManager deploymentManager;
private Undertow undertowServer;
private DeploymentInfo servletInfo;
Это меньше относится к Undertow и тому, как работает JVM. Сборщик мусора начинается с множества корней (думайте об этом как о потоках на JVM) и просматривает все ссылки на другие объекты. Как только он завершит обход, все недоступные объекты будут восстановлены. Это логический взгляд на весь процесс. Время сбора данных зависит от JVM, а также от поколений. Следующий код удалит ссылки на компоненты, если вы поместите их в метод #shutdown():
deploymentManager = null;
undertowServer = null;
servletInfo = null;
Примечание: после этого вы не сможете перезагрузить компьютер.
PathHandler path = Handlers.path()
.addPrefixPath("/quitQuit", new QuitHandler());
Undertow.Builder builder = Undertow.builder()
.setHandler(path)
.addHttpListener(8090, "0.0.0.0");
...
public class QuitHandler implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange hse) throws Exception {
// some log info...
System.exit(0);
}
}