Skip to content

Commit

Permalink
Merge branch 'jetty-12.0.x' into fix/jetty-12-10411/default-environment
Browse files Browse the repository at this point in the history
  • Loading branch information
gregw committed Aug 29, 2023
2 parents 0b63e44 + 76cc130 commit cc1d2e4
Show file tree
Hide file tree
Showing 30 changed files with 1,200 additions and 614 deletions.
4 changes: 2 additions & 2 deletions documentation/jetty-documentation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,8 @@
<artifactId>jetty-websocket-jetty-client</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.ee10.websocket</groupId>
<artifactId>jetty-ee10-websocket-jetty-server</artifactId>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>jetty-websocket-jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.ee10.websocket</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@
[[pg-server-websocket-configure-filter]]
==== Advanced `WebSocketUpgradeFilter` Configuration

The `WebSocketUpgradeFilter` that handles the HTTP requests that upgrade to WebSocket is installed in these cases:
The `WebSocketUpgradeFilter` that handles the HTTP requests that upgrade to WebSocket is installed by the `JakartaWebSocketServletContainerInitializer`, as described in xref:pg-server-websocket-standard[this section].

* Either by the `JakartaWebSocketServletContainerInitializer`, as described in xref:pg-server-websocket-standard[this section].
* Or by a call to `JettyWebSocketServerContainer.addMapping(\...)`, as described in xref:pg-server-websocket-jetty[this section].

Typically, the `WebSocketUpgradeFilter` is not present in the `web.xml` configuration, and therefore the mechanisms above create a new `WebSocketUpgradeFilter` and install it _before_ any other Filter declared in `web.xml`, under the default name of `"org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter"` and with path mapping `/*`.
Typically, the `WebSocketUpgradeFilter` is not present in the `web.xml` configuration, and therefore the mechanisms above create a new `WebSocketUpgradeFilter` and install it _before_ any other Filter declared in `web.xml`, under the default name of `"org.eclipse.jetty.{ee-current}.websocket.servlet.WebSocketUpgradeFilter"` and with path mapping `/*`.

However, if the `WebSocketUpgradeFilter` is already present in `web.xml` under the default name, then the ``ServletContainerInitializer``s will use that declared in `web.xml` instead of creating a new one.

Expand All @@ -32,7 +29,7 @@ This allows you to customize:

For example:

