New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue #5832 - shutdown Javax WSClientContainer with webapp if possible. #5840
Issue #5832 - shutdown Javax WSClientContainer with webapp if possible. #5840
Conversation
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
...in/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java
Show resolved
Hide resolved
...ain/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientContainerProvider.java
Outdated
Show resolved
Hide resolved
...in/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java
Show resolved
Hide resolved
...in/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java
Outdated
Show resolved
Hide resolved
...et-javax-tests/src/test/java/org/eclipse/jetty/websocket/javax/tests/ClientInWebappTest.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
...in/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java
Outdated
Show resolved
Hide resolved
...in/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java
Show resolved
Hide resolved
So here is a better idea based on the javax approach that might also work on tomcat deployments:
My only concern is the static and how to make that not be nasty if we run embedded or with the jar from the server classpath ??? But I'm sure you'll work it out :) |
@gregw This would require a dependency on javax.servlet for the And I'm not sure how this would work with multiple webapps using websocket client containers. We couldn't just use a simple static because we would have multiple instances of the |
@lachlan-roberts it can be a provided or optional dependency. If you don't run in a servlet container, then nothing will find the SCI and nothing will load the classes that have the dependency. Multiple webapps are not a problem, as you have multiple classloaders and thus multiple statics.... unless it is loaded from the system classloader. So maybe a static map of ServletContext to client container.. which would often only have a single entry... unless something strange is in the classloading hierarchy. Note that this is worse than an exception when stopping the maven plugin. Currently I think we are leaking an entire classloader of the webapp over stop/start cycles because the started threads will hold them in memory. So we have to fix this. |
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
…utility Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
@lachlan-roberts is this ready for re-review yet? |
@gregw yes its ready for review. |
jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
Outdated
Show resolved
Hide resolved
jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
Outdated
Show resolved
Hide resolved
...ent/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientShutdown.java
Outdated
Show resolved
Hide resolved
...ent/src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketClientShutdown.java
Outdated
Show resolved
Hide resolved
...in/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java
Outdated
Show resolved
Hide resolved
...in/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java
Outdated
Show resolved
Hide resolved
...g/eclipse/jetty/websocket/javax/server/config/JavaxWebSocketServletContainerInitializer.java
Outdated
Show resolved
Hide resolved
...ava/org/eclipse/jetty/websocket/server/config/JettyWebSocketServletContainerInitializer.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
…5832-WebSocketShutdownThread
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to take a look at the use-case for the ServletContextHandler.addServletContainerInitializer methods, and consider the wider picture of how this works with those that are discovered by the AnnotationConfiguration: we should be aiming for more code reuse rather than 2 separate mechanisms.
jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletContextHandler.java
Outdated
Show resolved
Hide resolved
.../src/main/java/org/eclipse/jetty/websocket/javax/client/JavaxWebSocketShutdownContainer.java
Show resolved
Hide resolved
...g/eclipse/jetty/websocket/javax/server/config/JavaxWebSocketServletContainerInitializer.java
Show resolved
Hide resolved
...ava/org/eclipse/jetty/websocket/server/config/JettyWebSocketServletContainerInitializer.java
Show resolved
Hide resolved
...in/java/org/eclipse/jetty/websocket/javax/client/internal/JavaxWebSocketClientContainer.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
LOG.debug("contextDestroyed({}) {}", sce, this); | ||
|
||
LifeCycle.stop(this); | ||
removeBeans(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that you have implemented doClientStop()
I don't think this is necessary.
@@ -95,6 +112,11 @@ public JavaxWebSocketClientContainer(WebSocketComponents components, Function<We | |||
this.frameHandlerFactory = new JavaxWebSocketClientFrameHandlerFactory(this); | |||
} | |||
|
|||
public void allowShutdownWithContextHandler(boolean allowShutdownWithContextHandler) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be a proper setter method, starting with set
and the getter should be there too, and used in the code.
server.stop(); | ||
assertThat(clientContainer.isRunning(), is(false)); | ||
assertThat(server.getContainedBeans(WebSocketContainer.class), empty()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add two tests that prove the behavior in case of multiple web applications, since we want to make sure that the static field SHUTDOWN_CONTAINER
is not overwritten by other instances.
One test should have the classes provided by the server, and one by the web applications (both).
This PR needs copyright header updates.
|
…5832-WebSocketShutdownThread Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
return; | ||
} | ||
|
||
ShutdownThread.register(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment here
@@ -52,6 +58,16 @@ | |||
@ManagedObject("JSR356 Client Container") | |||
public class JavaxWebSocketClientContainer extends JavaxWebSocketContainer implements javax.websocket.WebSocketContainer | |||
{ | |||
private static final Logger LOG = LoggerFactory.getLogger(JavaxWebSocketClientContainer.class); | |||
private static final AtomicReference<ContainerLifeCycle> SHUTDOWN_CONTAINER = new AtomicReference<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I comment here about the scope of this static with regards to server/context classloaders would be handy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps a few more comments, but I think this is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have expected to see:
context.addServletContainerInitializer(new CdiServletContainerInitializer())
Issue #5832
If
ContainerProvider.getWebSocketContainer()
is used within a webapp, we will attach its lifeCycle to theContextHandler
so that it shuts down with the webapp and not in theShutdownThread
.