Re: [jetty-users] Handle websocket upgrade request from inside Servlet#service (Jetty 12)
> org.eclipse.jetty.websocket.api.exceptions.InvalidWebSocketException: Cannot replace previously assigned [TEXT Handler] at MethodHandle(ObjectSocketAdapter,String,boolean)void with public void nl.idfix.scriptlet.scripts.handlers.ScriptHandler$ObjectSocketAdapter.onWebSocketText(java.lang.String) This is a totally different issue that has nothing to do with socketContainer.upgrade or Servlet.service. This stacktrace means you have a WebSocket that starts out with a handler for TEXT messages, then you attempt to swap to a different TEXT handler using the nl.idfix.scriptlet.scripts.handlers.ScriptHandler$ObjectSocketAdapter.onWebSocketText(java.lang.String) class. With just this 1 stacktrace it's hard to tell when this occurs. But the changed TEXT handler is likely happening after you have registered the websocket (or websocket creator). If you feel this is a bug in Jetty, then please provide a link to a github project that can replicate this issue. Joakim Erdfelt / joa...@webtide.com On Thu, Oct 19, 2023 at 6:27 AM Silvio Bierman wrote: > Thanks Joakim for the response. > > Very interesting, this is about the exact same code I was using in Jetty11 > and which I got to compile with Jetty12 by just changing some imports and > the type for the endpoint. > > But then I am back with some issues I had earlier on. I was assuming this > was because I was using some deprecated stuff and had to convert to the > code in the documentation examples. > > The first issue is that the call to > socketContainer.upgrade(socketCreator,request,response) > > logs a > > 2023-10-19 13:03:04.628:WARN :oeju.Blocker:qtp1582071873-35: > Blocking.Callback incomplete > > for every request that is not an upgrade request. The second problem is > that when the upgrade request does come in and the endpoint object (which > now extends Session.Listener) the next exception occurs: > > org.eclipse.jetty.websocket.api.exceptions.InvalidWebSocketException: > Cannot replace previously assigned [TEXT Handler] at > MethodHandle(ObjectSocketAdapter,String,boolean)void with public void > nl.idfix.scriptlet.scripts.handlers.ScriptHandler$ObjectSocketAdapter.onWebSocketText(java.lang.String) > at > org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerMetadata.assertNotSet(JettyWebSocketFrameHandlerMetadata.java:159) > JettyWebSocketFrameHandlerMetadata.java:159 > at > org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerMetadata.setTextHandle(JettyWebSocketFrameHandlerMetadata.java:131) > JettyWebSocketFrameHandlerMetadata.java:131 > at > org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory.createListenerMetadata(JettyWebSocketFrameHandlerFactory.java:213) > JettyWebSocketFrameHandlerFactory.java:213 > at > org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory.createMetadata(JettyWebSocketFrameHandlerFactory.java:129) > JettyWebSocketFrameHandlerFactory.java:129 > at > org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory.getMetadata(JettyWebSocketFrameHandlerFactory.java:119) > JettyWebSocketFrameHandlerFactory.java:119 > at > org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory.newJettyFrameHandler(JettyWebSocketFrameHandlerFactory.java:140) > JettyWebSocketFrameHandlerFactory.java:140 > at > org.eclipse.jetty.ee10.websocket.server.internal.JettyServerFrameHandlerFactory.newFrameHandler(JettyServerFrameHandlerFactory.java:42) > JettyServerFrameHandlerFactory.java:42 > at > org.eclipse.jetty.websocket.core.server.internal.CreatorNegotiator.negotiate(CreatorNegotiator.java:68) > CreatorNegotiator.java:68 > at > org.eclipse.jetty.websocket.core.server.internal.AbstractHandshaker.upgradeRequest(AbstractHandshaker.java:70) > AbstractHandshaker.java:70 > at > org.eclipse.jetty.websocket.core.server.internal.HandshakerSelector.upgradeRequest(HandshakerSelector.java:46) > HandshakerSelector.java:46 > at > org.eclipse.jetty.websocket.core.server.WebSocketMappings.upgrade(WebSocketMappings.java:294) > WebSocketMappings.java:294 > at > org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServerContainer.upgrade(JettyWebSocketServerContainer.java:228) > JettyWebSocketServerContainer.java:228 > > Earlier on I posted this and you then asked me > > ** > Does your `_socketCreator = new SocketCreator` return an Endpoint 100% of > the time? > ** > > and the answer to that is yes. > > The class extending JettySocketCreator implements createWebSocket by > passing the underlying jettyServerUpgradeRequest.httpServletRequest to > application level code which then is expected to return an EndPoint. In > this case this application level code does return an object that implements > Session.Listener just before the exception occurs. > > Thanks very much for all the help. > > Cheers, > > Silvio > > > > On 16-10-2023 17:19, Joakim Erdfelt wrote: > > Also, for Jetty WebSocket API on EE10 take a look at this test class
Re: [jetty-users] Handle websocket upgrade request from inside Servlet#service (Jetty 12)
Thanks Joakim for the response. Very interesting, this is about the exact same code I was using in Jetty11 and which I got to compile with Jetty12 by just changing some imports and the type for the endpoint. But then I am back with some issues I had earlier on. I was assuming this was because I was using some deprecated stuff and had to convert to the code in the documentation examples. The first issue is that the call to socketContainer.upgrade(socketCreator,request,response) logs a 2023-10-19 13:03:04.628:WARN :oeju.Blocker:qtp1582071873-35: Blocking.Callback incomplete for every request that is not an upgrade request. The second problem is that when the upgrade request does come in and the endpoint object (which now extends Session.Listener) the next exception occurs: org.eclipse.jetty.websocket.api.exceptions.InvalidWebSocketException: Cannot replace previously assigned [TEXT Handler] at MethodHandle(ObjectSocketAdapter,String,boolean)void with public void nl.idfix.scriptlet.scripts.handlers.ScriptHandler$ObjectSocketAdapter.onWebSocketText(java.lang.String) at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerMetadata.assertNotSet(JettyWebSocketFrameHandlerMetadata.java:159) JettyWebSocketFrameHandlerMetadata.java:159 at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerMetadata.setTextHandle(JettyWebSocketFrameHandlerMetadata.java:131) JettyWebSocketFrameHandlerMetadata.java:131 at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory.createListenerMetadata(JettyWebSocketFrameHandlerFactory.java:213) JettyWebSocketFrameHandlerFactory.java:213 at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory.createMetadata(JettyWebSocketFrameHandlerFactory.java:129) JettyWebSocketFrameHandlerFactory.java:129 at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory.getMetadata(JettyWebSocketFrameHandlerFactory.java:119) JettyWebSocketFrameHandlerFactory.java:119 at org.eclipse.jetty.websocket.common.JettyWebSocketFrameHandlerFactory.newJettyFrameHandler(JettyWebSocketFrameHandlerFactory.java:140) JettyWebSocketFrameHandlerFactory.java:140 at org.eclipse.jetty.ee10.websocket.server.internal.JettyServerFrameHandlerFactory.newFrameHandler(JettyServerFrameHandlerFactory.java:42) JettyServerFrameHandlerFactory.java:42 at org.eclipse.jetty.websocket.core.server.internal.CreatorNegotiator.negotiate(CreatorNegotiator.java:68) CreatorNegotiator.java:68 at org.eclipse.jetty.websocket.core.server.internal.AbstractHandshaker.upgradeRequest(AbstractHandshaker.java:70) AbstractHandshaker.java:70 at org.eclipse.jetty.websocket.core.server.internal.HandshakerSelector.upgradeRequest(HandshakerSelector.java:46) HandshakerSelector.java:46 at org.eclipse.jetty.websocket.core.server.WebSocketMappings.upgrade(WebSocketMappings.java:294) WebSocketMappings.java:294 at org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServerContainer.upgrade(JettyWebSocketServerContainer.java:228) JettyWebSocketServerContainer.java:228 Earlier on I posted this and you then asked me ** Does your `_socketCreator = new SocketCreator` return an Endpoint 100% of the time? ** and the answer to that is yes. The class extending JettySocketCreator implements createWebSocket by passing the underlying jettyServerUpgradeRequest.httpServletRequest to application level code which then is expected to return an EndPoint. In this case this application level code does return an object that implements Session.Listener just before the exception occurs. Thanks very much for all the help. Cheers, Silvio On 16-10-2023 17:19, Joakim Erdfelt wrote: Also, for Jetty WebSocket API on EE10 take a look at this test class for inspiration. https://github.com/jetty/jetty.project/blob/jetty-12.0.x/jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/ProgrammaticWebSocketUpgradeTest.java Joakim Erdfelt / joa...@webtide.com On Mon, Oct 16, 2023 at 10:01 AM Silvio Bierman via jetty-users wrote: Hallo all, I am porting an existing embedded Jetty application from Jetty11 to Jetty12. Since 12.0.2 everything seems to be working perfectly except for one thing I have not yet been able to port: our applications usage of the Jetty WebSocket API. The Jetty12 WebSocket API documentation shows the upgrade being done inside the Handler#handle method using the org.eclipse.jetty.server.Request / org.eclipse.jetty.server.Response objects available there. However, in our application code the information required to create the endpoint object is only known inside the Servlet instance. In the Jetty11 API we where able to upgrade the request from inside the Servlet#service method because the JettyWebSocketServerContainer#upgrade took
Re: [jetty-users] Handle websocket upgrade request from inside Servlet#service (Jetty 12)
Also, for Jetty WebSocket API on EE10 take a look at this test class for inspiration. https://github.com/jetty/jetty.project/blob/jetty-12.0.x/jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/ProgrammaticWebSocketUpgradeTest.java Joakim Erdfelt / joa...@webtide.com On Mon, Oct 16, 2023 at 10:01 AM Silvio Bierman via jetty-users < jetty-users@eclipse.org> wrote: > Hallo all, > > I am porting an existing embedded Jetty application from Jetty11 to > Jetty12. Since 12.0.2 everything seems to be working perfectly except > for one thing I have not yet been able to port: our applications usage > of the Jetty WebSocket API. > > The Jetty12 WebSocket API documentation shows the upgrade being done > inside the Handler#handle method using the > org.eclipse.jetty.server.Request / org.eclipse.jetty.server.Response > objects available there. However, in our application code the > information required to create the endpoint object is only known inside > the Servlet instance. In the Jetty11 API we where able to upgrade the > request from inside the Servlet#service method because the > JettyWebSocketServerContainer#upgrade took > HttpServletRequest/HttpServletResponse parameters. In the Jetty12 > WebSocket API ServerWebSocketContainer#upgrade these have been replaced > by above mentioned Request/Response objects. > > Is there a way around this? > > Kind regards, > > Silvio > > ___ > jetty-users mailing list > jetty-users@eclipse.org > To unsubscribe from this list, visit > https://www.eclipse.org/mailman/listinfo/jetty-users > ___ jetty-users mailing list jetty-users@eclipse.org To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/jetty-users
Re: [jetty-users] Handle websocket upgrade request from inside Servlet#service (Jetty 12)
If you are using jakarta.websocket you can use the new method ... void jakarta.websocket.server.ServerContainer.upgradeHttpToWebSocket(Object httpServletRequest, Object httpServletResponse, ServerEndpointConfig sec, Map pathParameters) throws IOException, DeploymentException If you are using the Jetty WebSocket API ... The endpoint is created with a registered org.eclipse.jetty.ee10.websocket.server.JettyWebSocketCreator. First, ask yourself what kind of information do you need from the HttpServletRequest / HttpServletResponse that requires you to go through an HttpServlet? If it can be handled via a JettyWebSocketCreator, use that. Note that you do have access to the HttpServletRequest in that class. Otherwise you'll have to implement your own custom version of the JettyWebSocketServlet. https://github.com/jetty/jetty.project/blob/jetty-12.0.x/jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/JettyWebSocketServlet.java Joakim Erdfelt / joa...@webtide.com On Mon, Oct 16, 2023 at 10:01 AM Silvio Bierman via jetty-users < jetty-users@eclipse.org> wrote: > Hallo all, > > I am porting an existing embedded Jetty application from Jetty11 to > Jetty12. Since 12.0.2 everything seems to be working perfectly except > for one thing I have not yet been able to port: our applications usage > of the Jetty WebSocket API. > > The Jetty12 WebSocket API documentation shows the upgrade being done > inside the Handler#handle method using the > org.eclipse.jetty.server.Request / org.eclipse.jetty.server.Response > objects available there. However, in our application code the > information required to create the endpoint object is only known inside > the Servlet instance. In the Jetty11 API we where able to upgrade the > request from inside the Servlet#service method because the > JettyWebSocketServerContainer#upgrade took > HttpServletRequest/HttpServletResponse parameters. In the Jetty12 > WebSocket API ServerWebSocketContainer#upgrade these have been replaced > by above mentioned Request/Response objects. > > Is there a way around this? > > Kind regards, > > Silvio > > ___ > jetty-users mailing list > jetty-users@eclipse.org > To unsubscribe from this list, visit > https://www.eclipse.org/mailman/listinfo/jetty-users > ___ jetty-users mailing list jetty-users@eclipse.org To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/jetty-users