[source,xml,subs=verbatim]
[source,xml,subs="verbatim,attributes"]
----
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
Expand All @@ -44,7 +41,7 @@ For example:
<!-- The CrossOriginFilter *must* be the first --> <!--1-->
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.ee9.servlets.CrossOriginFilter</filter-class>
<filter-class>org.eclipse.jetty.{ee-current}.servlets.CrossOriginFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
Expand All @@ -55,8 +52,8 @@ For example:
<!-- Configure the default WebSocketUpgradeFilter --> <!--2-->
<filter>
<!-- The filter name must be the default WebSocketUpgradeFilter name -->
<filter-name>org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter</filter-name> <!--3-->
<filter-class>org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter</filter-class>
<filter-name>org.eclipse.jetty.{ee-current}.websocket.servlet.WebSocketUpgradeFilter</filter-name> <!--3-->
<filter-class>org.eclipse.jetty.{ee-current}.websocket.servlet.WebSocketUpgradeFilter</filter-class>
<!-- Configure at most 1 MiB text messages -->
<init-param> <!--4-->
<param-name>maxTextMessageSize</param-name>
Expand All @@ -65,7 +62,7 @@ For example:
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter</filter-name>
<filter-name>org.eclipse.jetty.{ee-current}.websocket.servlet.WebSocketUpgradeFilter</filter-name>
<!-- Use a more specific path mapping for WebSocket requests -->
<url-pattern>/ws/*</url-pattern> <!--5-->
</filter-mapping>
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,54 +17,37 @@
When you write a WebSocket application using the standard `jakarta.websocket` APIs, your code typically need to depend on just the APIs to compile your application.
However, at runtime you need to have an implementation of the standard APIs in your class-path (or module-path).

The standard `jakarta.websocket` APIs are provided by the following Maven artifact:
The standard `jakarta.websocket` APIs, for example for Jakarta {ee-current-caps}, are provided by the following Maven artifact:

[source,xml,subs=normal]
----
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.0.0</version>
<version>2.1.0</version>
</dependency>
----

However, the artifact above lacks a proper JPMS `module-info.class` file, and therefore it is a little more difficult to use if you want to use of JPMS for your application.

If you want to use JPMS for your application, you can use this Maven artifact instead:

[source,xml,subs=normal]
----
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-jakarta-websocket-api</artifactId>
<version>2.0.0</version>
</dependency>
----

This artifact is nothing more than the `jakarta.websocket:jakarta.websocket-api:2.0.0` artifact repackaged with a proper `module-info.class` file.

At runtime, you also need an implementation of the standard `jakarta.websocket` APIs.

Jetty's implementation of the standard `jakarta.websocket` APIs is provided by the following Maven artifact (and its transitive dependencies):
At runtime, you also need an implementation of the standard Jakarta {ee-current-caps} WebSocket APIs, that Jetty provides with the following Maven artifact (and its transitive dependencies):

[source,xml,subs=normal]
----
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-jakarta-server</artifactId>
<groupId>org.eclipse.jetty.{ee-current}.websocket</groupId>
<artifactId>jetty-{ee-current}-websocket-jakarta-server</artifactId>
<version>{version}</version>
</dependency>
----

[NOTE]
====
The `jakarta.websocket-api` artifact and the `websocket-jakarta-server` artifact (and its transitive dependencies) should be present in the server class-path (or module-path), and never in the web application's `/WEB-INF/lib` directory.
The `jakarta.websocket-api` artifact and the `jetty-{ee-current}-websocket-jakarta-server` artifact (and their transitive dependencies) should be present in the server class-path (or module-path), and never in the web application's `/WEB-INF/lib` directory.
====

To configure correctly your WebSocket application based on the standard `jakarta.websocket` APIs, you need two steps:
To configure correctly your WebSocket application based on the standard Jakarta {ee-current-caps} WebSocket APIs, you need two steps:

. Make sure that Jetty xref:pg-server-websocket-standard-container[sets up] an instance of `jakarta.websocket.server.ServerContainer`.
. xref:pg-server-websocket-standard-endpoints[Configure] the WebSocket endpoints that implement your application logic, either by annotating their classes with the standard `jakarta.websocket` annotations, or by using the `ServerContainer` APIs to register them in your code.
. Make sure that Jetty sets up an instance of `jakarta.websocket.server.ServerContainer`, described in xref:pg-server-websocket-standard-container[this section].
. Configure the WebSocket endpoints that implement your application logic, either by annotating their classes with the standard `jakarta.websocket` annotations, or by using the `ServerContainer` APIs to register them in your code, described in xref:pg-server-websocket-standard-endpoints[this section].

[[pg-server-websocket-standard-container]]
===== Setting Up `ServerContainer`
Expand All @@ -86,7 +69,7 @@ On the other hand, when you deploy web applications using xref:pg-server-http-ha
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/websocket/WebSocketServerDocs.java[tags=standardContainerServletContextHandler]
----

Calling `JakartaWebSocketServletContainerInitializer.configure(\...)` must be done _before_ the `ServletContextHandler` is started, and configures the `jakarta.websocket` implementation for that web application context.
Calling `JakartaWebSocketServletContainerInitializer.configure(\...)` must be done _before_ the `ServletContextHandler` is started, and configures the Jakarta {ee-current-caps} WebSocket implementation for that web application context, making `ServerContainer` available to web applications.

[[pg-server-websocket-standard-endpoints]]
===== Configuring Endpoints
Expand All @@ -100,7 +83,7 @@ In this way, you do not need to write any additional code; you just need to ensu

On the other hand, when you deploy web applications using xref:pg-server-http-handler-use-webapp-context[`WebAppContext`] but you need to perform more advanced configuration of the `ServerContainer` or of the WebSocket endpoints, or when you deploy web applications using xref:pg-server-http-handler-use-servlet-context[`ServletContextHandler`], you need to access the `ServerContainer` APIs.

The `ServerContainer` instance is stored as a `ServletContext` attribute, so it can be retrieved when the `ServletContext` is initialized, either from a `ServletContextListener` or from a `HttpServlet`:
The `ServerContainer` instance is stored as a `ServletContext` attribute, so it can be retrieved when the `ServletContext` is initialized, either from a `ServletContextListener`, or from a Servlet `Filter`, or from an `HttpServlet`:

[source,java,indent=0]
----
Expand All @@ -112,7 +95,7 @@ include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/websocket/We
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/websocket/WebSocketServerDocs.java[tags=standardWebSocketInitializerServlet]
----

When you deploy web applications using xref:pg-server-http-handler-use-servlet-context[`ServletContextHandler`], you can also use this variant to set up the `ServerContainer` and configure the WebSocket endpoints in one step:
When you deploy web applications using xref:pg-server-http-handler-use-servlet-context[`ServletContextHandler`], you can alternatively use the code below to set up the `ServerContainer` and configure the WebSocket endpoints in one step:

[source,java,indent=0]
----
Expand All @@ -124,11 +107,11 @@ When the `ServletContextHandler` is started, the `Configurator` lambda (the seco
[[pg-server-websocket-standard-upgrade]]
====== Upgrade to WebSocket

Under the hood, `JakartaWebSocketServletContainerInitializer` installs the `org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter`, which is the component that intercepts HTTP requests to upgrade to WebSocket, and performs the upgrade from the HTTP protocol to the WebSocket protocol.
Under the hood, `JakartaWebSocketServletContainerInitializer` installs the `org.eclipse.jetty.{ee-current}.websocket.servlet.WebSocketUpgradeFilter`, which is the component that intercepts HTTP requests to upgrade to WebSocket, and performs the upgrade from the HTTP protocol to the WebSocket protocol.

[NOTE]
====
The `WebSocketUpgradeFilter` is installed under the filter name corresponding to its class name (that is, the string `"org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter"`) and with a filter mapping of `/*`.
The `WebSocketUpgradeFilter` is installed under the filter name corresponding to its class name (that is, the string `"org.eclipse.jetty.{ee-current}.websocket.servlet.WebSocketUpgradeFilter"`) and with a filter mapping of `/*`.
Refer to the xref:pg-server-websocket-configure-filter[advanced `WebSocketUpgradeFilter` configuration section] for more information.
====
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,34 @@
[[pg-server-websocket]]
=== WebSocket Server

Jetty provides two API implementations of the WebSocket protocol:
Jetty provides different implementations of the WebSocket protocol:

* An implementation for the standard `jakarta.websocket` APIs provided by link:https://jakarta.ee/specifications/websocket/2.0/[Jakarta WebSocket 2.0], described in xref:pg-server-websocket-standard[this section].
* An implementation for Jetty-specific WebSocket APIs, described in xref:pg-server-websocket-jetty[this section].
* A Jakarta EE 8 (`javax.websocket`) implementation, based on the link:https://jakarta.ee/specifications/websocket/1.1/[Jakarta WebSocket 1.1 Specification].
* A Jakarta EE 9 (`jakarta.websocket`) implementation, based on the link:https://jakarta.ee/specifications/websocket/2.0/[Jakarta WebSocket 2.0 Specification].
* A Jakarta EE 10 (`jakarta.websocket`) implementation, based on the link:https://jakarta.ee/specifications/websocket/2.1/[Jakarta WebSocket 2.1 Specification].
* A Jetty specific implementation, based on the Jetty WebSocket APIs, that does not depend on any Jakarta EE APIs.

Using the standard `jakarta.websocket` APIs allows your applications to depend only on standard APIs, and your applications may be deployed in any compliant WebSocket Container that supports Jakarta WebSocket 2.0.
The Jakarta EE implementations and APIs are described in xref:pg-server-websocket-standard[this section].

The standard APIs provide these features that are not present in the Jetty WebSocket APIs:
Using the standard Jakarta EE WebSocket APIs allows your applications to depend only on standard APIs, and your applications may be deployed in any compliant WebSocket Container that supports Jakarta WebSocket.
The standard Jakarta EE WebSocket APIs provide these features that are not present in the Jetty WebSocket APIs:

* Encoders and Decoders for automatic conversion of text or binary messages to objects.

On the other hand, the Jetty WebSocket APIs are more efficient and offer greater and more fine-grained control, and provide these features that are not present in the standard APIs:
The Jetty specific WebSocket implementation and APIs are described in xref:pg-server-websocket-jetty[this section].

* Suspend/resume to control backpressure.
Using the Jetty WebSocket APIs allows your applications to be more efficient and offer greater and more fine-grained control, and provide these features that are not present in the Jakarta EE WebSocket APIs:

* A demand mechanism to control backpressure.
* Remote socket address (IP address and port) information.
* WebSocket upgrade handling via Filter or Servlet.
* Advanced URI matching with Servlet WebSocket upgrade.
* Configuration of the network buffer capacity.
* Advanced request URI matching with regular expressions, in addition to Servlet patterns and URI template patterns.
* More configuration options, for example the network buffer capacity.
* Programmatic WebSocket upgrade, in addition to WebSocket upgrade based on URI matching, for maximum flexibility.

If your application needs specific features that are not provided by the standard APIs, the Jetty WebSocket APIs may provide such features.

If your application needs specific features that are not provided by the standard APIs, the Jetty WebSocket APIs may provide such features -- and if they do not, you may ask for these features by submitting an issue to the Jetty Project without waiting for the standard process to approve them.
TIP: If the feature you are looking for is not present, you may ask for these features by link:https://github.com/eclipse/jetty.project/issues[submitting an issue] to the Jetty Project without waiting for the standard Jakarta EE process to approve them and release a new version of the Jakarta EE WebSocket specification.

include::server-websocket-standard.adoc[]
include::server-websocket-jetty.adoc[]
include::server-websocket-filter.adoc[]
include::server-websocket-jetty.adoc[]
Loading

0 comments on commit cc1d2e4

Please sign in to comment.