WebSocket Integration

Hi devs,

While cleaning up GitHub - xwiki-contrib/xwiki-contrib-websocket: XWiki Websocket Integration in order to integrate it in platform, because it is needed by the real-time editing feature, I realized that this extension doesn’t use the standard Java API for WebSocket (JSR356). Instead it proposed a custom API implemented using Netty. Using standard APIs is always better and in this case it also means we can rely on the servlet container implementation without needing any additional library. Based on this I published a proposal at https://design.xwiki.org/xwiki/bin/view/Proposal/WebSocketIntegration and I pushed the code on two branches:

The main thing is that developers will be able to implement WebSocket end-points using the standard API (javax.websocket.*) with just one small addition: they will have to mark their end-points using the org.xwiki.websocket.EndpointComponent interface (component role with no methods).

I’d like to include this in XWiki 13.6RC1 so please share your thoughts ASAP.

Thanks,
Marius

Sounds good to me. Just for information, you said in the proposal that there is a Jakarta Websocket 2.0 standard we cannot use for now because of Java 8: this will replace in the future Java API Websocket 1.1, or it’s a brand new implem? Said otherwise would that be easy to move towards that implementation if it’s going to replace Java API Websocket in a near future, so that we’re not stuck with an old deprecated implementation?

Hi @surli, as can be seen from Jakarta WebSocket Specification the only significant change is the package rename, which is pain… In my proposal I haven’t added any abstraction layer on top of the WebSocket API (JSR356) because I think its too much work and it leads in the end to a custom WebSocket API…

So with my proposal, when you write a WebSocket end-point you are using directly the WebSocket API (JSR356) with its javax.websocket.* classes and interfaces. Moving to Jakarta WebSocket 2.0 would mean:

  • updating the pom to depend on the new API
  • updating the imported packages (javax.websocket.* to jakarta.websocket.*)
  • releasing a new version

From the point of view of XWiki Standard, we will start by supporting only JSR356, then add support for Jakarta WebSocket API and maintain both for some time (depending on the adoption by the servlet containers we support), and finally drop JSR356 and keep only Jakarta WebSocket API. This means we’ll have to duplicate some code while supporting both APIs…

Note that servlet containers won’t support both APIs at the same time. This is the current state:

  • Tomcat 9 (JSR-356 v1.1)
  • Tomcat 10 (Jakarta 2.0)
  • Jetty 9 (JSR-356 v1.0)
  • Jetty 10 (JSR-356 v1.1)
  • Jetty 11 (Jakarta 2.0)

XWiki Standard needs to work with multiple versions of Tomcat and Jetty so it needs to support / bundle both APIs, but only the one supported by the servlet container will be activated (i.e. only the WebSocket end-points that use the API supported by the servlet container will be deployed). This means that extension developers will have to maintain two versions (branches): one using JSR-356 and one using Jakarta 2.0. The administrator will have to install the extension version that works with the servlet container used.

On our side (XWiki Standard) we might be able to avoid code duplication by using the Maven Shade plugin. We basically maintain only one API (e.g. Jakarta) and we shade it to rename the pacakges:

  • xwiki-commons-websocket
    • xwiki-commons-websocket-jakarta (the one we maintain, where we keep the source code)
    • xwiki-commons-websocket-jsr356 (no source code here, just using the Maven Shade plugin to rename packages)

I experimented a bit with this and the main issue so far is that components.txt is not updated but I should be able to write a Resource Transformer.

WDYT?

Thanks,
Marius