Skip to content

Commit 1f3d52b

Browse files
committed
fix(jakarta): rewrite websocket example to use Jakarta WebSocket API
Replace Jetty-specific JettyWebSocketServlet with standard Jakarta WebSocket @serverendpoint API. This removes the dependency on Jetty EE10 websocket server classes. - Replace WebSocketExample (Jetty annotations) with WebSocketExampleEndpoint (Jakarta @serverendpoint) - Replace JettyWebSocketServlet with HttpServlet that registers the endpoint via ServerContainer - Switch dependencies from Jetty websocket to Jakarta WebSocket API - Test remains @ignore as Pax Web 11.1.0 OSGi HTTP Whiteboard does not support WebSocket endpoint registration via ServerContainer
1 parent 70685bb commit 1f3d52b

4 files changed

Lines changed: 51 additions & 53 deletions

File tree

examples/karaf-websocket-example/pom.xml

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,21 @@
3434

3535
<dependencies>
3636
<dependency>
37-
<groupId>org.eclipse.jetty.ee10.websocket</groupId>
38-
<artifactId>jetty-ee10-websocket-jetty-server</artifactId>
39-
<version>${jetty.version}</version>
37+
<groupId>${servlet.spec.groupId}</groupId>
38+
<artifactId>${servlet.spec.artifactId}</artifactId>
39+
<version>${servlet.spec.version}</version>
4040
<scope>provided</scope>
4141
</dependency>
4242
<dependency>
43-
<groupId>org.eclipse.jetty.websocket</groupId>
44-
<artifactId>jetty-websocket-jetty-api</artifactId>
45-
<version>${jetty.version}</version>
43+
<groupId>jakarta.websocket</groupId>
44+
<artifactId>jakarta.websocket-api</artifactId>
45+
<version>2.2.0</version>
46+
<scope>provided</scope>
47+
</dependency>
48+
<dependency>
49+
<groupId>jakarta.websocket</groupId>
50+
<artifactId>jakarta.websocket-client-api</artifactId>
51+
<version>2.2.0</version>
4652
<scope>provided</scope>
4753
</dependency>
4854
<dependency>
@@ -58,18 +64,6 @@
5864
<plugin>
5965
<groupId>org.apache.felix</groupId>
6066
<artifactId>maven-bundle-plugin</artifactId>
61-
<configuration>
62-
<instructions>
63-
<Import-Package>
64-
org.osgi.service.component,
65-
org.eclipse.jetty.ee10.websocket.server,
66-
*
67-
</Import-Package>
68-
<Private-Package>
69-
org.apache.karaf.examples.websocket
70-
</Private-Package>
71-
</instructions>
72-
</configuration>
7367
</plugin>
7468
</plugins>
7569
</build>

examples/karaf-websocket-example/src/main/java/org/apache/karaf/examples/websocket/WebSocketExample.java renamed to examples/karaf-websocket-example/src/main/java/org/apache/karaf/examples/websocket/WebSocketExampleEndpoint.java

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,30 @@
1616
*/
1717
package org.apache.karaf.examples.websocket;
1818

19-
import org.eclipse.jetty.websocket.api.Callback;
20-
import org.eclipse.jetty.websocket.api.Session;
21-
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
22-
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketOpen;
23-
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
19+
import jakarta.websocket.OnClose;
20+
import jakarta.websocket.OnOpen;
21+
import jakarta.websocket.Session;
22+
import jakarta.websocket.server.ServerEndpoint;
2423

25-
import java.time.Duration;
24+
import java.io.IOException;
2625
import java.util.Collections;
2726
import java.util.HashSet;
2827
import java.util.Set;
2928

30-
@WebSocket
31-
public class WebSocketExample {
29+
@ServerEndpoint("/example-websocket")
30+
public class WebSocketExampleEndpoint {
3231

3332
static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<>());
3433
static volatile boolean notification = false;
3534

36-
@OnWebSocketOpen
35+
@OnOpen
3736
public void onOpen(Session session) {
38-
session.setIdleTimeout(Duration.ZERO);
37+
session.setMaxIdleTimeout(0);
3938
sessions.add(session);
4039
}
4140

42-
@OnWebSocketClose
43-
public void onClose(Session session, int statusCode, String reason) {
41+
@OnClose
42+
public void onClose(Session session) {
4443
sessions.remove(session);
4544
}
4645

@@ -57,15 +56,13 @@ public void run() {
5756
try {
5857
while (notification) {
5958
for (Session session : sessions) {
60-
session.sendText("Hello World", Callback.NOOP);
59+
session.getBasicRemote().sendText("Hello World");
6160
}
6261
Thread.sleep(1000);
6362
}
64-
} catch (Exception e) {
63+
} catch (IOException | InterruptedException e) {
6564
e.printStackTrace();
6665
}
6766
}
68-
6967
}
70-
7168
}

