RFR: 7198: add websocket server that pushes data on selection updates

Brice Dutheil github.com+803621+bric3 at openjdk.java.net
Tue Sep 14 12:28:08 UTC 2021


On Thu, 9 Sep 2021 16:32:58 GMT, Alex Ciminian <github.com+348973+cimi at openjdk.org> wrote:

> This PR adds a websocket server that pushes event data as JSON to all connected clients whenever the user updates their current selection in JMC. The server is disabled by default and can be enabled and disabled from JMC preferences. This is a rework of the proof-of-concept code in https://github.com/openjdk/jmc/pull/225 and uses the JSON serialiser introduced in #279.
> 
> ### Dependency management
> 
> I've struggled to add the required dependencies to the project. Initially I was only testing in eclipse with the setup from #225 and it worked fine.`mvn package` also worked on the command line. However, the spotless task from our CI script failed with the following error:
> 
> 
> org.apache.felix.resolver.reason.ReasonException: Uses constraint violation. Unable to resolve resource org.openjdk.jmc.flightrecorder.ui [osgi.identity; osgi.identity="org.openjdk.jmc.flightrecorder.ui"; type="osgi.bundle"; version:Version="8.2.0.qualifier"; singleton:="true"] because it is exposed to package 'javax.servlet' from resources javax.servlet [osgi.identity; osgi.identity="javax.servlet"; type="osgi.bundle"; version:Version="3.1.0.v201410161800"] and jakarta.servlet-api [osgi.identity; osgi.identity="jakarta.servlet-api"; type="osgi.bundle"; version:Version="4.0.0"] via two dependency chains.
> [ERROR] 
> [ERROR] Chain 1:
> [ERROR]   org.openjdk.jmc.flightrecorder.ui [osgi.identity; osgi.identity="org.openjdk.jmc.flightrecorder.ui"; type="osgi.bundle"; version:Version="8.2.0.qualifier"; singleton:="true"]
> [ERROR]     require: (osgi.wiring.bundle=javax.servlet)
> [ERROR]      |
> [ERROR]     provide: osgi.wiring.bundle: javax.servlet
> [ERROR]   javax.servlet [osgi.identity; osgi.identity="javax.servlet"; type="osgi.bundle"; version:Version="3.1.0.v201410161800"]
> [ERROR] 
> [ERROR] Chain 2:
> [ERROR]   org.openjdk.jmc.flightrecorder.ui [osgi.identity; osgi.identity="org.openjdk.jmc.flightrecorder.ui"; type="osgi.bundle"; version:Version="8.2.0.qualifier"; singleton:="true"]
> [ERROR]     require: (osgi.wiring.bundle=org.eclipse.jetty.server)
> [ERROR]      |
> [ERROR]     provide: osgi.wiring.bundle; bundle-version:Version="10.0.5"; osgi.wiring.bundle="org.eclipse.jetty.server"
> [ERROR]   org.eclipse.jetty.server [osgi.identity; osgi.identity="org.eclipse.jetty.server"; type="osgi.bundle"; version:Version="10.0.5"]
> [ERROR]     import: (&(osgi.wiring.package=javax.servlet)(&(version>=4.0.0)(!(version>=5.0.0))))
> [ERROR]      |
> [ERROR]     export: osgi.wiring.package: javax.servlet
> [ERROR]   jakarta.servlet-api [osgi.identity; osgi.identity="jakarta.servlet-api"; type="osgi.bundle"; version:Version="4.0.0"]
> 
> 
> This is because the task is run with the `-P uitests` and something in the UI test configuration pulls in jetty.server 10.0.5. Since [the latest available version](https://mvnrepository.com/artifact/org.eclipse.jetty.websocket/websocket-server) for the jetty websocket server is `9.4.43.v20210629` we can't use the newer `10.x` for the transitive dependencies.
> 
> I was able to work around this problem by setting bundle-version constraints in the `flightrecorder.ui` manifest. This makes all CI checks pass, but unfortunately it also breaks the JFR editor view in eclipse �� I don't understand why this is happening or how to fix it.
> 
> 
> org.osgi.framework.BundleException: Could not resolve module: org.openjdk.jmc.joverflow.ui [457]
>   Unresolved requirement: Import-Package: org.openjdk.jmc.flightrecorder.ui
>     -> Export-Package: org.openjdk.jmc.flightrecorder.ui; bundle-symbolic-name="org.openjdk.jmc.flightrecorder.ui"; bundle-version="8.2.0.qualifier"; version="0.0.0"
>        org.openjdk.jmc.flightrecorder.ui [445]
>          Unresolved requirement: Require-Bundle: org.eclipse.jetty.server; bundle-version="[9.4.43,10.0.0)"

Nice stepping stone toward flexible UIs.
There's still some println here and there ;)
Stopping the websocket server is not yet implemented.

application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/JfrEditor.java line 134:

> 132: 		websocketServerEnabledListener = e -> {
> 133: 			if (e.getProperty().equals(PreferenceKeys.PROPERTY_ENABLE_WEBSOCKET_SERVER)) {
> 134: 				if ((Boolean) e.getNewValue()) {

For readability purpose maybe this code could benefit from an explicit equality check

application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/websocket/WebsocketServer.java line 23:

> 21: 
> 22: public class WebsocketServer {
> 23: 	private static int PORT = 8029;

I think the port should be configurable.

application/org.openjdk.jmc.flightrecorder.ui/src/main/java/org/openjdk/jmc/flightrecorder/ui/websocket/WebsocketServer.java line 37:

> 35: 		Server server = new Server();
> 36: 		ServerConnector connector = new ServerConnector(server);
> 37: 		connector.setPort(PORT);

I'm not quite sure how this feature will be used, but can it make sense to only bind to locahost ?

releng/third-party/pom.xml line 50:

> 48: 		<jakarta.mail.version>1.6.5</jakarta.mail.version>
> 49: 		<javax.websocket.version>1.1</javax.websocket.version>
> 50: 		<jetty.version>9.4.43.v20210629</jetty.version>

I have seen in the PR description this codes needs to stick with 9.4.43…. But I noticed the coordinate of the artefacts may have changed after version 9 (group:`org.eclipse.jetty.websocket`, artefact: `wesocket-server` -> `websocket-jetty-server`). I haven't yet checked the dependencies in the POM, maybe that helps.

By the way there's a more recent version of [jetty 11.0.6](https://search.maven.org/artifact/org.eclipse.jetty.websocket/websocket-jetty-server/11.0.6/jar).

-------------

PR: https://git.openjdk.java.net/jmc/pull/306


More information about the jmc-dev mailing list