My objective is to have a functional version of the latest Graphql-java mixed with jetty version 10.
I have done a lot of tests, using different methods, and now I am stuck with the difference of the WebSocket implementation (on Jetty) between the version 9.4 and 10.0.6.
To test the implementation I am working on the example from the graphQL repository sample.
My tests are on the subproject servlet-hello-world
, where a simple graphQL subscription is done and working on jetty 9.4
I have updated gradle to use the latest version
def jettyVersion = '9.4.43.v20210629'
dependencies {
implementation "com.graphql-java-kickstart:graphql-java-servlet:$LIB_GRAPHQL_SERVLET_VER"
implementation "io.projectreactor:reactor-core:3.4.9"
implementation 'ch.qos.logback:logback-classic:1.2.5'
implementation 'org.slf4j:slf4j-simple:2.0.0-alpha4'
implementation "org.eclipse.jetty:jetty-webapp:${jettyVersion}"
implementation "org.eclipse.jetty:jetty-annotations:${jettyVersion}"
implementation "org.eclipse.jetty.websocket:websocket-api:${jettyVersion}"
implementation "org.eclipse.jetty.websocket:websocket-server:${jettyVersion}"
implementation "org.eclipse.jetty.websocket:javax-websocket-server-impl:${jettyVersion}"
implementation "org.eclipse.jetty.websocket:websocket-common:${jettyVersion}"
}
to
def jettyVersion = '10.0.6'
dependencies {
implementation "com.graphql-java-kickstart:graphql-java-servlet:$LIB_GRAPHQL_SERVLET_VER"
implementation "io.projectreactor:reactor-core:3.4.9"
implementation 'ch.qos.logback:logback-classic:1.2.5'
implementation 'org.slf4j:slf4j-simple:2.0.0-alpha4'
// implementation "org.eclipse.jetty:jetty-webapp:${jettyVersion}"
// implementation "org.eclipse.jetty:jetty-annotations:${jettyVersion}"
implementation "org.eclipse.jetty.websocket:websocket-jetty-api:${jettyVersion}"
implementation "org.eclipse.jetty.websocket:websocket-jetty-server:${jettyVersion}"
// implementation "org.eclipse.jetty.websocket:javax-websocket-server-impl:${jettyVersion}"
// implementation "org.eclipse.jetty.websocket:websocket-common:${jettyVersion}"
}
Then I am stuck on the changes in the API where the WebSocketServletContainerInitalizer is replaced by JettyWebSocketServletContainerInitializer:
var server = new Server();
var connector = new ServerConnector(server);
connector.setPort(PORT);
server.addConnector(connector);
var context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet(HelloServlet.class, "/graphql");
server.setHandler(context);
WebSocketServerContainerInitializer.configure(
context,
(servletContext, serverContainer) ->
serverContainer.addEndpoint(
ServerEndpointConfig.Builder.create(SubscriptionEndpoint.class, "/subscriptions")
.configurator(new GraphQLWSEndpointConfigurer())
.build()));
server.setHandler(context);
server.start();
server.dump(System.err);
server.join();
}
The difference is the configurator that has changed the type of the configurator from ServletContainer
to a JettyWebSocketServerContainer
and there is no addEndpoint method anymore to connect my SubscriptionEndpoint to.
I have absolutely no clue how to connect my GraphQLWebsocketServlet
.
The old version of Jetty was websocket implementation neutral (core, javax.websocket, jetty native websocket, etc). That proved to be too complex when multiple implementations were being used at the same time.
The new Jetty 10+ implementation requires you to use the appropriate <Impl>WebSocketServletContainerInitializer
for the implementation you are using. (where <Impl>
is one of Javax
, Jakarta
, or Jetty
)
Since it looks like you are using javax.websocket
, here's the appropriate class to use.
JavaxWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) ->
{
// This lambda will be called at the appropriate place in the
// ServletContext initialization phase where you can initialize
// and configure your websocket container.
// Configure defaults for container
wsContainer.setDefaultMaxTextMessageBufferSize(65535);
// Add WebSocket endpoint to javax.websocket layer
wsContainer.addEndpoint(
ServerEndpointConfig.Builder.create(
SubscriptionEndpoint.class, "/subscriptions")
.configurator(new GraphQLWSEndpointConfigurer())
.build());
});