examples/karaf-websocket-example/src/main/java/org/apache/karaf/examples/websocket/WebsocketExampleServlet.java

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,41 @@
1717
package org.apache.karaf.examples.websocket;
1818

1919
import jakarta.servlet.Servlet;
20-
import jakarta.servlet.annotation.WebServlet;
21-
import org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServlet;
22-
import org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServletFactory;
23-
import org.osgi.service.component.annotations.Activate;
20+
import jakarta.servlet.ServletException;
21+
import jakarta.servlet.http.HttpServlet;
22+
import jakarta.websocket.DeploymentException;
23+
import jakarta.websocket.server.ServerContainer;
2424
import org.osgi.service.component.annotations.Component;
2525
import org.osgi.service.component.annotations.Deactivate;
2626

2727
@Component(
2828
service = Servlet.class,
29-
property = {"osgi.http.whiteboard.servlet.pattern=/example-websocket"}
29+
property = {
30+
"osgi.http.whiteboard.servlet.pattern=/example-websocket-init",
31+
"osgi.http.whiteboard.servlet.init-order=1"
32+
}
3033
)
31-
@WebServlet(name = "Example WebSocket Servlet", urlPatterns = {"/example-websocket"})
32-
public class WebsocketExampleServlet extends JettyWebSocketServlet {
34+
public class WebsocketExampleServlet extends HttpServlet {
3335

3436
@Override
35-
protected void configure(JettyWebSocketServletFactory factory) {
36-
factory.register(WebSocketExample.class);
37-
}
38-
39-
@Activate
40-
public void activate() {
41-
WebSocketExample.notification = true;
42-
Thread notification = new Thread(new WebSocketExample.NotificationThread(WebSocketExample.sessions));
37+
public void init() throws ServletException {
38+
super.init();
39+
ServerContainer container = (ServerContainer) getServletContext()
40+
.getAttribute(ServerContainer.class.getName());
41+
if (container != null) {
42+
try {
43+
container.addEndpoint(WebSocketExampleEndpoint.class);
44+
} catch (DeploymentException e) {
45+
throw new ServletException("Failed to register WebSocket endpoint", e);
46+
}
47+
}
48+
WebSocketExampleEndpoint.notification = true;
49+
Thread notification = new Thread(new WebSocketExampleEndpoint.NotificationThread(WebSocketExampleEndpoint.sessions));
4350
notification.start();
4451
}
4552

4653
@Deactivate
4754
public void deactivate() {
48-
WebSocketExample.notification = false;
55+
WebSocketExampleEndpoint.notification = false;
4956
}
50-
5157
}

itests/test/src/test/java/org/apache/karaf/itests/examples/WebSocketExampleTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
@ExamReactorStrategy(PerClass.class)
4040
public class WebSocketExampleTest extends BaseTest {
4141

42-
@Ignore("JettyWebSocketServlet is not compatible with Pax Web 11.1.0 OSGi HTTP Whiteboard websocket upgrade handling")
42+
@Ignore("Pax Web 11.1.0 OSGi HTTP Whiteboard does not support WebSocket endpoint registration via ServerContainer")
4343
@Test(timeout = 60000)
4444
public void test() throws Exception {
4545
featureService.installFeature("http-whiteboard");
@@ -50,8 +50,9 @@ public void test() throws Exception {
5050
Bundle bundle = bundleContext.installBundle("mvn:org.apache.karaf.examples/karaf-websocket-example/" + System.getProperty("karaf.version"));
5151
bundle.start();
5252

53+
// Wait for the init servlet to register (which also registers the WebSocket endpoint)
5354
String httpList = executeCommand("web:servlet-list");
54-
while (!httpList.contains("/example-websocket")) {
55+
while (!httpList.contains("example-websocket-init")) {
5556
Thread.sleep(1000);
5657
httpList = executeCommand("web:servlet-list");
5758
}

0 commit comments

Comments
 (0)