Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.

DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.

Expand Down Expand Up @@ -157,13 +157,6 @@
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.ee9.websocket.servlet"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.websocket.server"
download-size="0"
Expand Down
120 changes: 1 addition & 119 deletions application/org.openjdk.jmc.feature.ide/feature.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.

DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.

Expand Down Expand Up @@ -105,144 +105,26 @@
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.ee9.webapp"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.security"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.server"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.alpn.client"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.ee9.websocket.servlet"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.http"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.io"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.util"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.xml"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.websocket.core.client"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.websocket.core.common"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.websocket.core.server"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.websocket.common"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.client"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.ee9.security"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.ee9.server"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.ee9.servlet"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.ee9.websocket.api"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.ee9.websocket.common"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

<plugin
id="org.eclipse.jetty.ee9.websocket.server"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

</feature>
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,7 @@ Require-Bundle: org.openjdk.jmc.rjmx,
org.openjdk.jmc.commands,
org.openjdk.jmc.browser,
org.openjdk.jmc.ui.websocket,
org.hdrhistogram.HdrHistogram,
org.eclipse.jetty.io,
org.eclipse.jetty.websocket.server,
org.eclipse.jetty.util,
org.eclipse.jetty.ee9.websocket.api,
org.eclipse.jetty.ee9.servlet,
org.eclipse.jetty.ee9.websocket.servlet,
org.eclipse.jetty.ee9.server,
org.eclipse.jetty.server,
org.eclipse.jetty.ee9.websocket.server,
org.eclipse.jetty.servlet-api
org.hdrhistogram.HdrHistogram
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.openjdk.jmc.flightrecorder.ui.FlightRecorderUI
Export-Package: org.openjdk.jmc.flightrecorder.ui,
Expand Down
8 changes: 3 additions & 5 deletions application/org.openjdk.jmc.ui.websocket/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ Bundle-RequiredExecutionEnvironment: JavaSE-21
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.osgi,
org.eclipse.ui,
org.eclipse.jetty.ee9.server,
org.eclipse.jetty.ee9.servlet,
org.eclipse.jetty.ee9.websocket.api,
org.eclipse.jetty.ee9.websocket.server,
org.eclipse.jetty.http,
org.eclipse.jetty.server,
org.eclipse.jetty.servlet-api,
org.eclipse.jetty.util,
org.eclipse.jetty.websocket.api,
org.eclipse.jetty.websocket.server,
org.openjdk.jmc.common,
org.openjdk.jmc.flightrecorder.serializers,
org.openjdk.jmc.flightrecorder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
*/
package org.openjdk.jmc.ui.websocket;

import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.time.Duration;
import java.util.HashMap;
Expand All @@ -46,12 +45,11 @@
import java.util.logging.Level;
import java.util.stream.Collectors;

import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
import org.eclipse.jetty.ee9.websocket.api.Session;
import org.eclipse.jetty.ee9.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.ee9.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.websocket.api.Callback;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.server.WebSocketUpgradeHandler;
import org.openjdk.jmc.common.item.IItemCollection;
import org.openjdk.jmc.flightrecorder.serializers.dot.DotSerializer;
import org.openjdk.jmc.flightrecorder.serializers.json.FlameGraphJsonSerializer;
Expand Down Expand Up @@ -80,35 +78,33 @@ public void startServer(int port) {
connector.setPort(port);
server.addConnector(connector);

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);

JettyWebSocketServletContainerInitializer.configure(context, (servletContext, container) -> {
WebSocketUpgradeHandler upgradeHandler = WebSocketUpgradeHandler.from(server, container -> {
container.setMaxBinaryMessageSize(Long.MAX_VALUE);
container.setIdleTimeout(Duration.ofMinutes(Long.MAX_VALUE));
container.addMapping("/events/*", (req, resp) -> {
container.setIdleTimeout(Duration.ofMillis(Long.MAX_VALUE));
container.addMapping("/events/*", (req, resp, callback) -> {
String eventsJson = MCWebsocketServer.toEventsJsonString(currentSelection);
WebsocketConnectionHandler handler = new WebsocketConnectionHandler(eventsJson);
handlers.add(handler);
return handler;
});
container.addMapping("/tree/*", (req, resp) -> {
container.addMapping("/tree/*", (req, resp, callback) -> {
String treeJson = MCWebsocketServer.toTreeModelJsonString(currentSelection);
WebsocketConnectionHandler handler = new WebsocketConnectionHandler(treeJson);
treeHandlers.add(handler);
return handler;
});
container.addMapping("/graph/*", (req, resp) -> {
container.addMapping("/graph/*", (req, resp, callback) -> {
String dot = MCWebsocketServer.toGraphModelDotString(currentSelection);
WebsocketConnectionHandler handler = new WebsocketConnectionHandler(dot);
graphHandlers.add(handler);
return handler;
});
});
server.setHandler(upgradeHandler);

try {
server.start();
WebsocketPlugin.getLogger().log(Level.INFO, "JMC WebSocket server listening on 127.0.0.1:" + port);
} catch (Exception e) {
WebsocketPlugin.getLogger().log(Level.SEVERE, "Failed to start websocket server", e);
}
Expand Down Expand Up @@ -174,53 +170,47 @@ public void shutdown() throws Exception {
server.stop();
}

private static class WebsocketConnectionHandler extends WebSocketAdapter {
public static class WebsocketConnectionHandler implements Session.Listener.AutoDemanding {
private String firstMessage;
private Session session;

WebsocketConnectionHandler(String firstMessage) {
this.firstMessage = firstMessage;
}

boolean isConnected() {
return session != null && session.isOpen();
}

public void sendMessage(String message) {
if (getSession() != null && isConnected()) {
WebsocketPlugin.getLogger().log(Level.INFO,
"Sending message to " + getSession().getRemoteAddress().toString());
try {
getSession().getRemote().sendString(message);
} catch (IOException e) {
WebsocketPlugin.getLogger().log(Level.SEVERE, "Failed to send websocket message", e);
}
if (isConnected()) {
WebsocketPlugin.getLogger().log(Level.INFO, "Sending message to " + session.getRemoteSocketAddress());
session.sendText(message, Callback.NOOP);
}
}

@Override
public void onWebSocketConnect(Session sess) {
super.onWebSocketConnect(sess);
WebsocketPlugin.getLogger().log(Level.INFO, "Socket connected to " + sess.getRemoteAddress().toString());
try {
if (firstMessage != null) {
getSession().getRemote().sendString(firstMessage);
firstMessage = null;
}
} catch (IOException e) {
WebsocketPlugin.getLogger().log(Level.SEVERE, "Failed to show outline view", e);
public void onWebSocketOpen(Session sess) {
this.session = sess;
WebsocketPlugin.getLogger().log(Level.INFO, "Socket connected to " + sess.getRemoteSocketAddress());
if (firstMessage != null) {
sess.sendText(firstMessage, Callback.NOOP);
firstMessage = null;
}
}

@Override
public void onWebSocketText(String message) {
super.onWebSocketText(message);
// No-op: the server is a one-way feed; incoming text is ignored.
}

@Override
public void onWebSocketClose(int statusCode, String reason) {
super.onWebSocketClose(statusCode, reason);
WebsocketPlugin.getLogger().log(Level.INFO, "Socket closed: [" + statusCode + "] " + reason);
}

@Override
public void onWebSocketError(Throwable cause) {
super.onWebSocketError(cause);
if (cause instanceof TimeoutException) {
WebsocketPlugin.getLogger().log(Level.INFO, "Websocket timed out");
} else if (cause instanceof ClosedChannelException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ public void start(BundleContext bundleContext) throws Exception {
this.getPreferenceStore().addPropertyChangeListener(preferenceChangeListener);
plugin = this;
startServer(getCryostatPort());
LOGGER.log(Level.INFO, "JMC Websocket Server is live!");
}

public void stop(BundleContext bundleContext) throws Exception {
Expand All @@ -88,17 +87,22 @@ public void notifyAll(IItemCollection events) {

private void startServer(int port) {
if (getServerEnabled()) {
LOGGER.log(Level.INFO, "Creating JMC WebSocket server on port " + port);
server = new MCWebsocketServer(port);
} else {
LOGGER.log(Level.INFO, "JMC WebSocket server disabled by preference; not creating");
}
}

private void stopServer() {
if (server != null) {
LOGGER.log(Level.INFO, "Stopping JMC WebSocket server");
try {
server.shutdown();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error shutting down the Jetty WebSocket server", e);
}
server = null;
}
}

Expand Down
Loading