Skip to content
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

CompressionPools are not shared between multiple contexts for 9.4 WebSocket #7078

Closed
lachlan-roberts opened this issue Nov 4, 2021 · 6 comments
Assignees

Comments

@lachlan-roberts
Copy link
Contributor

Target Jetty version(s)
9.4.x

Enhancement Description
There should be only one instance of InflaterPool and DeflaterPool kept on the server and shared with all contexts.

@lachlan-roberts lachlan-roberts self-assigned this Nov 4, 2021
lachlan-roberts added a commit that referenced this issue Nov 4, 2021
lachlan-roberts added a commit that referenced this issue Nov 4, 2021
lachlan-roberts added a commit that referenced this issue Nov 16, 2021
…essionPools

Issue #7078 - share inflater/deflater pools for websocket in jetty 9.4
@lachlan-roberts
Copy link
Contributor Author

Merged PR #7079.

@tresf
Copy link

tresf commented Mar 18, 2022

@lachlan-roberts

This change now appears to prevent configuration from being initialized when calling WebSocketUpgradeFilter.configure(context);, potentially causing NPE when calling something like webSocketUpgradeFilter.addMapping(...). A workaround is to use the well-deprecated configureContext(...) which will create the configuration automatically. Is this intended? It forces switching 9.4.x projects to use a deprecated API when one wasn't needed prior. From the surface, this seems like a breaking API change. I'm happy to open a dedicated bug report, but I'd rather not if it's a usage issue. 🍻

Raw error:

java.lang.NullPointerException: Cannot invoke "org.eclipse.jetty.websocket.server.NativeWebSocketConfiguration.addMapping(org.eclipse.jetty.http.pathmap.PathSpec, org.eclipse.jetty.websocket.servlet.WebSocketCreator)" because "this.configuration" is null
  at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.addMapping(WebSocketUpgradeFilter.java:157)

@joakime
Copy link
Contributor

joakime commented Mar 18, 2022

@tresf is this embedded Jetty or standalone?

If embedded, how are you initializing websocket?

It should look like this ...

ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
// various things initializing the ServletContextHandler
WebSocketUpgradeFilter.configure(servletContextHandler);

Note that you can use WebSocketUpgradeFilter and configure it when you setup the ServletContextHandler, like this ...

https://github.com/eclipse/jetty.project/blob/4a0c91c0be53805e3fcffdcdcc9587d5301863db/jetty-websocket/jetty-websocket-tests/src/test/java/org/eclipse/jetty/websocket/tests/PermessageDeflateBufferTest.java#L84-L93

This lambda configures the WebSocketUpgradeFilter during the Servlet initialization phase, which is the only valid phase to initialize and configure websocket mappings.

@lachlan-roberts
Copy link
Contributor Author

@tresf I see from your stacktrace the error is from PrintSocketServer.

It doesn't make much sense to be configuring the mappings before starting as the mappings are cleared on restart, so this change was intentional as without it other use cases are broken. I see that this change does break your usage of WebSocketUpgradeFilter.addMapping(), I think this method should probably be deprecated as well.

The preferred way to do this is with the NativeWebSocketServletContainerInitializer like Joakim said. Your websocket setup code in PrintSocketServer should now become this:

// Handle WebSocket connections
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configure(context);
NativeWebSocketServletContainerInitializer.configure(context, (context, container) ->
{
    container.addMapping(new ServletPathSpec("/"), (req, resp) -> new PrintSocketClient(server));
    container.getPolicy().setMaxTextMessageSize(MAX_MESSAGE_SIZE);
});

I think you would have same logic as before by using the deprecated configureContext(...) method, but this is not recommended and is not supported in newer versions of Jetty (10+).

@tresf
Copy link

tresf commented Mar 23, 2022

@lachlan-roberts, @joakime much thanks, minor changes (commented) all working now. 🍻

// Handle WebSocket connections
WebSocketUpgradeFilter.configure(context); // NOTE: return object no longer required
NativeWebSocketServletContainerInitializer.configure(context, (ctx, container) -> { // NOTE: context is already declared
   container.addMapping(new ServletPathSpec("/"), (req, resp) -> new PrintSocketClient(server));
   container.getPolicy().setMaxTextMessageSize(MAX_MESSAGE_SIZE);
});

tresf added a commit to qzind/tray that referenced this issue Mar 23, 2022
jetty/jetty.project#7078 caused a regression in the way WebSocketUpgradeFilters could be applied.  This change was intentional, using API as instructed by Jetty team. :)
@joakime
Copy link
Contributor

joakime commented Mar 23, 2022

I went ahead and opened Issue #7771 about this, and updated the javadoc in PR #7772 to clarify this behavior in javadoc a bit more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants