Issue #5832 - fix bugs when stopping the JavaxWebSocketClientContainer
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
29f185931e
commit
a60ecfa4cc
|
@ -23,9 +23,13 @@ import javax.servlet.ServletException;
|
||||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||||
import org.eclipse.jetty.util.component.LifeCycle;
|
import org.eclipse.jetty.util.component.LifeCycle;
|
||||||
import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer;
|
import org.eclipse.jetty.websocket.javax.client.internal.JavaxWebSocketClientContainer;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class JavaxWebSocketClientShutdown extends ContainerLifeCycle implements ServletContainerInitializer, ServletContextListener
|
public class JavaxWebSocketClientShutdown extends ContainerLifeCycle implements ServletContainerInitializer, ServletContextListener
|
||||||
{
|
{
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketClientShutdown.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException
|
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException
|
||||||
{
|
{
|
||||||
|
@ -36,12 +40,17 @@ public class JavaxWebSocketClientShutdown extends ContainerLifeCycle implements
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent sce)
|
public void contextInitialized(ServletContextEvent sce)
|
||||||
{
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("contextInitialized({}) {}", sce, this);
|
||||||
LifeCycle.start(this);
|
LifeCycle.start(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent sce)
|
public void contextDestroyed(ServletContextEvent sce)
|
||||||
{
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("contextDestroyed({}) {}", sce, this);
|
||||||
|
|
||||||
LifeCycle.stop(this);
|
LifeCycle.stop(this);
|
||||||
removeBeans();
|
removeBeans();
|
||||||
JavaxWebSocketClientContainer.initialize(null);
|
JavaxWebSocketClientContainer.initialize(null);
|
||||||
|
|
|
@ -64,12 +64,14 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
|
||||||
public static void initialize(ContainerLifeCycle container)
|
public static void initialize(ContainerLifeCycle container)
|
||||||
{
|
{
|
||||||
SHUTDOWN_CONTAINER.set(container);
|
SHUTDOWN_CONTAINER.set(container);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("initialized {} to {}", String.format("%s@%x", SHUTDOWN_CONTAINER.getClass().getSimpleName(), SHUTDOWN_CONTAINER.hashCode()), container);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected WebSocketCoreClient coreClient;
|
protected WebSocketCoreClient coreClient;
|
||||||
protected Function<WebSocketComponents, WebSocketCoreClient> coreClientFactory;
|
protected Function<WebSocketComponents, WebSocketCoreClient> coreClientFactory;
|
||||||
private final JavaxWebSocketClientFrameHandlerFactory frameHandlerFactory;
|
private final JavaxWebSocketClientFrameHandlerFactory frameHandlerFactory;
|
||||||
private boolean allowContextHandlerRegistration = true;
|
private boolean allowShutdownWithContextHandler = true;
|
||||||
|
|
||||||
public JavaxWebSocketClientContainer()
|
public JavaxWebSocketClientContainer()
|
||||||
{
|
{
|
||||||
|
@ -110,9 +112,9 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
|
||||||
this.frameHandlerFactory = new JavaxWebSocketClientFrameHandlerFactory(this);
|
this.frameHandlerFactory = new JavaxWebSocketClientFrameHandlerFactory(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void allowContextHandlerRegistration(boolean allowContextHandlerRegistration)
|
public void allowShutdownWithContextHandler(boolean allowShutdownWithContextHandler)
|
||||||
{
|
{
|
||||||
this.allowContextHandlerRegistration = allowContextHandlerRegistration;
|
this.allowShutdownWithContextHandler = allowShutdownWithContextHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpClient getHttpClient()
|
protected HttpClient getHttpClient()
|
||||||
|
@ -302,37 +304,51 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
|
||||||
@Override
|
@Override
|
||||||
protected void doStop() throws Exception
|
protected void doStop() throws Exception
|
||||||
{
|
{
|
||||||
doClientStop();
|
|
||||||
super.doStop();
|
super.doStop();
|
||||||
|
doClientStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doClientStart()
|
protected void doClientStart()
|
||||||
{
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("doClientStart() {}", this);
|
||||||
|
|
||||||
// If we are running in Jetty register shutdown with the ContextHandler.
|
// If we are running in Jetty register shutdown with the ContextHandler.
|
||||||
if (allowContextHandlerRegistration && addToContextHandler(this))
|
if (allowShutdownWithContextHandler && addToContextHandler())
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Shutdown registered with ContextHandler");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If we are running inside a different ServletContainer we can register with the SHUTDOWN_CONTAINER static.
|
// If we are running inside a different ServletContainer we can register with the SHUTDOWN_CONTAINER static.
|
||||||
ContainerLifeCycle shutdownContainer = SHUTDOWN_CONTAINER.get();
|
ContainerLifeCycle shutdownContainer = SHUTDOWN_CONTAINER.get();
|
||||||
if (shutdownContainer != null)
|
if (shutdownContainer != null)
|
||||||
{
|
{
|
||||||
shutdownContainer.addManaged(this);
|
shutdownContainer.addManaged(this);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Shutdown registered with ShutdownContainer {}", shutdownContainer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShutdownThread.register(this);
|
ShutdownThread.register(this);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Shutdown registered with ShutdownThread");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doClientStop()
|
protected void doClientStop()
|
||||||
{
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("doClientStop() {}", this);
|
||||||
|
|
||||||
// Remove from context handler if running in Jetty server.
|
// Remove from context handler if running in Jetty server.
|
||||||
removeFromContextHandler(this);
|
removeFromContextHandler();
|
||||||
|
|
||||||
// Remove from the Shutdown Container.
|
// Remove from the Shutdown Container.
|
||||||
ContainerLifeCycle shutdownContainer = SHUTDOWN_CONTAINER.get();
|
ContainerLifeCycle shutdownContainer = SHUTDOWN_CONTAINER.get();
|
||||||
if (shutdownContainer != null && shutdownContainer.contains(this))
|
if (shutdownContainer != null && shutdownContainer.contains(this))
|
||||||
{
|
{
|
||||||
// Un-manage first as removeBean() will stop this, but this is already in STOPPING state.
|
// Un-manage first as we don't want to call stop again while in STOPPING state.
|
||||||
shutdownContainer.unmanage(this);
|
shutdownContainer.unmanage(this);
|
||||||
shutdownContainer.removeBean(this);
|
shutdownContainer.removeBean(this);
|
||||||
}
|
}
|
||||||
|
@ -341,7 +357,7 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
|
||||||
ShutdownThread.deregister(this);
|
ShutdownThread.deregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addToContextHandler(LifeCycle lifeCycle)
|
private boolean addToContextHandler()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -356,19 +372,19 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
|
||||||
|
|
||||||
contextHandler.getClass()
|
contextHandler.getClass()
|
||||||
.getMethod("addManaged", LifeCycle.class)
|
.getMethod("addManaged", LifeCycle.class)
|
||||||
.invoke(contextHandler, lifeCycle);
|
.invoke(contextHandler, this);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Throwable throwable)
|
catch (Throwable throwable)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("error from addToContextHandler({})", lifeCycle, throwable);
|
LOG.debug("error from addToContextHandler() for {}", this, throwable);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeFromContextHandler(LifeCycle lifeCycle)
|
private void removeFromContextHandler()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -381,14 +397,19 @@ public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer imple
|
||||||
.getMethod("getContextHandler")
|
.getMethod("getContextHandler")
|
||||||
.invoke(context);
|
.invoke(context);
|
||||||
|
|
||||||
|
// Un-manage first as we don't want to call stop again while in STOPPING state.
|
||||||
|
contextHandler.getClass()
|
||||||
|
.getMethod("unmanage", Object.class)
|
||||||
|
.invoke(contextHandler, this);
|
||||||
|
|
||||||
contextHandler.getClass()
|
contextHandler.getClass()
|
||||||
.getMethod("removeBean", Object.class)
|
.getMethod("removeBean", Object.class)
|
||||||
.invoke(contextHandler, JavaxWebSocketClientContainer.this);
|
.invoke(contextHandler, this);
|
||||||
}
|
}
|
||||||
catch (Throwable throwable)
|
catch (Throwable throwable)
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("error from removeFromContextHandler({})", lifeCycle, throwable);
|
LOG.debug("error from removeFromContextHandler() for {}", this, throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class JavaxClientShutdownWithServerTest
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||||
{
|
{
|
||||||
JavaxWebSocketClientContainer clientContainer = new JavaxWebSocketClientContainer();
|
JavaxWebSocketClientContainer clientContainer = new JavaxWebSocketClientContainer();
|
||||||
clientContainer.allowContextHandlerRegistration(false);
|
clientContainer.allowShutdownWithContextHandler(false);
|
||||||
LifeCycle.start(clientContainer);
|
LifeCycle.start(clientContainer);
|
||||||
container = clientContainer;
|
container = clientContainer;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue