Merge remote-tracking branch 'upstream/3.0' into 'upstream/3.1'

Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 7a3a052..f40113d 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -24,7 +24,7 @@
     strategy:
       matrix:
         java_version: [ 11 ]
-        verify_profiles: [ '-Plicense_check' ]
+        verify_profiles: [ '-Plicense_check,staging' ]
     continue-on-error: false
 
     steps:
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000..cb28b0e
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.jar
Binary files differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000..eacdc9e
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar
diff --git a/NOTICE.md b/NOTICE.md
index a737757..724bef4 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -43,11 +43,11 @@
 

 Bean Validation API 3.0.2

 * License: Apache License, 2.0

-* Project: http://beanvalidation.org/1.1/

+* Project: https://projects.eclipse.org/projects/ee4j.bean-validation

 * Copyright: 2009, Red Hat, Inc. and/or its affiliates, and individual contributors

 * by the @authors tag.

 

-Hibernate Validator CDI, 7.0.5.Final

+Hibernate Validator CDI, 8.0.1.Final

 * License: Apache License, 2.0

 * Project: https://beanvalidation.org/

 * Repackaged in org.glassfish.jersey.server.validation.internal.hibernate

diff --git a/archetypes/jersey-example-java8-webapp/pom.xml b/archetypes/jersey-example-java8-webapp/pom.xml
index 275b8f0..f67e025 100644
--- a/archetypes/jersey-example-java8-webapp/pom.xml
+++ b/archetypes/jersey-example-java8-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.archetypes</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-example-java8-webapp</artifactId>
diff --git a/archetypes/jersey-example-java8-webapp/src/main/resources/archetype-resources/pom.xml b/archetypes/jersey-example-java8-webapp/src/main/resources/archetype-resources/pom.xml
index dc88fe1..05b0c3d 100644
--- a/archetypes/jersey-example-java8-webapp/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/jersey-example-java8-webapp/src/main/resources/archetype-resources/pom.xml
@@ -125,7 +125,7 @@
     </profiles>
 
     <properties>
-        <java.version>1.8</java.version>
+        <java.version>11</java.version>
         <jersey.config.test.container.port>8080</jersey.config.test.container.port>
         <war.mvn.plugin.version>3.4.0</war.mvn.plugin.version>
     </properties>
diff --git a/archetypes/jersey-heroku-webapp/pom.xml b/archetypes/jersey-heroku-webapp/pom.xml
index e4a6f09..9dffb84 100644
--- a/archetypes/jersey-heroku-webapp/pom.xml
+++ b/archetypes/jersey-heroku-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.archetypes</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <packaging>maven-archetype</packaging>
 
diff --git a/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/pom.xml b/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/pom.xml
index 8652193..3b60fd3 100644
--- a/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/pom.xml
@@ -38,14 +38,14 @@
         </dependency> -->
 
         <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-servlet</artifactId>
+            <groupId>org.eclipse.jetty.ee10</groupId>
+            <artifactId>jetty-ee10-servlet</artifactId>
             <version>\${jetty.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-webapp</artifactId>
+            <groupId>org.eclipse.jetty.ee10</groupId>
+            <artifactId>jetty-ee10-webapp</artifactId>
             <version>\${jetty.version}</version>
             <scope>provided</scope>
         </dependency>
@@ -89,8 +89,8 @@
                 </executions>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
                 <version>\${jetty.version}</version>
                 <configuration>
                     <contextPath>/</contextPath>
@@ -117,7 +117,7 @@
 
     <properties>
         <jersey.version>${project.version}</jersey.version>
-        <jetty.version>11.0.18</jetty.version>
+        <jetty.version>12.0.3</jetty.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <surefire.mvn.plugin.version>3.2.1</surefire.mvn.plugin.version>
         <war.mvn.plugin.version>3.4.0</war.mvn.plugin.version>
diff --git a/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/src/main/java/heroku/Main.java b/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/src/main/java/heroku/Main.java
index 06594bf..30d0665 100644
--- a/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/src/main/java/heroku/Main.java
+++ b/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/src/main/java/heroku/Main.java
@@ -1,7 +1,7 @@
 package ${package}.heroku;
 
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.ee10.webapp.WebAppContext;
 
 /**
  * This class launches the web application in an embedded Jetty container. This is the entry point to your application. The Java
@@ -30,7 +30,7 @@
 
         final String webappDirLocation = "src/main/webapp/";
         root.setDescriptor(webappDirLocation + "/WEB-INF/web.xml");
-        root.setResourceBase(webappDirLocation);
+        root.setBaseResourceAsString(webappDirLocation);
 
         server.setHandler(root);
 
diff --git a/archetypes/jersey-quickstart-grizzly2/pom.xml b/archetypes/jersey-quickstart-grizzly2/pom.xml
index 5fd4f5c..7b7371e 100644
--- a/archetypes/jersey-quickstart-grizzly2/pom.xml
+++ b/archetypes/jersey-quickstart-grizzly2/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.glassfish.jersey.archetypes</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <artifactId>jersey-quickstart-grizzly2</artifactId>
     <packaging>maven-archetype</packaging>
diff --git a/archetypes/jersey-quickstart-webapp/pom.xml b/archetypes/jersey-quickstart-webapp/pom.xml
index 2d1fdfd..43525bc 100644
--- a/archetypes/jersey-quickstart-webapp/pom.xml
+++ b/archetypes/jersey-quickstart-webapp/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.glassfish.jersey.archetypes</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>maven-archetype</packaging>
diff --git a/archetypes/pom.xml b/archetypes/pom.xml
index 8b0010e..6642616 100644
--- a/archetypes/pom.xml
+++ b/archetypes/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.archetypes</groupId>
diff --git a/bom/pom.xml b/bom/pom.xml
index e5eb354..b3e32ba 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -30,7 +30,7 @@
 
     <groupId>org.glassfish.jersey</groupId>
     <artifactId>jersey-bom</artifactId>
-    <version>3.0.99-SNAPSHOT</version>
+    <version>3.1.99-SNAPSHOT</version>
     <packaging>pom</packaging>
     <name>jersey-bom</name>
 
@@ -80,11 +80,21 @@
             </dependency>
             <dependency>
                 <groupId>org.glassfish.jersey.connectors</groupId>
+                <artifactId>jersey-jnh-connector</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jersey.connectors</groupId>
                 <artifactId>jersey-jetty-connector</artifactId>
                 <version>${project.version}</version>
             </dependency>
             <dependency>
                 <groupId>org.glassfish.jersey.connectors</groupId>
+                <artifactId>jersey-jetty11-connector</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jersey.connectors</groupId>
                 <artifactId>jersey-jetty-http2-connector</artifactId>
                 <version>${project.version}</version>
             </dependency>
diff --git a/bundles/apidocs/pom.xml b/bundles/apidocs/pom.xml
index 33c6b72..b3387eb 100644
--- a/bundles/apidocs/pom.xml
+++ b/bundles/apidocs/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.bundles</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>apidocs</artifactId>
@@ -93,6 +93,11 @@
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.connectors</groupId>
+            <artifactId>jersey-jnh-connector</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.connectors</groupId>
             <artifactId>jersey-jdk-connector</artifactId>
             <version>${project.version}</version>
         </dependency>
@@ -134,6 +139,10 @@
             <version>3.1</version>
         </dependency>
         <dependency>
+            <groupId>jakarta.persistence</groupId>
+            <artifactId>jakarta.persistence-api</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.glassfish.jersey.containers</groupId>
             <artifactId>jersey-container-simple-http</artifactId>
             <version>${project.version}</version>
@@ -170,6 +179,22 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
+            <groupId>com.fasterxml.jackson.module</groupId>
+            <artifactId>jackson-module-jaxb-annotations</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>jakarta.xml.bind</groupId>
+                    <artifactId>jakarta.xml.bind-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>jakarta.activation</groupId>
+                    <artifactId>jakarta.activation-api</artifactId>
+                </exclusion>
+            </exclusions>
+            <optional>true</optional>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.glassfish.jersey.media</groupId>
             <artifactId>jersey-media-json-jettison</artifactId>
             <version>${project.version}</version>
@@ -255,54 +280,6 @@
             <version>${project.version}</version>
         </dependency>
     </dependencies>
-    <profiles>
-        <profile>
-        <id>JettyExclude</id>
-        <activation>
-            <jdk>1.8</jdk>
-        </activation>
-        <properties>
-            <jetty.version>${jetty9.version}</jetty.version>
-        </properties>
-        <dependencies>
-            <dependency>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-client</artifactId>
-                <version>${jetty.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-util</artifactId>
-                <version>${jetty.version}</version>
-            </dependency>
-        </dependencies>
-        </profile>
-        <profile>
-            <id>jetty2x</id>
-            <activation>
-                <activeByDefault>false</activeByDefault>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>org.glassfish.jersey.ext.microprofile</groupId>
-                    <artifactId>jersey-mp-rest-client</artifactId>
-                    <version>${project.version}</version>
-                </dependency>
-                <!-- media -->
-                <dependency>
-                    <groupId>org.glassfish.jersey.media</groupId>
-                    <artifactId>jersey-media-json-jackson1</artifactId>
-                    <version>${project.version}</version>
-                </dependency>
-                <!-- connectors -->
-                <dependency>
-                    <groupId>org.glassfish.jersey.connectors</groupId>
-                    <artifactId>jersey-helidon-connector</artifactId>
-                    <version>${project.version}</version>
-                </dependency>
-            </dependencies>
-        </profile>
-    </profiles>
     <build>
         <plugins>
             <plugin>
@@ -320,6 +297,8 @@
                                 <fileExclude>META-INF/versions/12/org/glassfish/jersey/wadl/doclet/*.java</fileExclude>
                                 <fileExclude>META-INF/versions/17/org/glassfish/jersey/helidon/connector/*.java</fileExclude>
                                 <fileExclude>org/glassfish/jersey/helidon/connector/*.java</fileExclude>
+                                <fileExclude>META-INF/versions/17/org/glassfish/jersey/helidon/connector/*.java</fileExclude>
+                                <fileExclude>org/glassfish/jersey/wadl/doclet/*.java</fileExclude>
                             </sourceFileExcludes>
                             <dependencySourceIncludes>
                                 <dependencySourceInclude>org.glassfish.jersey.*:*</dependencySourceInclude>
diff --git a/bundles/examples/pom.xml b/bundles/examples/pom.xml
index eb9b10a..0ac09a0 100644
--- a/bundles/examples/pom.xml
+++ b/bundles/examples/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.bundles</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-examples</artifactId>
@@ -735,5 +735,7 @@
             </plugin>
         </plugins>
     </build>
-
+    <properties>
+        <enforcer.skip>true</enforcer.skip>
+    </properties>
 </project>
diff --git a/bundles/jaxrs-ri/pom.xml b/bundles/jaxrs-ri/pom.xml
index ef1772f..f676560 100644
--- a/bundles/jaxrs-ri/pom.xml
+++ b/bundles/jaxrs-ri/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.bundles</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jaxrs-ri</artifactId>
@@ -182,7 +182,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -254,7 +253,7 @@
                             <includeGroupIds>jakarta.ws.rs,org.glassfish.jersey.core,org.glassfish.jersey.containers,org.glassfish.jersey.jaxb,org.glassfish.jersey.inject</includeGroupIds>
                             <includeClassifiers>sources</includeClassifiers>
                             <outputDirectory>${generated.src.dir}</outputDirectory>
-                            <excludes>**/NOTICE.md,**/NOTICE.markdown</excludes>
+                            <excludes>module-info.*,META-INF/MANIFEST.MF,**/NOTICE.md,**/NOTICE.markdown</excludes>
                         </configuration>
                     </execution>
                 </executions>
@@ -278,9 +277,9 @@
                             jersey.repackaged.org.objectweb.asm.*;version=${project.version}
                         </Export-Package>
                         <Import-Package><![CDATA[
-                            jakarta.servlet.annotation.*;resolution:=optional;version="[5.0,6.0)",
-                            jakarta.servlet.descriptor.*;resolution:=optional;version="[5.0,6.0)",
-                            jakarta.servlet.*;version="[5.0,6.0)",
+                            jakarta.servlet.annotation.*;resolution:=optional;version="[5.0,7.0)",
+                            jakarta.servlet.descriptor.*;resolution:=optional;version="[5.0,7.0)",
+                            jakarta.servlet.*;version="[5.0,7.0)",
                             ${jakarta.annotation.osgi.version},
                             jakarta.persistence.*;resolution:=optional,
                             jakarta.validation.*;resolution:=optional;version="[3,4)",
diff --git a/bundles/pom.xml b/bundles/pom.xml
index 1dc3d96..b5c4994 100644
--- a/bundles/pom.xml
+++ b/bundles/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.bundles</groupId>
diff --git a/connectors/apache-connector/pom.xml b/connectors/apache-connector/pom.xml
index b36502a..229b72a 100644
--- a/connectors/apache-connector/pom.xml
+++ b/connectors/apache-connector/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.connectors</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-apache-connector</artifactId>
diff --git a/connectors/apache5-connector/pom.xml b/connectors/apache5-connector/pom.xml
index 9cc96ec..54bb337 100644
--- a/connectors/apache5-connector/pom.xml
+++ b/connectors/apache5-connector/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.connectors</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-apache5-connector</artifactId>
diff --git a/connectors/grizzly-connector/pom.xml b/connectors/grizzly-connector/pom.xml
index 755a599..3d16f8f 100644
--- a/connectors/grizzly-connector/pom.xml
+++ b/connectors/grizzly-connector/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.connectors</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-grizzly-connector</artifactId>
diff --git a/connectors/helidon-connector/pom.xml b/connectors/helidon-connector/pom.xml
index 23d5dc7..68002fa 100644
--- a/connectors/helidon-connector/pom.xml
+++ b/connectors/helidon-connector/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.connectors</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -81,6 +81,7 @@
                <artifactId>maven-javadoc-plugin</artifactId>
                <configuration>
                     <source>8</source>
+                   <detectJavaApiLink>false</detectJavaApiLink>
                </configuration>
             </plugin>
         </plugins>
diff --git a/connectors/jdk-connector/pom.xml b/connectors/jdk-connector/pom.xml
index 54a3c95..a184a23 100644
--- a/connectors/jdk-connector/pom.xml
+++ b/connectors/jdk-connector/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.connectors</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-jdk-connector</artifactId>
@@ -34,6 +34,8 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <!-- https://bugs.openjdk.java.net/browse/JDK-8211426 -->
+        <surefire.security.argline>-Djdk.tls.server.protocols=TLSv1.2</surefire.security.argline>
     </properties>
 
     <dependencies>
@@ -84,16 +86,6 @@
 
     <profiles>
         <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <properties>
-                <!-- https://bugs.openjdk.java.net/browse/JDK-8211426 -->
-                <surefire.security.argline>-Djdk.tls.server.protocols=TLSv1.2</surefire.security.argline>
-            </properties>
-        </profile>
-        <profile>
             <id>disable_tls1and11</id>
             <!-- TLS 1 and TLS 1.1 are disabled for JDK 16 -->
             <activation>
@@ -116,5 +108,4 @@
             </build>
         </profile>
     </profiles>
-
 </project>
diff --git a/connectors/jetty-connector/pom.xml b/connectors/jetty-connector/pom.xml
index 9aa979e..f55209a 100644
--- a/connectors/jetty-connector/pom.xml
+++ b/connectors/jetty-connector/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.connectors</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-jetty-connector</artifactId>
@@ -34,10 +34,10 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <java8.build.outputDirectory>${project.basedir}/target</java8.build.outputDirectory>
-        <java8.sourceDirectory>${project.basedir}/src/main/java8</java8.sourceDirectory>
-        <java11.build.outputDirectory>${project.basedir}/target11</java11.build.outputDirectory>
+        <java11.build.outputDirectory>${project.basedir}/target</java11.build.outputDirectory>
         <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
+        <java17.build.outputDirectory>${project.basedir}/target17</java17.build.outputDirectory>
+        <java17.sourceDirectory>${project.basedir}/src/main/java17</java17.sourceDirectory>
     </properties>
 
     <dependencies>
@@ -51,16 +51,6 @@
                 </exclusion>
             </exclusions>
         </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-util</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-api</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
 
         <dependency>
             <groupId>org.glassfish.jersey.media</groupId>
@@ -74,18 +64,28 @@
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
-<!--        <dependency>-->
-<!--            <groupId>org.glassfish.jersey.media</groupId>-->
-<!--            <artifactId>jersey-media-json-jackson</artifactId>-->
-<!--            <version>${project.version}</version>-->
-<!--            <scope>test</scope>-->
-<!--        </dependency>-->
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-json-jackson</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.test-framework.providers</groupId>
             <artifactId>jersey-test-framework-provider-jetty</artifactId>
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-osgi</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -105,21 +105,6 @@
                 <artifactId>maven-compiler-plugin</artifactId>
             </plugin>
             <plugin>
-                <!-- TODO remove after jakartification -->
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <executions>
-            <execution>
-                <id>default-test</id> <!-- jakartification-excluded-tests -->
-                <configuration>
-                    <excludes>
-                        <exclude>org/glassfish/jersey/jetty/connector/EntityTest.java</exclude>
-                    </excludes>
-                </configuration>
-            </execution>
-            </executions>
-            </plugin>
-            <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                 <inherited>true</inherited>
@@ -139,72 +124,11 @@
         <profile>
             <id>JettyExclude</id>
             <activation>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <properties>
-                <jetty.version>${jetty9.version}</jetty.version>
+                <jetty.version>${jetty11.version}</jetty.version>
             </properties>
-            <dependencies>
-                <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-client</artifactId>
-                    <version>${jetty.version}</version>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-                <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-util</artifactId>
-                    <version>${jetty.version}</version>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-            </dependencies>
-            <build>
-                <directory>${java8.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java8.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <configuration>
-                            <testExcludes>
-                                <testExclude>org/glassfish/jersey/jetty/connector/*.java</testExclude>
-                            </testExcludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>Jetty11</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
             <build>
                 <directory>${java11.build.outputDirectory}</directory>
                 <plugins>
@@ -225,17 +149,54 @@
                             </execution>
                         </executions>
                     </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <configuration>
+                            <testExcludes>
+                                <testExclude>org/glassfish/jersey/jetty/connector/*.java</testExclude>
+                            </testExcludes>
+                        </configuration>
+                    </plugin>
                 </plugins>
             </build>
         </profile>
         <profile>
-            <id>copyJDK11FilesToMultiReleaseJar</id>
+            <id>JettyInclude</id>
+            <activation>
+                <jdk>[17,)</jdk>
+            </activation>
+            <build>
+                <directory>${java17.build.outputDirectory}</directory>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>add-source</goal>
+                                </goals>
+                                <configuration>
+                                    <sources>
+                                        <source>${java17.sourceDirectory}</source>
+                                    </sources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>copyJDK17FilesToMultiReleaseJar</id>
             <activation>
                 <file>
-                    <!-- ${java11.build.outputDirectory} does not work here -->
-                    <exists>target11/classes/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.class</exists>
+                    <!-- ${java17.build.outputDirectory} does not work here -->
+                    <exists>target17/classes/org/glassfish/jersey/jetty/connector/JettyConnector.class</exists>
                 </file>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <build>
                 <plugins>
@@ -256,16 +217,16 @@
                         <inherited>true</inherited>
                         <executions>
                             <execution>
-                                <id>copy-jdk11-classes</id>
+                                <id>copy-jdk17-classes</id>
                                 <phase>prepare-package</phase>
                                 <goals>
                                     <goal>copy-resources</goal>
                                 </goals>
                                 <configuration>
-                                    <outputDirectory>${java8.build.outputDirectory}/classes/META-INF/versions/11</outputDirectory>
+                                    <outputDirectory>${java11.build.outputDirectory}/classes/META-INF/versions/17</outputDirectory>
                                     <resources>
                                         <resource>
-                                            <directory>${java11.build.outputDirectory}/classes</directory>
+                                            <directory>${java17.build.outputDirectory}/classes</directory>
                                         </resource>
                                     </resources>
                                 </configuration>
@@ -277,14 +238,14 @@
                         <artifactId>maven-antrun-plugin</artifactId>
                         <executions>
                             <execution>
-                                <id>copy-jdk11-sources</id>
+                                <id>copy-jdk17-sources</id>
                                 <phase>package</phase>
                                 <configuration>
                                     <target>
-                                        <property name="sources-jar" value="${java8.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+                                        <property name="sources-jar" value="${java11.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
                                         <echo>sources-jar: ${sources-jar}</echo>
                                         <zip destfile="${sources-jar}" update="true">
-                                            <zipfileset dir="${java11.sourceDirectory}" prefix="META-INF/versions/11"/>
+                                            <zipfileset dir="${java17.sourceDirectory}" prefix="META-INF/versions/17"/>
                                         </zip>
                                     </target>
                                 </configuration>
@@ -298,5 +259,4 @@
             </build>
         </profile>
     </profiles>
-
 </project>
diff --git a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
index dfd3b79..50ec6bd 100644
--- a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
+++ b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,16 +18,10 @@
 
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.core.Configurable;
 import jakarta.ws.rs.core.Configuration;
-
-import org.glassfish.jersey.client.Initializable;
 import org.glassfish.jersey.client.spi.Connector;
 import org.glassfish.jersey.client.spi.ConnectorProvider;
 
-import org.eclipse.jetty.client.HttpClient;
-import org.glassfish.jersey.internal.util.JdkVersion;
-
 /**
  * A {@link ConnectorProvider} for Jersey {@link Connector connector}
  * instances that utilize the Jetty HTTP Client to send and receive
@@ -86,43 +80,6 @@
 
     @Override
     public Connector getConnector(Client client, Configuration runtimeConfig) {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
-            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-        }
-        return new JettyConnector(client, runtimeConfig);
-    }
-
-    /**
-     * Retrieve the underlying Jetty {@link org.eclipse.jetty.client.HttpClient} instance from
-     * {@link org.glassfish.jersey.client.JerseyClient} or {@link org.glassfish.jersey.client.JerseyWebTarget}
-     * configured to use {@code JettyConnectorProvider}.
-     *
-     * @param component {@code JerseyClient} or {@code JerseyWebTarget} instance that is configured to use
-     *                  {@code JettyConnectorProvider}.
-     * @return underlying Jetty {@code HttpClient} instance.
-     *
-     * @throws java.lang.IllegalArgumentException in case the {@code component} is neither {@code JerseyClient}
-     *                                            nor {@code JerseyWebTarget} instance or in case the component
-     *                                            is not configured to use a {@code JettyConnectorProvider}.
-     * @since 2.8
-     */
-    public static HttpClient getHttpClient(Configurable<?> component) {
-        if (!(component instanceof Initializable)) {
-            throw new IllegalArgumentException(
-                    LocalizationMessages.INVALID_CONFIGURABLE_COMPONENT_TYPE(component.getClass().getName()));
-        }
-
-        final Initializable<?> initializable = (Initializable<?>) component;
-        Connector connector = initializable.getConfiguration().getConnector();
-        if (connector == null) {
-            initializable.preInitialize();
-            connector = initializable.getConfiguration().getConnector();
-        }
-
-        if (connector instanceof JettyConnector) {
-            return ((JettyConnector) connector).getHttpClient();
-        }
-
-        throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED());
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 }
diff --git a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
index b061ef5..6453521 100644
--- a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
+++ b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
index dc43fb3..2b9e8b2 100644
--- a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
+++ b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnector.java
similarity index 80%
copy from connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java
copy to connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnector.java
index d85ec4d..4ae73dd 100644
--- a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java
+++ b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnector.java
@@ -16,33 +16,49 @@
 
 package org.glassfish.jersey.jetty.connector;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.CookieStore;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.core.Configuration;
 import jakarta.ws.rs.core.MultivaluedMap;
-import org.eclipse.jetty.client.HttpClient;
+
+import javax.net.ssl.SSLContext;
+
+import org.eclipse.jetty.client.AuthenticationStore;
+import org.eclipse.jetty.client.BasicAuthentication;
+import org.eclipse.jetty.client.ByteBufferRequestContent;
+import org.eclipse.jetty.client.ContentResponse;
+import org.eclipse.jetty.client.FutureResponseListener;
 import org.eclipse.jetty.client.HttpClientTransport;
-import org.eclipse.jetty.client.HttpProxy;
-import org.eclipse.jetty.client.ProxyConfiguration;
-import org.eclipse.jetty.client.api.AuthenticationStore;
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.client.api.Result;
-import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
-import org.eclipse.jetty.client.util.BasicAuthentication;
-import org.eclipse.jetty.client.util.BytesContentProvider;
-import org.eclipse.jetty.client.util.FutureResponseListener;
-import org.eclipse.jetty.client.util.OutputStreamContentProvider;
-import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.client.OutputStreamRequestContent;
+import org.eclipse.jetty.client.Request;
+import org.eclipse.jetty.client.Response;
+import org.eclipse.jetty.client.Result;
+import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
+import org.eclipse.jetty.client.transport.HttpRequest;
+import org.eclipse.jetty.http.HttpCookieStore;
 import org.eclipse.jetty.io.ClientConnector;
-import org.eclipse.jetty.util.HttpCookieStore;
-import org.eclipse.jetty.util.Jetty;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
 import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.ClientRequest;
 import org.glassfish.jersey.client.ClientResponse;
@@ -55,30 +71,15 @@
 import org.glassfish.jersey.message.internal.OutboundMessageContext;
 import org.glassfish.jersey.message.internal.Statuses;
 
-import javax.net.ssl.SSLContext;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.CookieStore;
-import java.net.URI;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.HttpProxy;
+import org.eclipse.jetty.client.ProxyConfiguration;
+import org.eclipse.jetty.http.HttpField;
+import org.eclipse.jetty.http.HttpFields;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.util.Jetty;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
 
 /**
  * A {@link Connector} that utilizes the Jetty HTTP Client to send and receive
@@ -129,12 +130,12 @@
  * @author Arul Dhesiaseelan (aruld at acm.org)
  * @author Marek Potociar
  */
-public class JettyConnector implements Connector {
+class JettyConnector implements Connector {
 
     private static final Logger LOGGER = Logger.getLogger(JettyConnector.class.getName());
 
     private final HttpClient client;
-    private final CookieStore cookieStore;
+    private final HttpCookieStore cookieStore;
     private final Configuration configuration;
     private final Optional<Integer> syncListenerResponseMaxSize;
 
@@ -144,17 +145,23 @@
      * @param jaxrsClient JAX-RS client instance, for which the connector is created.
      * @param config client configuration.
      */
-    protected JettyConnector(final Client jaxrsClient, final Configuration config) {
+    JettyConnector(final Client jaxrsClient, final Configuration config) {
         this.configuration = config;
-        HttpClient httpClient = getRegisteredHttpClient(config);
-
+        HttpClient httpClient = null;
+        if (config.isRegistered(JettyHttpClientSupplier.class)) {
+            Optional<Object> contract = config.getInstances().stream()
+                    .filter(a-> JettyHttpClientSupplier.class.isInstance(a)).findFirst();
+            if (contract.isPresent()) {
+                httpClient = ((JettyHttpClientSupplier) contract.get()).getHttpClient();
+            }
+        }
         if (httpClient == null) {
             final SSLContext sslContext = jaxrsClient.getSslContext();
             final SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(false);
             sslContextFactory.setSslContext(sslContext);
             final ClientConnector connector = new ClientConnector();
             connector.setSslContextFactory(sslContextFactory);
-            final HttpClientTransport transport = initClientTransport(connector);
+            final HttpClientTransport transport = new HttpClientTransportOverHTTP(connector);
             httpClient = new HttpClient(transport);
         }
         this.client = httpClient;
@@ -202,13 +209,13 @@
         });
 
         if (disableCookies) {
-            client.setCookieStore(new HttpCookieStore.Empty());
+            client.setHttpCookieStore(new HttpCookieStore.Empty());
         }
 
         final Object slResponseMaxSize = configuration.getProperties()
-            .get(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE);
+                .get(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE);
         if (slResponseMaxSize != null && slResponseMaxSize instanceof Integer
-            && (Integer) slResponseMaxSize > 0) {
+                && (Integer) slResponseMaxSize > 0) {
             this.syncListenerResponseMaxSize = Optional.of((Integer) slResponseMaxSize);
         }
         else {
@@ -220,38 +227,7 @@
         } catch (final Exception e) {
             throw new ProcessingException("Failed to start the client.", e);
         }
-        this.cookieStore = client.getCookieStore();
-    }
-
-    /**
-     * provides required HTTP client transport for client
-     *
-     * the default transport is {@link HttpClientTransportOverHTTP}
-     *
-     * @return instance of {@link HttpClientTransport}
-     * @since 2.41
-     */
-    protected HttpClientTransport initClientTransport(ClientConnector clientConnector) {
-        return new HttpClientTransportOverHTTP(clientConnector);
-    }
-
-    /**
-     * provides custom registered {@link HttpClient} if any (or NULL)
-     *
-     * @param config configuration where {@link HttpClient} could be registered
-     * @return {@link HttpClient} instance if any was previously registered or NULL
-     *
-     * @since 2.41
-     */
-    protected HttpClient getRegisteredHttpClient(Configuration config) {
-        if (config.isRegistered(JettyHttpClientSupplier.class)) {
-            Optional<Object> contract = config.getInstances().stream()
-                    .filter(a-> JettyHttpClientSupplier.class.isInstance(a)).findFirst();
-            if (contract.isPresent()) {
-                return  ((JettyHttpClientSupplier) contract.get()).getHttpClient();
-            }
-        }
-        return null;
+        this.cookieStore = client.getHttpCookieStore();
     }
 
     /**
@@ -270,20 +246,17 @@
      * @return the {@link CookieStore} instance or null when
      * JettyClientProperties.DISABLE_COOKIES set to true.
      */
-    public CookieStore getCookieStore() {
+    public HttpCookieStore getCookieStore() {
         return cookieStore;
     }
 
     @Override
     public ClientResponse apply(final ClientRequest jerseyRequest) throws ProcessingException {
         final Request jettyRequest = translateRequest(jerseyRequest);
-        final Map<String, String> clientHeadersSnapshot = new HashMap<>();
-        final ContentProvider entity =
-                getBytesProvider(jerseyRequest, jerseyRequest.getHeaders(), clientHeadersSnapshot, jettyRequest);
+        final Map<String, String> clientHeadersSnapshot = writeOutBoundHeaders(jerseyRequest.getHeaders(), jettyRequest);
+        final Request.Content entity = getBytesProvider(jerseyRequest);
         if (entity != null) {
-            jettyRequest.content(entity);
-        } else {
-            clientHeadersSnapshot.putAll(writeOutBoundHeaders(jerseyRequest.getHeaders(), jettyRequest));
+            jettyRequest.body(entity);
         }
 
         try {
@@ -293,12 +266,12 @@
             }
             else {
                 final FutureResponseListener listener
-                    = new FutureResponseListener(jettyRequest, syncListenerResponseMaxSize.get());
+                        = new FutureResponseListener(jettyRequest, syncListenerResponseMaxSize.get());
                 jettyRequest.send(listener);
                 jettyResponse = listener.get();
             }
             HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, jerseyRequest.getHeaders(),
-                                           JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
+                    JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
 
             final jakarta.ws.rs.core.Response.StatusType status = jettyResponse.getReason() == null
                     ? Statuses.from(jettyResponse.getStatus())
@@ -364,22 +337,19 @@
 
     private Map<String, String> writeOutBoundHeaders(final MultivaluedMap<String, Object> headers, final Request request) {
         final Map<String, String> stringHeaders = HeaderUtils.asStringHeadersSingleValue(headers, configuration);
-        final Consumer<HttpFields.Mutable> mutableConsumer = httpFields -> {
-            // remove User-agent header set by Jetty; Jersey already sets this in its request (incl. Jetty version)
-            httpFields.remove(HttpHeader.USER_AGENT);
-            for (final Map.Entry<String, String> e : stringHeaders.entrySet()) {
-                httpFields.put(e.getKey(), e.getValue());
-            }
-        };
-        request.headers(mutableConsumer);
 
+        // remove User-agent header set by Jetty; Jersey already sets this in its request (incl. Jetty version)
+        request.headers(httpFields -> httpFields.remove(HttpHeader.USER_AGENT));
+        if (request instanceof HttpRequest) {
+            final HttpRequest httpRequest = (HttpRequest) request;
+            for (final Map.Entry<String, String> e : stringHeaders.entrySet()) {
+                httpRequest.addHeader(new HttpField(e.getKey(), e.getValue()));
+            }
+        }
         return stringHeaders;
     }
 
-    private ContentProvider getBytesProvider(final ClientRequest clientRequest,
-                                             final MultivaluedMap<String, Object> headers,
-                                             final Map<String, String> snapshot,
-                                             final Request request) {
+    private Request.Content getBytesProvider(final ClientRequest clientRequest) {
         final Object entity = clientRequest.getEntity();
 
         if (entity == null) {
@@ -390,7 +360,6 @@
         clientRequest.setStreamProvider(new OutboundMessageContext.StreamProvider() {
             @Override
             public OutputStream getOutputStream(final int contentLength) throws IOException {
-                snapshot.putAll(writeOutBoundHeaders(headers, request));
                 return outputStream;
             }
         });
@@ -400,17 +369,22 @@
         } catch (final IOException e) {
             throw new ProcessingException("Failed to write request entity.", e);
         }
-        return new BytesContentProvider(outputStream.toByteArray());
+        return new ByteBufferRequestContent(ByteBuffer.wrap(outputStream.toByteArray()));
     }
 
-    private ContentProvider getStreamProvider(final ClientRequest clientRequest) {
+    private Request.Content getStreamProvider(final ClientRequest clientRequest) {
         final Object entity = clientRequest.getEntity();
 
         if (entity == null) {
             return null;
         }
 
-        final OutputStreamContentProvider streamContentProvider = new OutputStreamContentProvider();
+        String contentTypeHeader = clientRequest.getRequestHeaders()
+                .getFirst(HttpHeader.CONTENT_TYPE.asString());
+
+        String contentType = contentTypeHeader != null ? contentTypeHeader : "application/octet-stream";
+
+        final OutputStreamRequestContent streamContentProvider = new OutputStreamRequestContent(contentType);
         clientRequest.setStreamProvider(new OutboundMessageContext.StreamProvider() {
             @Override
             public OutputStream getOutputStream(final int contentLength) throws IOException {
@@ -420,12 +394,12 @@
         return streamContentProvider;
     }
 
-    private void processContent(final ClientRequest clientRequest, final ContentProvider entity) throws IOException {
+    private void processContent(final ClientRequest clientRequest, final Request.Content entity) throws IOException {
         if (entity == null) {
             return;
         }
 
-        final OutputStreamContentProvider streamContentProvider = (OutputStreamContentProvider) entity;
+        final OutputStreamRequestContent streamContentProvider = (OutputStreamRequestContent) entity;
         try (final OutputStream output = streamContentProvider.getOutputStream()) {
             clientRequest.writeEntity();
         }
@@ -435,31 +409,31 @@
     public Future<?> apply(final ClientRequest jerseyRequest, final AsyncConnectorCallback callback) {
         final Request jettyRequest = translateRequest(jerseyRequest);
         final Map<String, String> clientHeadersSnapshot = writeOutBoundHeaders(jerseyRequest.getHeaders(), jettyRequest);
-        final ContentProvider entity = getStreamProvider(jerseyRequest);
+        final Request.Content entity = getStreamProvider(jerseyRequest);
         if (entity != null) {
-            jettyRequest.content(entity);
+            jettyRequest.body(entity);
         }
         final AtomicBoolean callbackInvoked = new AtomicBoolean(false);
         final Throwable failure;
         try {
             final CompletableFuture<ClientResponse> responseFuture = new CompletableFuture<ClientResponse>();
             responseFuture.whenComplete(
-                            (clientResponse, throwable) -> {
-                                if (throwable != null && throwable instanceof CancellationException) {
-                                    // take care of future cancellation
-                                    jettyRequest.abort(throwable);
+                    (clientResponse, throwable) -> {
+                        if (throwable != null && throwable instanceof CancellationException) {
+                            // take care of future cancellation
+                            jettyRequest.abort(throwable);
 
-                                }
-                            });
+                        }
+                    });
 
             final AtomicReference<ClientResponse> jerseyResponse = new AtomicReference<>();
             final ByteBufferInputStream entityStream = new ByteBufferInputStream();
-            jettyRequest.send(new Response.Listener.Adapter() {
+            jettyRequest.send(new Response.Listener() {
 
                 @Override
                 public void onHeaders(final Response jettyResponse) {
                     HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, jerseyRequest.getHeaders(),
-                                                   JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
+                            JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
 
                     if (responseFuture.isDone()) {
                         if (!callbackInvoked.compareAndSet(false, true)) {
@@ -528,7 +502,7 @@
     }
 
     private static ClientResponse translateResponse(final ClientRequest jerseyRequest,
-                                                    final org.eclipse.jetty.client.api.Response jettyResponse,
+                                                    final org.eclipse.jetty.client.Response jettyResponse,
                                                     final NonBlockingInputStream entityStream) {
         final ClientResponse jerseyResponse = new ClientResponse(Statuses.from(jettyResponse.getStatus()), jerseyRequest);
         processResponseHeaders(jettyResponse.getHeaders(), jerseyResponse);
@@ -549,4 +523,4 @@
             throw new ProcessingException("Failed to stop the client.", e);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
new file mode 100644
index 0000000..43a08ce
--- /dev/null
+++ b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty.connector;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+
+import org.glassfish.jersey.client.Initializable;
+import org.glassfish.jersey.client.spi.Connector;
+import org.glassfish.jersey.client.spi.ConnectorProvider;
+
+import org.eclipse.jetty.client.HttpClient;
+
+/**
+ * A {@link ConnectorProvider} for Jersey {@link Connector connector}
+ * instances that utilize the Jetty HTTP Client to send and receive
+ * HTTP request and responses.
+ * <p>
+ * The following connector configuration properties are supported:
+ * <ul>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#ASYNC_THREADPOOL_SIZE}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#CONNECT_TIMEOUT}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#FOLLOW_REDIRECTS}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_URI}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
+ * <li>{@link JettyClientProperties#DISABLE_COOKIES}</li>*
+ * <li>{@link JettyClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
+ * <li>{@link JettyClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
+ * <li>{@link JettyClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
+ * </ul>
+ * </p>
+ * <p>
+ * This transport supports both synchronous and asynchronous processing of client requests.
+ * The following methods are supported: GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT and MOVE.
+ * </p>
+ * <p>
+ * Typical usage:
+ * </p>
+ * <pre>
+ * {@code
+ * ClientConfig config = new ClientConfig();
+ * config.connectorProvider(new JettyConnectorProvider());
+ * Client client = ClientBuilder.newClient(config);
+ *
+ * // async request
+ * WebTarget target = client.target("http://localhost:8080");
+ * Future<Response> future = target.path("resource").request().async().get();
+ *
+ * // wait for 3 seconds
+ * Response response = future.get(3, TimeUnit.SECONDS);
+ * String entity = response.readEntity(String.class);
+ * client.close();
+ * }
+ * </pre>
+ * <p>
+ * Connector instances created via Jetty HTTP Client-based connector provider support only
+ * {@link org.glassfish.jersey.client.RequestEntityProcessing#BUFFERED entity buffering}.
+ * Defining the property {@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING} has no
+ * effect on Jetty HTTP Client-based connectors.
+ * </p>
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Marek Potociar
+ * @since 2.5
+ */
+public class JettyConnectorProvider implements ConnectorProvider {
+
+    @Override
+    public Connector getConnector(Client client, Configuration runtimeConfig) {
+        return new JettyConnector(client, runtimeConfig);
+    }
+
+    /**
+     * Retrieve the underlying Jetty {@link org.eclipse.jetty.client.HttpClient} instance from
+     * {@link org.glassfish.jersey.client.JerseyClient} or {@link org.glassfish.jersey.client.JerseyWebTarget}
+     * configured to use {@code JettyConnectorProvider}.
+     *
+     * @param component {@code JerseyClient} or {@code JerseyWebTarget} instance that is configured to use
+     *                  {@code JettyConnectorProvider}.
+     * @return underlying Jetty {@code HttpClient} instance.
+     *
+     * @throws java.lang.IllegalArgumentException in case the {@code component} is neither {@code JerseyClient}
+     *                                            nor {@code JerseyWebTarget} instance or in case the component
+     *                                            is not configured to use a {@code JettyConnectorProvider}.
+     * @since 2.8
+     */
+    public static HttpClient getHttpClient(Configurable<?> component) {
+        if (!(component instanceof Initializable)) {
+            throw new IllegalArgumentException(
+                    LocalizationMessages.INVALID_CONFIGURABLE_COMPONENT_TYPE(component.getClass().getName()));
+        }
+
+        final Initializable<?> initializable = (Initializable<?>) component;
+        Connector connector = initializable.getConfiguration().getConnector();
+        if (connector == null) {
+            initializable.preInitialize();
+            connector = initializable.getConfiguration().getConnector();
+        }
+
+        if (connector instanceof JettyConnector) {
+            return ((JettyConnector) connector).getHttpClient();
+        }
+
+        throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED());
+    }
+}
diff --git a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
similarity index 93%
rename from connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
rename to connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
index b061ef5..6453521 100644
--- a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
+++ b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
similarity index 84%
rename from connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
rename to connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
index 59c8fd3..2b9e8b2 100644
--- a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
+++ b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,9 +15,7 @@
  */
 package org.glassfish.jersey.jetty.connector;
 
-import jakarta.ws.rs.ProcessingException;
 import org.eclipse.jetty.client.HttpClient;
-import org.glassfish.jersey.internal.util.JdkVersion;
 
 /**
  * Jetty HttpClient supplier to be registered into Jersey configuration to be used by {@link JettyConnector}.
@@ -53,9 +51,6 @@
 
     @Override
     public HttpClient getHttpClient() {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
-            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-        }
-        return null; // does not work at JDK 1.8
+        return httpClient;
     }
 }
diff --git a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java b/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
deleted file mode 100644
index 8723025..0000000
--- a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.jetty.connector;
-
-import jakarta.ws.rs.ProcessingException;
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.core.Configuration;
-
-import org.glassfish.jersey.client.spi.Connector;
-import org.glassfish.jersey.client.spi.ConnectorProvider;
-
-import org.glassfish.jersey.internal.util.JdkVersion;
-
-/**
- * JDK 1.8 Jetty Connector stub which only throws exception when running on JDK 1.8
- * New Jetty (11+) does not support JDKs prior to 11
- *
- * @since 3.0.0
- */
-public class JettyConnectorProvider implements ConnectorProvider {
-
-    @Override
-    public Connector getConnector(Client client, Configuration runtimeConfig) {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
-            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-        }
-        return null; // does not work at JDK 1.8
-    }
-
-}
diff --git a/connectors/jetty-connector/src/main/resources/org/glassfish/jersey/jetty/connector/localization.properties b/connectors/jetty-connector/src/main/resources/org/glassfish/jersey/jetty/connector/localization.properties
index 128d40b..6561153 100644
--- a/connectors/jetty-connector/src/main/resources/org/glassfish/jersey/jetty/connector/localization.properties
+++ b/connectors/jetty-connector/src/main/resources/org/glassfish/jersey/jetty/connector/localization.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
 #
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,4 +18,4 @@
 method.not.supported=Method {0} not supported.
 invalid.configurable.component.type=The supplied component "{0}" is not assignable from JerseyClient or JerseyWebTarget.
 expected.connector.provider.not.used=The supplied component is not configured to use a JettyConnectorProvider.
-not.supported=Jetty connector is not supported on JDK version less than 11.
+not.supported=Jetty connector is not supported on JDK version less than 17.
diff --git a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/AuthTest.java b/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/AuthTest.java
index f0bfb60..16f1b55 100644
--- a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/AuthTest.java
+++ b/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/AuthTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -33,12 +33,12 @@
 
 import jakarta.inject.Singleton;
 
+import org.eclipse.jetty.client.BasicAuthentication;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 
-import org.eclipse.jetty.client.util.BasicAuthentication;
 import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
diff --git a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/CookieTest.java b/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/CookieTest.java
index 2a49c00..782cf40 100644
--- a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/CookieTest.java
+++ b/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/CookieTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -95,7 +95,7 @@
 
         final JettyConnector connector = (JettyConnector) client.getConfiguration().getConnector();
         if (connector.getCookieStore() != null) {
-            assertTrue(connector.getCookieStore().getCookies().isEmpty());
+            assertTrue(connector.getCookieStore().all().isEmpty());
         } else {
             assertNull(connector.getCookieStore());
         }
@@ -113,9 +113,9 @@
         assertEquals("value", r.request().get(String.class));
 
         final JettyConnector connector = (JettyConnector) client.getConfiguration().getConnector();
-        assertNotNull(connector.getCookieStore().getCookies());
-        assertEquals(1, connector.getCookieStore().getCookies().size());
-        assertEquals("value", connector.getCookieStore().getCookies().get(0).getValue());
+        assertNotNull(connector.getCookieStore().all());
+        assertEquals(1, connector.getCookieStore().all().size());
+        assertEquals("value", connector.getCookieStore().all().get(0).getValue());
         client.close();
     }
 }
diff --git a/connectors/jetty-http2-connector/pom.xml b/connectors/jetty-http2-connector/pom.xml
deleted file mode 100644
index 2142f7e..0000000
--- a/connectors/jetty-http2-connector/pom.xml
+++ /dev/null
@@ -1,302 +0,0 @@
-<?xml version="1.0"?>
-<!--
-
-    Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
-
-    This program and the accompanying materials are made available under the
-    terms of the Eclipse Public License v. 2.0, which is available at
-    http://www.eclipse.org/legal/epl-2.0.
-
-    This Source Code may also be made available under the following Secondary
-    Licenses when the conditions for such availability set forth in the
-    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
-    version 2 with the GNU Classpath Exception, which is available at
-    https://www.gnu.org/software/classpath/license.html.
-
-    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
-
--->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.glassfish.jersey.connectors</groupId>
-        <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>jersey-jetty-http2-connector</artifactId>
-    <packaging>jar</packaging>
-    <name>jersey-connectors-jetty-http2</name>
-
-    <description>Jersey Client Transport via Jetty</description>
-
-    <properties>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <java8.build.outputDirectory>${project.basedir}/target</java8.build.outputDirectory>
-        <java8.sourceDirectory>${project.basedir}/src/main/java8</java8.sourceDirectory>
-        <java11.build.outputDirectory>${project.basedir}/target11</java11.build.outputDirectory>
-        <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty.http2</groupId>
-            <artifactId>http2-client</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty.http2</groupId>
-            <artifactId>http2-http-client-transport</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-util</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.connectors</groupId>
-            <artifactId>jersey-jetty-connector</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.media</groupId>
-            <artifactId>jersey-media-jaxb</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.containers</groupId>
-            <artifactId>jersey-container-jetty-http2</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.glassfish.jersey.media</groupId>
-            <artifactId>jersey-media-json-jackson</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
-            <artifactId>jersey-test-framework-provider-jetty-http2</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>com.sun.istack</groupId>
-                <artifactId>istack-commons-maven-plugin</artifactId>
-                <inherited>true</inherited>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>build-helper-maven-plugin</artifactId>
-                <inherited>true</inherited>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <inherited>true</inherited>
-                <configuration>
-                    <instructions>
-                        <Import-Package>
-                            ${jetty.osgi.version},
-                            *
-                        </Import-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>com.sun.xml.bind</groupId>
-                    <artifactId>jaxb-osgi</artifactId>
-                    <scope>test</scope>
-                </dependency>
-            </dependencies>
-        </profile>
-        <profile>
-            <id>JettyExclude</id>
-            <activation>
-                <jdk>1.8</jdk>
-            </activation>
-            <properties>
-                <jetty.version>${jetty9.version}</jetty.version>
-            </properties>
-            <dependencies>
-                <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-client</artifactId>
-                    <version>${jetty.version}</version>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-                <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-util</artifactId>
-                    <version>${jetty.version}</version>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-            </dependencies>
-            <build>
-                <directory>${java8.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java8.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <configuration>
-                            <testExcludes>
-                                <testExclude>org/glassfish/jersey/jetty/http2/connector/*.java</testExclude>
-                            </testExcludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>Jetty11</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <build>
-                <directory>${java11.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java11.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>copyJDK11FilesToMultiReleaseJar</id>
-            <activation>
-                <file>
-                    <!-- ${java11.build.outputDirectory} does not work here -->
-                    <exists>target11/classes/org/glassfish/jersey/jetty/connector/JettyHttp2ConnectorProvider.class</exists>
-                </file>
-                <jdk>1.8</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.felix</groupId>
-                        <artifactId>maven-bundle-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <extensions>true</extensions>
-                        <configuration>
-                            <instructions>
-                                <Multi-Release>true</Multi-Release>
-                            </instructions>
-                        </configuration>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-resources-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <executions>
-                            <execution>
-                                <id>copy-jdk11-classes</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${java8.build.outputDirectory}/classes/META-INF/versions/11</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>${java11.build.outputDirectory}/classes</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-antrun-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <id>copy-jdk11-sources</id>
-                                <phase>package</phase>
-                                <configuration>
-                                    <target>
-                                        <property name="sources-jar" value="${java8.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
-                                        <echo>sources-jar: ${sources-jar}</echo>
-                                        <zip destfile="${sources-jar}" update="true">
-                                            <zipfileset dir="${java11.sourceDirectory}" prefix="META-INF/versions/11"/>
-                                        </zip>
-                                    </target>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-</project>
\ No newline at end of file
diff --git a/connectors/jetty-http2-connector/src/main/java8/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ClientSupplier.java b/connectors/jetty-http2-connector/src/main/java8/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ClientSupplier.java
deleted file mode 100644
index 6275727..0000000
--- a/connectors/jetty-http2-connector/src/main/java8/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ClientSupplier.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.jetty.http2.connector;
-
-import jakarta.ws.rs.ProcessingException;
-import org.eclipse.jetty.client.HttpClient;
-import org.glassfish.jersey.internal.util.JdkVersion;
-import org.glassfish.jersey.jetty.connector.JettyHttpClientContract;
-import org.glassfish.jersey.jetty.connector.JettyHttpClientSupplier;
-import org.glassfish.jersey.jetty.connector.LocalizationMessages;
-
-/**
- * HTTP/2 enabled version of the {@link JettyHttpClientSupplier}
- *
- * @since 2.41
- */
-public class JettyHttp2ClientSupplier implements JettyHttpClientContract {
-    private final HttpClient http2Client;
-
-    /**
-     * default Http2Client created for the supplier.
-     */
-    public JettyHttp2ClientSupplier() {
-        this(createHttp2Client());
-    }
-    /**
-     * supplier for the {@code HttpClient} with {@code HttpClientTransportOverHTTP2} to be optionally registered
-     * to a {@link org.glassfish.jersey.client.ClientConfig}
-     * @param http2Client seed doc for JDK 11+.
-     */
-    public JettyHttp2ClientSupplier(HttpClient http2Client) {
-        this.http2Client = http2Client;
-    }
-
-    private static final HttpClient createHttp2Client() {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
-            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-        }
-        return null; // does not work at JDK 1.8
-    }
-
-    @Override
-    public HttpClient getHttpClient() {
-        return http2Client;
-    }
-}
\ No newline at end of file
diff --git a/connectors/jetty-http2-connector/src/main/java8/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ConnectorProvider.java b/connectors/jetty-http2-connector/src/main/java8/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ConnectorProvider.java
deleted file mode 100644
index 74e5670..0000000
--- a/connectors/jetty-http2-connector/src/main/java8/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ConnectorProvider.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.jetty.http2.connector;
-
-import jakarta.ws.rs.ProcessingException;
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.core.Configuration;
-import org.glassfish.jersey.client.spi.Connector;
-import org.glassfish.jersey.internal.util.JdkVersion;
-import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
-import org.glassfish.jersey.jetty.connector.LocalizationMessages;
-
-/**
- * Provides HTTP2 enabled version of the {@link JettyConnectorProvider} for a client
- *
- * @since 2.41
- */
-public class JettyHttp2ConnectorProvider extends JettyConnectorProvider {
-    @Override
-    public Connector getConnector(Client client, Configuration runtimeConfig) {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
-            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-        }
-        return null; // does not work at JDK 1.8
-    }
-}
\ No newline at end of file
diff --git a/connectors/jetty11-connector/pom.xml b/connectors/jetty11-connector/pom.xml
new file mode 100644
index 0000000..8862fb8
--- /dev/null
+++ b/connectors/jetty11-connector/pom.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0"?>
+<!--
+
+    Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <artifactId>project</artifactId>
+        <version>3.1.99-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>jersey-jetty11-connector</artifactId>
+    <packaging>jar</packaging>
+    <name>jersey-connectors-jetty11</name>
+
+    <description>Jersey Client Transport via Jetty 11.x</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency><dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-client</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-util</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-client</artifactId>
+            <version>${jetty11.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>${jetty11.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>${slf4j.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-jaxb</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-grizzly2-http</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-json-jackson</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-osgi</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.sun.istack</groupId>
+                <artifactId>istack-commons-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <inherited>true</inherited>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            ${jetty.osgi.version},
+                            *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ClientProperties.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ClientProperties.java
new file mode 100644
index 0000000..d2d9986
--- /dev/null
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ClientProperties.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.Map;
+
+import org.glassfish.jersey.internal.util.PropertiesClass;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+
+/**
+ * Configuration options specific to the Client API that utilizes {@link Jetty11ConnectorProvider}.
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+@PropertiesClass
+public final class Jetty11ClientProperties {
+
+    /**
+     * Prevents instantiation.
+     */
+    private Jetty11ClientProperties() {
+        throw new AssertionError("No instances allowed.");
+    }
+
+    /**
+     * A value of {@code false} indicates the client should handle cookies
+     * automatically using HttpClient's default cookie policy. A value
+     * of {@code false} will cause the client to ignore all cookies.
+     * <p/>
+     * The value MUST be an instance of {@link Boolean}.
+     * If the property is absent the default value is {@code false}
+     */
+    public static final String DISABLE_COOKIES =
+            "jersey.config.jetty11.client.disableCookies";
+
+    /**
+     * The credential provider that should be used to retrieve
+     * credentials from a user.
+     *
+     * If an {@link org.eclipse.jetty.client.api.Authentication} mechanism is found,
+     * it is then used for the given request, returning an {@link org.eclipse.jetty.client.api.Authentication.Result},
+     * which is then stored in the {@link org.eclipse.jetty.client.api.AuthenticationStore}
+     * so that subsequent requests can be preemptively authenticated.
+
+     * <p/>
+     * The value MUST be an instance of {@link
+     * org.eclipse.jetty.client.util.BasicAuthentication}.  If
+     * the property is absent a default provider will be used.
+     */
+    public static final String PREEMPTIVE_BASIC_AUTHENTICATION =
+            "jersey.config.jetty11.client.preemptiveBasicAuthentication";
+
+    /**
+     * A value of {@code false} indicates the client disable a hostname verification
+     * during SSL Handshake. A client will ignore CN value defined in a certificate
+     * that is stored in a truststore.
+     * <p/>
+     * The value MUST be an instance of {@link Boolean}.
+     * If the property is absent the default value is {@code true}.
+     */
+    public static final String ENABLE_SSL_HOSTNAME_VERIFICATION =
+            "jersey.config.jetty11.client.enableSslHostnameVerification";
+
+    /**
+     * Overrides the default Jetty synchronous listener response max buffer size.
+     * In practise, this allows you to read larger responses.
+     * Size in bytes.
+     * <p/>
+     * If the property is absent, the value is such as specified by Jetty (currently 2MiB).
+     */
+    public static final String SYNC_LISTENER_RESPONSE_MAX_SIZE =
+        "jersey.config.jetty11.client.syncListenerResponseMaxSize";
+
+    /**
+     * Total timeout interval for request/response conversation, in milliseconds.
+     * Opposed to {@link org.glassfish.jersey.client.ClientProperties#READ_TIMEOUT}.
+     * <p>
+     * The value MUST be an instance convertible to {@link Integer}. The
+     * value of zero (0) is equivalent to an interval of infinity.
+     * </p>
+     * <p>
+     * The default value is zero (infinity).
+     * </p>
+     * <p>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     * </p>
+     *
+     * @since 2.37
+     */
+    public static final String TOTAL_TIMEOUT = "jersey.config.jetty11.client.totalTimeout";
+
+    /**
+     * Get the value of the specified property.
+     *
+     * If the property is not set or the real value type is not compatible with the specified value type, returns {@code null}.
+     *
+     * @param properties  Map of properties to get the property value from.
+     * @param key         Name of the property.
+     * @param type        Type to retrieve the value as.
+     * @param <T>         Type of the property value.
+     * @return Value of the property or {@code null}.
+     *
+     * @since 2.8
+     */
+    public static <T> T getValue(final Map<String, ?> properties, final String key, final Class<T> type) {
+        return PropertiesHelper.getValue(properties, key, type, null);
+    }
+
+}
diff --git a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11Connector.java
similarity index 91%
rename from connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java
rename to connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11Connector.java
index d85ec4d..beb723d 100644
--- a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11Connector.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.connector;
+package org.glassfish.jersey.jetty11.connector;
 
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Client;
@@ -93,10 +93,10 @@
  * <li>{@link ClientProperties#PROXY_USERNAME}</li>
  * <li>{@link ClientProperties#PROXY_PASSWORD}</li>
  * <li>{@link ClientProperties#PROXY_PASSWORD}</li>
- * <li>{@link JettyClientProperties#DISABLE_COOKIES}</li>*
- * <li>{@link JettyClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
- * <li>{@link JettyClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
- * <li>{@link JettyClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
+ * <li>{@link Jetty11ClientProperties#DISABLE_COOKIES}</li>*
+ * <li>{@link Jetty11ClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
+ * <li>{@link Jetty11ClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
+ * <li>{@link Jetty11ClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
  * </ul>
  * <p/>
  * This transport supports both synchronous and asynchronous processing of client requests.
@@ -107,7 +107,7 @@
  * <pre>
  * {@code
  * ClientConfig config = new ClientConfig();
- * Connector connector = new JettyConnector(config);
+ * Connector connector = new Jetty11Connector(config);
  * config.connector(connector);
  * Client client = ClientBuilder.newClient(config);
  *
@@ -129,9 +129,9 @@
  * @author Arul Dhesiaseelan (aruld at acm.org)
  * @author Marek Potociar
  */
-public class JettyConnector implements Connector {
+public class Jetty11Connector implements Connector {
 
-    private static final Logger LOGGER = Logger.getLogger(JettyConnector.class.getName());
+    private static final Logger LOGGER = Logger.getLogger(Jetty11Connector.class.getName());
 
     private final HttpClient client;
     private final CookieStore cookieStore;
@@ -144,7 +144,7 @@
      * @param jaxrsClient JAX-RS client instance, for which the connector is created.
      * @param config client configuration.
      */
-    protected JettyConnector(final Client jaxrsClient, final Configuration config) {
+    protected Jetty11Connector(final Client jaxrsClient, final Configuration config) {
         this.configuration = config;
         HttpClient httpClient = getRegisteredHttpClient(config);
 
@@ -160,7 +160,7 @@
         this.client = httpClient;
 
         Boolean enableHostnameVerification = (Boolean) config.getProperties()
-                .get(JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION);
+                .get(Jetty11ClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION);
         if (enableHostnameVerification != null) {
             final String verificationAlgorithm = enableHostnameVerification ? "HTTPS" : null;
             client.getSslContextFactory().setEndpointIdentificationAlgorithm(verificationAlgorithm);
@@ -180,11 +180,11 @@
             threadPool.setName(name);
             client.setExecutor(threadPool);
         }
-        Boolean disableCookies = (Boolean) config.getProperties().get(JettyClientProperties.DISABLE_COOKIES);
+        Boolean disableCookies = (Boolean) config.getProperties().get(Jetty11ClientProperties.DISABLE_COOKIES);
         disableCookies = (disableCookies != null) ? disableCookies : false;
 
         final AuthenticationStore auth = client.getAuthenticationStore();
-        final Object basicAuthProvider = config.getProperty(JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION);
+        final Object basicAuthProvider = config.getProperty(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION);
         if (basicAuthProvider != null && (basicAuthProvider instanceof BasicAuthentication)) {
             auth.addAuthentication((BasicAuthentication) basicAuthProvider);
         }
@@ -206,9 +206,9 @@
         }
 
         final Object slResponseMaxSize = configuration.getProperties()
-            .get(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE);
+                .get(Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE);
         if (slResponseMaxSize != null && slResponseMaxSize instanceof Integer
-            && (Integer) slResponseMaxSize > 0) {
+                && (Integer) slResponseMaxSize > 0) {
             this.syncListenerResponseMaxSize = Optional.of((Integer) slResponseMaxSize);
         }
         else {
@@ -244,11 +244,11 @@
      * @since 2.41
      */
     protected HttpClient getRegisteredHttpClient(Configuration config) {
-        if (config.isRegistered(JettyHttpClientSupplier.class)) {
+        if (config.isRegistered(Jetty11HttpClientSupplier.class)) {
             Optional<Object> contract = config.getInstances().stream()
-                    .filter(a-> JettyHttpClientSupplier.class.isInstance(a)).findFirst();
+                    .filter(a-> Jetty11HttpClientSupplier.class.isInstance(a)).findFirst();
             if (contract.isPresent()) {
-                return  ((JettyHttpClientSupplier) contract.get()).getHttpClient();
+                return  ((Jetty11HttpClientSupplier) contract.get()).getHttpClient();
             }
         }
         return null;
@@ -268,7 +268,7 @@
      * Get the {@link CookieStore}.
      *
      * @return the {@link CookieStore} instance or null when
-     * JettyClientProperties.DISABLE_COOKIES set to true.
+     * Jetty11ClientProperties.DISABLE_COOKIES set to true.
      */
     public CookieStore getCookieStore() {
         return cookieStore;
@@ -293,12 +293,12 @@
             }
             else {
                 final FutureResponseListener listener
-                    = new FutureResponseListener(jettyRequest, syncListenerResponseMaxSize.get());
+                        = new FutureResponseListener(jettyRequest, syncListenerResponseMaxSize.get());
                 jettyRequest.send(listener);
                 jettyResponse = listener.get();
             }
             HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, jerseyRequest.getHeaders(),
-                                           JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
+                    Jetty11Connector.this.getClass().getName(), jerseyRequest.getConfiguration());
 
             final jakarta.ws.rs.core.Response.StatusType status = jettyResponse.getReason() == null
                     ? Statuses.from(jettyResponse.getStatus())
@@ -354,7 +354,7 @@
             request.idleTimeout((Integer) readTimeout, TimeUnit.MILLISECONDS);
         }
 
-        final Object totalTimeout = clientRequest.resolveProperty(JettyClientProperties.TOTAL_TIMEOUT, -1);
+        final Object totalTimeout = clientRequest.resolveProperty(Jetty11ClientProperties.TOTAL_TIMEOUT, -1);
         if (totalTimeout != null && totalTimeout instanceof Integer && (Integer) totalTimeout > 0) {
             request.timeout((Integer) totalTimeout, TimeUnit.MILLISECONDS);
         }
@@ -444,13 +444,13 @@
         try {
             final CompletableFuture<ClientResponse> responseFuture = new CompletableFuture<ClientResponse>();
             responseFuture.whenComplete(
-                            (clientResponse, throwable) -> {
-                                if (throwable != null && throwable instanceof CancellationException) {
-                                    // take care of future cancellation
-                                    jettyRequest.abort(throwable);
+                    (clientResponse, throwable) -> {
+                        if (throwable != null && throwable instanceof CancellationException) {
+                            // take care of future cancellation
+                            jettyRequest.abort(throwable);
 
-                                }
-                            });
+                        }
+                    });
 
             final AtomicReference<ClientResponse> jerseyResponse = new AtomicReference<>();
             final ByteBufferInputStream entityStream = new ByteBufferInputStream();
@@ -459,7 +459,7 @@
                 @Override
                 public void onHeaders(final Response jettyResponse) {
                     HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, jerseyRequest.getHeaders(),
-                                                   JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
+                            Jetty11Connector.this.getClass().getName(), jerseyRequest.getConfiguration());
 
                     if (responseFuture.isDone()) {
                         if (!callbackInvoked.compareAndSet(false, true)) {
@@ -549,4 +549,4 @@
             throw new ProcessingException("Failed to stop the client.", e);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ConnectorProvider.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ConnectorProvider.java
new file mode 100644
index 0000000..de6bc77
--- /dev/null
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ConnectorProvider.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+
+import org.glassfish.jersey.client.Initializable;
+import org.glassfish.jersey.client.spi.Connector;
+import org.glassfish.jersey.client.spi.ConnectorProvider;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.glassfish.jersey.internal.util.JdkVersion;
+
+/**
+ * A {@link ConnectorProvider} for Jersey {@link Connector connector}
+ * instances that utilize the Jetty HTTP Client to send and receive
+ * HTTP request and responses.
+ * <p>
+ * The following connector configuration properties are supported:
+ * <ul>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#ASYNC_THREADPOOL_SIZE}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#CONNECT_TIMEOUT}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#FOLLOW_REDIRECTS}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_URI}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
+ * <li>{@link Jetty11ClientProperties#DISABLE_COOKIES}</li>*
+ * <li>{@link Jetty11ClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
+ * <li>{@link Jetty11ClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
+ * <li>{@link Jetty11ClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
+ * </ul>
+ * </p>
+ * <p>
+ * This transport supports both synchronous and asynchronous processing of client requests.
+ * The following methods are supported: GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT and MOVE.
+ * </p>
+ * <p>
+ * Typical usage:
+ * </p>
+ * <pre>
+ * {@code
+ * ClientConfig config = new ClientConfig();
+ * config.connectorProvider(new JettyConnectorProvider());
+ * Client client = ClientBuilder.newClient(config);
+ *
+ * // async request
+ * WebTarget target = client.target("http://localhost:8080");
+ * Future<Response> future = target.path("resource").request().async().get();
+ *
+ * // wait for 3 seconds
+ * Response response = future.get(3, TimeUnit.SECONDS);
+ * String entity = response.readEntity(String.class);
+ * client.close();
+ * }
+ * </pre>
+ * <p>
+ * Connector instances created via Jetty HTTP Client-based connector provider support only
+ * {@link org.glassfish.jersey.client.RequestEntityProcessing#BUFFERED entity buffering}.
+ * Defining the property {@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING} has no
+ * effect on Jetty HTTP Client-based connectors.
+ * </p>
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Marek Potociar
+ * @since 2.5
+ */
+public class Jetty11ConnectorProvider implements ConnectorProvider {
+
+    @Override
+    public Connector getConnector(Client client, Configuration runtimeConfig) {
+        if (JdkVersion.getJdkVersion().getMajor() < 11) {
+            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+        }
+        return new Jetty11Connector(client, runtimeConfig);
+    }
+
+    /**
+     * Retrieve the underlying Jetty {@link HttpClient} instance from
+     * {@link org.glassfish.jersey.client.JerseyClient} or {@link org.glassfish.jersey.client.JerseyWebTarget}
+     * configured to use {@code JettyConnectorProvider}.
+     *
+     * @param component {@code JerseyClient} or {@code JerseyWebTarget} instance that is configured to use
+     *                  {@code JettyConnectorProvider}.
+     * @return underlying Jetty {@code HttpClient} instance.
+     *
+     * @throws IllegalArgumentException in case the {@code component} is neither {@code JerseyClient}
+     *                                            nor {@code JerseyWebTarget} instance or in case the component
+     *                                            is not configured to use a {@code JettyConnectorProvider}.
+     * @since 2.8
+     */
+    public static HttpClient getHttpClient(Configurable<?> component) {
+        if (!(component instanceof Initializable)) {
+            throw new IllegalArgumentException(
+                    LocalizationMessages.INVALID_CONFIGURABLE_COMPONENT_TYPE(component.getClass().getName()));
+        }
+
+        final Initializable<?> initializable = (Initializable<?>) component;
+        Connector connector = initializable.getConfiguration().getConnector();
+        if (connector == null) {
+            initializable.preInitialize();
+            connector = initializable.getConfiguration().getConnector();
+        }
+
+        if (connector instanceof Jetty11Connector) {
+            return ((Jetty11Connector) connector).getHttpClient();
+        }
+
+        throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED());
+    }
+}
diff --git a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientContract.java
similarity index 81%
copy from connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
copy to connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientContract.java
index b061ef5..3b0321d 100644
--- a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientContract.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,17 +14,17 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.connector;
+package org.glassfish.jersey.jetty11.connector;
 
 import org.eclipse.jetty.client.HttpClient;
 import org.glassfish.jersey.spi.Contract;
 
 /**
  * A contract that allows for an optional registration of user predefined Jetty {@code HttpClient}
- * that is consequently used by {@link JettyConnector}
+ * that is consequently used by {@link Jetty11Connector}
  */
 @Contract
-public interface JettyHttpClientContract {
+public interface Jetty11HttpClientContract {
     /**
      * Supply a user predefined HttpClient
      * @return a user predefined HttpClient
diff --git a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientSupplier.java
similarity index 71%
copy from connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
copy to connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientSupplier.java
index 59c8fd3..b5f1462 100644
--- a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientSupplier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -13,14 +13,12 @@
  *
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
-package org.glassfish.jersey.jetty.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import jakarta.ws.rs.ProcessingException;
 import org.eclipse.jetty.client.HttpClient;
-import org.glassfish.jersey.internal.util.JdkVersion;
 
 /**
- * Jetty HttpClient supplier to be registered into Jersey configuration to be used by {@link JettyConnector}.
+ * Jetty HttpClient supplier to be registered into Jersey configuration to be used by {@link Jetty11Connector}.
  * Not every possible configuration option is covered by the Jetty Connector and this supplier offers a way to provide
  * an HttpClient that has configured the options not covered by the Jetty Connector.
  * <p>
@@ -37,25 +35,22 @@
  * }
  * </pre>
  * <p>
- *     The {@code HttpClient} is configured as if it was created by {@link JettyConnector} the usual way.
+ *     The {@code HttpClient} is configured as if it was created by {@link Jetty11Connector} the usual way.
  * </p>
  */
-public class JettyHttpClientSupplier implements JettyHttpClientContract {
+public class Jetty11HttpClientSupplier implements Jetty11HttpClientContract {
     private final HttpClient httpClient;
 
     /**
      * {@code HttpClient} supplier to be optionally registered to a {@link org.glassfish.jersey.client.ClientConfig}
-     * @param httpClient a HttpClient to be supplied when {@link JettyConnector#getHttpClient()} is called.
+     * @param httpClient a HttpClient to be supplied when {@link Jetty11Connector#getHttpClient()} is called.
      */
-    public JettyHttpClientSupplier(HttpClient httpClient) {
+    public Jetty11HttpClientSupplier(HttpClient httpClient) {
         this.httpClient = httpClient;
     }
 
     @Override
     public HttpClient getHttpClient() {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
-            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-        }
-        return null; // does not work at JDK 1.8
+        return httpClient;
     }
 }
diff --git a/connectors/jetty-http2-connector/src/main/java/org/glassfish/jersey/jetty/http2/connector/package-info.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/package-info.java
similarity index 82%
copy from connectors/jetty-http2-connector/src/main/java/org/glassfish/jersey/jetty/http2/connector/package-info.java
copy to connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/package-info.java
index 960bbb6..0f85c4f 100644
--- a/connectors/jetty-http2-connector/src/main/java/org/glassfish/jersey/jetty/http2/connector/package-info.java
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/package-info.java
@@ -15,7 +15,7 @@
  */
 
 /**
- * Jersey HTTP2 client {@link org.glassfish.jersey.client.spi.Connector connector} based on the
+ * Jersey client {@link org.glassfish.jersey.client.spi.Connector connector} based on the
  * Jetty Client.
  */
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
diff --git a/connectors/jetty-http2-connector/src/main/resources/org.glassfish.jersey.jetty.http2.connector/localization.properties b/connectors/jetty11-connector/src/main/resources/org/glassfish/jersey/jetty11/connector/localization.properties
similarity index 100%
rename from connectors/jetty-http2-connector/src/main/resources/org.glassfish.jersey.jetty.http2.connector/localization.properties
rename to connectors/jetty11-connector/src/main/resources/org/glassfish/jersey/jetty11/connector/localization.properties
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AsyncTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AsyncTest.java
similarity index 95%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AsyncTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AsyncTest.java
index 76ef67b..9d0edbc 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AsyncTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AsyncTest.java
@@ -14,14 +14,11 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.hamcrest.Matchers;
-import org.junit.jupiter.api.Test;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.POST;
@@ -32,13 +29,23 @@
 import jakarta.ws.rs.container.TimeoutHandler;
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.Response;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
 
-import static org.hamcrest.MatcherAssert.assertThat;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.hamcrest.MatcherAssert.assertThat;
 
+/**
+ * Asynchronous connector test.
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Marek Potociar
+ */
 public class AsyncTest extends JerseyTest {
     private static final Logger LOGGER = Logger.getLogger(AsyncTest.class.getName());
     private static final String PATH = "async";
@@ -140,8 +147,9 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
+        // TODO: fails with true on request - should be fixed by resolving JERSEY-2273
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.HEADERS_ONLY));
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     /**
@@ -190,4 +198,4 @@
         assertEquals(503, response.getStatus());
         assertEquals("Operation time out.", response.readEntity(String.class));
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthFilterTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthFilterTest.java
similarity index 92%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthFilterTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthFilterTest.java
index 5daad2d..1c6cddc 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthFilterTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthFilterTest.java
@@ -14,22 +14,27 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
+
 import org.junit.jupiter.api.Test;
-
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.core.Application;
-import jakarta.ws.rs.core.Response;
-import java.util.logging.Logger;
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
 public class AuthFilterTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(AuthFilterTest.class.getName());
@@ -44,7 +49,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     @Test
@@ -69,4 +74,4 @@
         assertEquals(204, response.getStatus());
     }
 
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthTest.java
similarity index 91%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthTest.java
rename to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthTest.java
index 7fe2edf..6b5111b 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthTest.java
@@ -14,17 +14,10 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.eclipse.jetty.client.util.BasicAuthentication;
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.jetty.connector.JettyClientProperties;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.util.logging.Logger;
 
-import jakarta.inject.Singleton;
 import jakarta.ws.rs.DELETE;
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.POST;
@@ -37,11 +30,23 @@
 import jakarta.ws.rs.core.Context;
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.Response;
-import java.util.logging.Logger;
 
+import jakarta.inject.Singleton;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.eclipse.jetty.client.util.BasicAuthentication;
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
 public class AuthTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(AuthTest.class.getName());
@@ -153,9 +158,9 @@
     @Test
     public void testAuthGet() {
         ClientConfig config = new ClientConfig();
-        config.property(JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+        config.property(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
                 new BasicAuthentication(getBaseUri(), "WallyWorld", "name", "password"));
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
 
         Response response = client.target(getBaseUri()).path(PATH).request().get();
@@ -166,9 +171,9 @@
     @Test
     public void testAuthPost() {
         ClientConfig config = new ClientConfig();
-        config.property(JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+        config.property(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
                 new BasicAuthentication(getBaseUri(), "WallyWorld", "name", "password"));
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
 
         Response response = client.target(getBaseUri()).path(PATH).request().post(Entity.text("POST"));
@@ -179,9 +184,9 @@
     @Test
     public void testAuthDelete() {
         ClientConfig config = new ClientConfig();
-        config.property(JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+        config.property(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
                 new BasicAuthentication(getBaseUri(), "WallyWorld", "name", "password"));
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
 
         Response response = client.target(getBaseUri()).path(PATH).request().delete();
@@ -189,4 +194,4 @@
         client.close();
     }
 
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CookieTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CookieTest.java
similarity index 86%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CookieTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CookieTest.java
index eb1c653..0cd585e 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CookieTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CookieTest.java
@@ -14,16 +14,9 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.JerseyClient;
-import org.glassfish.jersey.client.JerseyClientBuilder;
-import org.glassfish.jersey.jetty.connector.JettyClientProperties;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
@@ -36,13 +29,24 @@
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.NewCookie;
 import jakarta.ws.rs.core.Response;
-import java.util.logging.Logger;
 
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.JerseyClient;
+import org.glassfish.jersey.client.JerseyClientBuilder;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
 public class CookieTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(CookieTest.class.getName());
@@ -68,7 +72,7 @@
     @Test
     public void testCookieResource() {
         ClientConfig config = new ClientConfig();
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
         WebTarget r = client.target(getBaseUri());
 
@@ -81,15 +85,15 @@
     @Test
     public void testDisabledCookies() {
         ClientConfig cc = new ClientConfig();
-        cc.property(JettyClientProperties.DISABLE_COOKIES, true);
-        cc.connectorProvider(new JettyHttp2ConnectorProvider());
+        cc.property(Jetty11ClientProperties.DISABLE_COOKIES, true);
+        cc.connectorProvider(new Jetty11ConnectorProvider());
         JerseyClient client = JerseyClientBuilder.createClient(cc);
         WebTarget r = client.target(getBaseUri());
 
         assertEquals("NO-COOKIE", r.request().get(String.class));
         assertEquals("NO-COOKIE", r.request().get(String.class));
 
-        final JettyHttp2Connector connector = (JettyHttp2Connector) client.getConfiguration().getConnector();
+        final Jetty11Connector connector = (Jetty11Connector) client.getConfiguration().getConnector();
         if (connector.getCookieStore() != null) {
             assertTrue(connector.getCookieStore().getCookies().isEmpty());
         } else {
@@ -101,17 +105,17 @@
     @Test
     public void testCookies() {
         ClientConfig cc = new ClientConfig();
-        cc.connectorProvider(new JettyHttp2ConnectorProvider());
+        cc.connectorProvider(new Jetty11ConnectorProvider());
         JerseyClient client = JerseyClientBuilder.createClient(cc);
         WebTarget r = client.target(getBaseUri());
 
         assertEquals("NO-COOKIE", r.request().get(String.class));
         assertEquals("value", r.request().get(String.class));
 
-        final JettyHttp2Connector connector = (JettyHttp2Connector) client.getConfiguration().getConnector();
+        final Jetty11Connector connector = (Jetty11Connector) client.getConfiguration().getConnector();
         assertNotNull(connector.getCookieStore().getCookies());
         assertEquals(1, connector.getCookieStore().getCookies().size());
         assertEquals("value", connector.getCookieStore().getCookies().get(0).getValue());
         client.close();
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CustomLoggingFilter.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CustomLoggingFilter.java
similarity index 93%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CustomLoggingFilter.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CustomLoggingFilter.java
index 369169a..386f96e 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CustomLoggingFilter.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CustomLoggingFilter.java
@@ -14,7 +14,9 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
+
+import java.io.IOException;
 
 import jakarta.ws.rs.client.ClientRequestContext;
 import jakarta.ws.rs.client.ClientRequestFilter;
@@ -24,10 +26,14 @@
 import jakarta.ws.rs.container.ContainerRequestFilter;
 import jakarta.ws.rs.container.ContainerResponseContext;
 import jakarta.ws.rs.container.ContainerResponseFilter;
-import java.io.IOException;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+/**
+ * Custom logging filter.
+ *
+ * @author Santiago Pericas-Geertsen (santiago.pericasgeertsen at oracle.com)
+ */
 public class CustomLoggingFilter implements ContainerRequestFilter, ContainerResponseFilter,
         ClientRequestFilter, ClientResponseFilter {
 
@@ -61,4 +67,4 @@
         assertEquals("bar", context.getProperty("foo"));
         postFilterCalled++;
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/EntityTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/EntityTest.java
similarity index 92%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/EntityTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/EntityTest.java
index 0f508ca..e9de353 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/EntityTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/EntityTest.java
@@ -14,14 +14,11 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.jackson.JacksonFeature;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.POST;
@@ -30,13 +27,23 @@
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
-import jakarta.xml.bind.annotation.XmlRootElement;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-import java.util.logging.Logger;
 
+import jakarta.xml.bind.annotation.XmlRootElement;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+// import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+/**
+ * Tests the Http content negotiation.
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
 public class EntityTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(EntityTest.class.getName());
@@ -96,15 +103,15 @@
 
     @Override
     protected Application configure() {
-        ResourceConfig config = new ResourceConfig(EntityResource.class, JacksonFeature.class);
+        ResourceConfig config = new ResourceConfig(EntityResource.class/*, JacksonFeature.class*/);
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
         return config;
     }
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider())
-                .register(JacksonFeature.class);
+        config.connectorProvider(new Jetty11ConnectorProvider());
+                //.register(/*JacksonFeature.class*/);
     }
 
     @Test
@@ -148,4 +155,4 @@
         person = response.readEntity(Person.class);
         assertEquals("John Doe", person.toString());
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ErrorTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ErrorTest.java
similarity index 94%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ErrorTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ErrorTest.java
index 64d8198..a8a97e5 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ErrorTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ErrorTest.java
@@ -14,13 +14,9 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.ClientErrorException;
 import jakarta.ws.rs.POST;
@@ -29,10 +25,19 @@
 import jakarta.ws.rs.client.WebTarget;
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.Response;
-import java.util.logging.Logger;
 
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
 public class ErrorTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(ErrorTest.class.getName());
@@ -47,7 +52,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
 
@@ -116,4 +121,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/FollowRedirectsTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/FollowRedirectsTest.java
similarity index 87%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/FollowRedirectsTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/FollowRedirectsTest.java
index 2604f9b..a30efbc 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/FollowRedirectsTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/FollowRedirectsTest.java
@@ -14,15 +14,11 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.client.ClientResponse;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.io.IOException;
+import java.net.URI;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
@@ -35,12 +31,24 @@
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.UriBuilder;
-import java.io.IOException;
-import java.net.URI;
-import java.util.logging.Logger;
 
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientResponse;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+/**
+ * Jetty connector follow redirect tests.
+ *
+ * @author Martin Matula
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Marek Potociar
+ */
 public class FollowRedirectsTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(FollowRedirectsTest.class.getName());
@@ -69,7 +77,7 @@
     @Override
     protected void configureClient(ClientConfig config) {
         config.property(ClientProperties.FOLLOW_REDIRECTS, false);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     private static class RedirectTestFilter implements ClientResponseFilter {
@@ -88,7 +96,7 @@
     public void testDoFollow() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
         Response r = t.path("test/redirect")
@@ -96,6 +104,11 @@
                 .request().get();
         assertEquals(200, r.getStatus());
         assertEquals("GET", r.readEntity(String.class));
+// TODO uncomment as part of JERSEY-2388 fix.
+//        assertEquals(
+//                UriBuilder.fromUri(getBaseUri()).path(RedirectResource.class).build().toString(),
+//                r.getHeaderString(RedirectTestFilter.RESOLVED_URI_HEADER));
+
         c.close();
     }
 
@@ -118,7 +131,7 @@
     public void testDontFollowPerRequestOverride() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
         WebTarget t = client.target(u);
         t.property(ClientProperties.FOLLOW_REDIRECTS, false);
@@ -126,4 +139,4 @@
         assertEquals(303, r.getStatus());
         client.close();
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/GZIPContentEncodingTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/GZIPContentEncodingTest.java
similarity index 92%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/GZIPContentEncodingTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/GZIPContentEncodingTest.java
index 29bb444..459eccb 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/GZIPContentEncodingTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/GZIPContentEncodingTest.java
@@ -14,15 +14,10 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.message.GZipEncoder;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.util.Arrays;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.POST;
 import jakarta.ws.rs.Path;
@@ -33,11 +28,21 @@
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
-import java.util.Arrays;
-import java.util.logging.Logger;
 
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.message.GZipEncoder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
 public class GZIPContentEncodingTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(EntityTest.class.getName());
@@ -61,7 +66,7 @@
     @Override
     protected void configureClient(ClientConfig config) {
         config.register(GZipEncoder.class);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     @Test
@@ -80,7 +85,7 @@
     public void testPostChunked() {
         ClientConfig config = new ClientConfig();
         config.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
 
         Client client = ClientBuilder.newClient(config);
@@ -97,4 +102,4 @@
         client.close();
     }
 
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HelloWorldTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HelloWorldTest.java
similarity index 97%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HelloWorldTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HelloWorldTest.java
index ac6870a..a60719b 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HelloWorldTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HelloWorldTest.java
@@ -14,13 +14,11 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
@@ -32,13 +30,20 @@
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
 
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+/**
+ *
+ * @author Jakub Podlesak
+ */
 public class HelloWorldTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(HelloWorldTest.class.getName());
@@ -65,7 +70,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     @Test
@@ -217,4 +222,4 @@
         client.close();
     }
 
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HttpHeadersTest.java
similarity index 94%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HttpHeadersTest.java
index cb3b319..3d03872 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HttpHeadersTest.java
@@ -14,13 +14,10 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.util.List;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.HeaderParam;
@@ -30,12 +27,23 @@
 import jakarta.ws.rs.core.Context;
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.Response;
-import java.util.List;
-import java.util.logging.Logger;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+
+/**
+ * Tests the headers.
+ *
+ * @author Stepan Kopriva
+ */
 public class HttpHeadersTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(HttpHeadersTest.class.getName());
@@ -71,7 +79,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     @Test
@@ -90,4 +98,4 @@
         String response = target().path("test").request().get(String.class);
         assertTrue(response.startsWith("Jersey"), "User-agent header should start with 'Jersey', but was " + response);
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ManagedClientTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ManagedClientTest.java
similarity index 97%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ManagedClientTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ManagedClientTest.java
index 215408b..628af89 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ManagedClientTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ManagedClientTest.java
@@ -14,15 +14,15 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ClientBinding;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.Uri;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.io.IOException;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
@@ -38,16 +38,22 @@
 import jakarta.ws.rs.core.FeatureContext;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
-import java.io.IOException;
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.logging.Logger;
 
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ClientBinding;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.Uri;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+/**
+ * Jersey programmatic managed client test
+ *
+ * @author Marek Potociar
+ */
 public class ManagedClientTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(ManagedClientTest.class.getName());
@@ -225,7 +231,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     /**
@@ -247,4 +253,4 @@
         assertEquals("b", response.readEntity(String.class));
     }
 
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/MethodTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/MethodTest.java
similarity index 94%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/MethodTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/MethodTest.java
index 8412c41..f62834b 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/MethodTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/MethodTest.java
@@ -14,13 +14,10 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.DELETE;
 import jakarta.ws.rs.GET;
@@ -32,11 +29,21 @@
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
-import java.util.concurrent.ExecutionException;
-import java.util.logging.Logger;
 
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+/**
+ * Tests the Http methods.
+ *
+ * @author Stepan Kopriva
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
 public class MethodTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(MethodTest.class.getName());
@@ -80,7 +87,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     @Test
@@ -143,4 +150,4 @@
         assertEquals(200, response.getStatus());
         response.close();
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/NoEntityTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/NoEntityTest.java
similarity index 89%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/NoEntityTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/NoEntityTest.java
index 1c14296..f5f754d 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/NoEntityTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/NoEntityTest.java
@@ -14,13 +14,9 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.POST;
@@ -28,8 +24,19 @@
 import jakarta.ws.rs.client.WebTarget;
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.Response;
-import java.util.logging.Logger;
+import jakarta.ws.rs.core.Response.Status;
 
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
 public class NoEntityTest extends JerseyTest {
     private static final Logger LOGGER = Logger.getLogger(NoEntityTest.class.getName());
 
@@ -37,7 +44,7 @@
     public static class HttpMethodResource {
         @GET
         public Response get() {
-            return Response.status(Response.Status.CONFLICT).build();
+            return Response.status(Status.CONFLICT).build();
         }
 
         @POST
@@ -54,7 +61,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     @Test
@@ -92,4 +99,4 @@
             cr.close();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/SyncResponseSizeTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/SyncResponseSizeTest.java
similarity index 82%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/SyncResponseSizeTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/SyncResponseSizeTest.java
index e3b2c3d..be67e9a 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/SyncResponseSizeTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/SyncResponseSizeTest.java
@@ -14,11 +14,10 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.jetty.connector.JettyClientProperties;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
@@ -38,11 +37,22 @@
 import java.util.logging.Logger;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
+/**
+ * Default synchronous jetty client implementation has a hard response size limit of 2MiB.
+ * When response is too big, a processing exception is thrown.
+ * The original code path was left to preserve this behaviour but could be removed
+ * and reworked in the future with a custom listener like async path.
+ *
+ * This tests the previous behavior with large payloads (>2MiB), the new size override (4MiB)
+ * and very big payloads (>4MiB).
+ *
+ * @author cen1 (cen.is.imba at gmail.com)
+ */
 public class SyncResponseSizeTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(SyncResponseSizeTest.class.getName());
@@ -87,7 +97,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     @Test
@@ -101,7 +111,7 @@
     public void testDefaultTooBig() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
 
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
@@ -121,8 +131,8 @@
     public void testCustomBig() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
-        config.property(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
+        config.connectorProvider(new Jetty11ConnectorProvider());
+        config.property(Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
 
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
@@ -132,7 +142,7 @@
             assertEquals(p.length(), maxBufferSize);
         } catch (ProcessingException e) {
             assertThat("Unexpected processing exception cause",
-                    e.getCause(), instanceOf(TimeoutException.class));
+                e.getCause(), instanceOf(TimeoutException.class));
         } finally {
             c.close();
         }
@@ -142,8 +152,8 @@
     public void testCustomTooBig() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
-        config.property(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
+        config.connectorProvider(new Jetty11ConnectorProvider());
+        config.property(Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
 
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
@@ -158,4 +168,4 @@
             c.close();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TimeoutTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TimeoutTest.java
similarity index 89%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TimeoutTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TimeoutTest.java
index 59f242e..3644262 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TimeoutTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TimeoutTest.java
@@ -14,16 +14,13 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.CommonProperties;
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.jetty.connector.JettyClientProperties;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.DefaultValue;
 import jakarta.ws.rs.GET;
@@ -36,18 +33,26 @@
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.StreamingOutput;
-import java.net.URI;
-import java.nio.charset.StandardCharsets;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.logging.Logger;
 
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
 import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.fail;
 
+/**
+ * @author Martin Matula
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
 public class TimeoutTest extends JerseyTest {
     private static final Logger LOGGER = Logger.getLogger(TimeoutTest.class.getName());
 
@@ -78,7 +83,7 @@
         @GET
         @Path("stream")
         public Response streamsWithDelay(@QueryParam("start") @DefaultValue("0") int startMillis, @QueryParam("count") int count,
-                                         @QueryParam("pauseMillis") int pauseMillis) {
+                @QueryParam("pauseMillis") int pauseMillis) {
             StreamingOutput streamingOutput = streamSlowly(startMillis, count, pauseMillis);
 
             return Response.ok(streamingOutput)
@@ -121,7 +126,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
     }
 
     @Test
@@ -135,7 +140,7 @@
     public void testSlow() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
         try {
@@ -153,7 +158,7 @@
     public void testTimeoutInRequest() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig();
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11ConnectorProvider());
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
         try {
@@ -173,6 +178,7 @@
      * @throws ProcessingException in case of a test error.
      */
     @Test
+    @Disabled("Test fails with grizzly2 container") // TODO: evaluate, why this test fails with grizzly2
     public void testSlowlyStreamedContentDoesNotReadTimeout() throws Exception {
 
         int count = 5;
@@ -197,12 +203,12 @@
 
         try {
             target("test")
-                    .property(JettyClientProperties.TOTAL_TIMEOUT, 100L)
-                    .property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER, "-1")
-                    .path("stream")
-                    .queryParam("count", count)
-                    .queryParam("pauseMillis", pauseMillis)
-                    .request().get();
+                .property(Jetty11ClientProperties.TOTAL_TIMEOUT, 100L)
+                .property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER, "-1")
+                .path("stream")
+                .queryParam("count", count)
+                .queryParam("pauseMillis", pauseMillis)
+                .request().get();
 
             fail("This operation should trigger total timeout");
         } catch (ProcessingException e) {
@@ -236,4 +242,4 @@
             assertEquals(TimeoutException.class, e.getCause().getClass());
         }
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TraceSupportTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TraceSupportTest.java
similarity index 96%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TraceSupportTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TraceSupportTest.java
index 4bf0bda..751f127 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TraceSupportTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TraceSupportTest.java
@@ -14,16 +14,15 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.connector;
 
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.process.Inflector;
-import org.glassfish.jersey.server.ContainerRequest;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.model.Resource;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.HttpMethod;
 import jakarta.ws.rs.Path;
@@ -37,18 +36,26 @@
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Request;
 import jakarta.ws.rs.core.Response;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
 
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.process.Inflector;
+import org.glassfish.jersey.server.ContainerRequest;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.model.Resource;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
+/**
+ * This very basic resource showcases support of a HTTP TRACE method,
+ * not directly supported by JAX-RS API.
+ *
+ * @author Marek Potociar
+ */
 public class TraceSupportTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(TraceSupportTest.class.getName());
@@ -183,7 +190,7 @@
     }
 
     private Client getJettyClient() {
-        return ClientBuilder.newClient(new ClientConfig().connectorProvider(new JettyHttp2ConnectorProvider()));
+        return ClientBuilder.newClient(new ClientConfig().connectorProvider(new Jetty11ConnectorProvider()));
     }
 
 
@@ -225,4 +232,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/UnderlyingHttpClientAccessTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/UnderlyingHttpClientAccessTest.java
similarity index 80%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/UnderlyingHttpClientAccessTest.java
copy to connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/UnderlyingHttpClientAccessTest.java
index 29efcba..c1a6470 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/UnderlyingHttpClientAccessTest.java
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/UnderlyingHttpClientAccessTest.java
@@ -14,21 +14,27 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
-
-import org.eclipse.jetty.client.HttpClient;
-import org.glassfish.jersey.client.ClientConfig;
-import org.junit.jupiter.api.Test;
+package org.glassfish.jersey.jetty11.connector;
 
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.client.ClientBuilder;
 import jakarta.ws.rs.client.WebTarget;
 
+import org.glassfish.jersey.client.ClientConfig;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.junit.jupiter.api.Test;
+
 import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.hamcrest.MatcherAssert.assertThat;
 
+/**
+ * Test of access to the underlying HTTP client instance used by the connector.
+ *
+ * @author Marek Potociar
+ */
 public class UnderlyingHttpClientAccessTest {
 
     /**
@@ -36,13 +42,13 @@
      */
     @Test
     public void testHttpClientInstanceAccess() {
-        final Client client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new JettyHttp2ConnectorProvider()));
-        final HttpClient hcOnClient = JettyHttp2ConnectorProvider.getHttpClient(client);
+        final Client client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new Jetty11ConnectorProvider()));
+        final HttpClient hcOnClient = Jetty11ConnectorProvider.getHttpClient(client);
         // important: the web target instance in this test must be only created AFTER the client has been pre-initialized
         // (see org.glassfish.jersey.client.Initializable.preInitialize method). This is here achieved by calling the
         // connector provider's static getHttpClient method above.
         final WebTarget target = client.target("http://localhost/");
-        final HttpClient hcOnTarget = JettyHttp2ConnectorProvider.getHttpClient(target);
+        final HttpClient hcOnTarget = Jetty11ConnectorProvider.getHttpClient(target);
 
         assertNotNull(hcOnClient, "HTTP client instance set on JerseyClient should not be null.");
         assertNotNull(hcOnTarget, "HTTP client instance set on JerseyWebTarget should not be null.");
@@ -54,13 +60,13 @@
     public void testGetProvidedClientInstance() {
         final HttpClient httpClient = new HttpClient();
         final ClientConfig clientConfig = new ClientConfig()
-                .connectorProvider(new JettyHttp2ConnectorProvider())
-                .register(new JettyHttp2ClientSupplier(httpClient));
+                .connectorProvider(new Jetty11ConnectorProvider())
+                .register(new Jetty11HttpClientSupplier(httpClient));
         final Client client = ClientBuilder.newClient(clientConfig);
         final WebTarget target = client.target("http://localhost/");
-        final HttpClient hcOnTarget = JettyHttp2ConnectorProvider.getHttpClient(target);
+        final HttpClient hcOnTarget = Jetty11ConnectorProvider.getHttpClient(target);
 
         assertThat("Instance provided to a ClientConfig differs from instance provided by JettyProvider",
                 httpClient, is(hcOnTarget));
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty11-http2-connector/pom.xml b/connectors/jetty11-http2-connector/pom.xml
new file mode 100644
index 0000000..c3633ed
--- /dev/null
+++ b/connectors/jetty11-http2-connector/pom.xml
@@ -0,0 +1,187 @@
+<?xml version="1.0"?>
+<!--
+
+    Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <artifactId>project</artifactId>
+        <version>3.1.99-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>jersey-jetty11-http2-connector</artifactId>
+    <packaging>jar</packaging>
+    <name>jersey-connectors-jetty11-http2</name>
+
+    <description>Jersey Client Transport via Jetty 11</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <java8.build.outputDirectory>${project.basedir}/target</java8.build.outputDirectory>
+        <java8.sourceDirectory>${project.basedir}/src/main/java8</java8.sourceDirectory>
+        <java11.build.outputDirectory>${project.basedir}/target11</java11.build.outputDirectory>
+        <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-client</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-util</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty.http2</groupId>
+                <artifactId>http2-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-alpn-conscrypt-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty.http2</groupId>
+                <artifactId>http2-client</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty.http2</groupId>
+                <artifactId>http2-http-client-transport</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-client</artifactId>
+            <version>${jetty11.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.http2</groupId>
+            <artifactId>http2-client</artifactId>
+            <version>${jetty11.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.http2</groupId>
+            <artifactId>http2-http-client-transport</artifactId>
+            <version>${jetty11.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>${jetty11.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.connectors</groupId>
+            <artifactId>jersey-jetty11-connector</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>jetty-client</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-jaxb</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-jetty11-http2</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>http2-server</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-json-jackson</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+            <artifactId>jersey-test-framework-provider-jetty11-http2</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+            <dependency>
+                <groupId>com.sun.xml.bind</groupId>
+                <artifactId>jaxb-osgi</artifactId>
+                <scope>test</scope>
+            </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.sun.istack</groupId>
+                <artifactId>istack-commons-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <inherited>true</inherited>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            ${jetty.osgi.version},
+                            *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/connectors/jetty-http2-connector/src/main/java11/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ClientSupplier.java b/connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/Jetty11Http2ClientSupplier.java
similarity index 74%
rename from connectors/jetty-http2-connector/src/main/java11/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ClientSupplier.java
rename to connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/Jetty11Http2ClientSupplier.java
index 454efd0..f13ef3d 100644
--- a/connectors/jetty-http2-connector/src/main/java11/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ClientSupplier.java
+++ b/connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/Jetty11Http2ClientSupplier.java
@@ -14,36 +14,36 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.HttpClientTransport;
 import org.eclipse.jetty.http2.client.HTTP2Client;
 import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
-import org.glassfish.jersey.jetty.connector.JettyConnector;
-import org.glassfish.jersey.jetty.connector.JettyHttpClientContract;
-import org.glassfish.jersey.jetty.connector.JettyHttpClientSupplier;
+import org.glassfish.jersey.jetty11.connector.Jetty11Connector;
+import org.glassfish.jersey.jetty11.connector.Jetty11HttpClientContract;
+import org.glassfish.jersey.jetty11.connector.Jetty11HttpClientSupplier;
 
 /**
- * HTTP/2 enabled version of the {@link JettyHttpClientSupplier}
+ * HTTP/2 enabled version of the {@link Jetty11HttpClientSupplier}
  *
  * @since 2.41
  */
-public class JettyHttp2ClientSupplier implements JettyHttpClientContract {
+public class Jetty11Http2ClientSupplier implements Jetty11HttpClientContract {
     private final HttpClient http2Client;
 
     /**
      * default Http2Client created for the supplier.
      */
-    public JettyHttp2ClientSupplier() {
+    public Jetty11Http2ClientSupplier() {
         this(createHttp2Client());
     }
     /**
      * supplier for the {@code HttpClient} with {@code HttpClientTransportOverHTTP2} to be optionally registered
      * to a {@link org.glassfish.jersey.client.ClientConfig}
-     * @param http2Client a HttpClient to be supplied when {@link JettyConnector#getHttpClient()} is called.
+     * @param http2Client a HttpClient to be supplied when {@link Jetty11Connector#getHttpClient()} is called.
      */
-    public JettyHttp2ClientSupplier(HttpClient http2Client) {
+    public Jetty11Http2ClientSupplier(HttpClient http2Client) {
         this.http2Client = http2Client;
     }
 
diff --git a/connectors/jetty-http2-connector/src/main/java11/org/glassfish/jersey/jetty/http2/connector/JettyHttp2Connector.java b/connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/Jetty11Http2Connector.java
similarity index 80%
rename from connectors/jetty-http2-connector/src/main/java11/org/glassfish/jersey/jetty/http2/connector/JettyHttp2Connector.java
rename to connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/Jetty11Http2Connector.java
index 7f1e45d..35dc504 100644
--- a/connectors/jetty-http2-connector/src/main/java11/org/glassfish/jersey/jetty/http2/connector/JettyHttp2Connector.java
+++ b/connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/Jetty11Http2Connector.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.core.Configuration;
@@ -24,16 +24,16 @@
 import org.eclipse.jetty.http2.client.HTTP2Client;
 import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
 import org.eclipse.jetty.io.ClientConnector;
-import org.glassfish.jersey.jetty.connector.JettyConnector;
+import org.glassfish.jersey.jetty11.connector.Jetty11Connector;
 
 import java.util.Optional;
 
 /**
- * Extends {@link JettyConnector} with HTTP/2 transport support
+ * Extends {@link Jetty11Connector} with HTTP/2 transport support
  *
  * @since 2.41
  */
-class JettyHttp2Connector extends JettyConnector {
+class Jetty11Http2Connector extends Jetty11Connector {
 
 
     /**
@@ -42,7 +42,7 @@
      * @param jaxrsClient JAX-RS client instance, for which the connector is created.
      * @param config      client configuration.
      */
-    JettyHttp2Connector(Client jaxrsClient, Configuration config) {
+    Jetty11Http2Connector(Client jaxrsClient, Configuration config) {
         super(jaxrsClient, config);
     }
 
@@ -69,11 +69,11 @@
      */
     @Override
     protected HttpClient getRegisteredHttpClient(Configuration config) {
-        if (config.isRegistered(JettyHttp2ClientSupplier.class)) {
+        if (config.isRegistered(Jetty11Http2ClientSupplier.class)) {
             Optional<Object> contract = config.getInstances().stream()
-                    .filter(a-> JettyHttp2ClientSupplier.class.isInstance(a)).findFirst();
+                    .filter(a-> Jetty11Http2ClientSupplier.class.isInstance(a)).findFirst();
             if (contract.isPresent()) {
-                return  ((JettyHttp2ClientSupplier) contract.get()).getHttpClient();
+                return  ((Jetty11Http2ClientSupplier) contract.get()).getHttpClient();
             }
         }
         return null;
diff --git a/connectors/jetty-http2-connector/src/main/java11/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ConnectorProvider.java b/connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/Jetty11Http2ConnectorProvider.java
similarity index 76%
rename from connectors/jetty-http2-connector/src/main/java11/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ConnectorProvider.java
rename to connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/Jetty11Http2ConnectorProvider.java
index 02eaf5a..a4d02d5 100644
--- a/connectors/jetty-http2-connector/src/main/java11/org/glassfish/jersey/jetty/http2/connector/JettyHttp2ConnectorProvider.java
+++ b/connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/Jetty11Http2ConnectorProvider.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.core.Configurable;
@@ -22,18 +22,18 @@
 import org.eclipse.jetty.client.HttpClient;
 import org.glassfish.jersey.client.Initializable;
 import org.glassfish.jersey.client.spi.Connector;
-import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
-import org.glassfish.jersey.jetty.connector.LocalizationMessages;
+import org.glassfish.jersey.jetty11.connector.Jetty11ConnectorProvider;
+import org.glassfish.jersey.jetty11.connector.LocalizationMessages;
 
 /**
- * Provides HTTP2 enabled version of the {@link JettyConnectorProvider} for a client
+ * Provides HTTP2 enabled version of the {@link Jetty11ConnectorProvider} for a client
  *
  * @since 2.41
  */
-public class JettyHttp2ConnectorProvider extends JettyConnectorProvider {
+public class Jetty11Http2ConnectorProvider extends Jetty11ConnectorProvider {
     @Override
     public Connector getConnector(Client client, Configuration runtimeConfig) {
-        return new JettyHttp2Connector(client, runtimeConfig);
+        return new Jetty11Http2Connector(client, runtimeConfig);
     }
 
     public static HttpClient getHttpClient(Configurable<?> component) {
@@ -49,8 +49,8 @@
             connector = initializable.getConfiguration().getConnector();
         }
 
-        if (connector instanceof JettyHttp2Connector) {
-            return ((JettyHttp2Connector) connector).getHttpClient();
+        if (connector instanceof Jetty11Http2Connector) {
+            return ((Jetty11Http2Connector) connector).getHttpClient();
         }
 
         throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED());
diff --git a/connectors/jetty-http2-connector/src/main/java/org/glassfish/jersey/jetty/http2/connector/package-info.java b/connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/package-info.java
similarity index 93%
rename from connectors/jetty-http2-connector/src/main/java/org/glassfish/jersey/jetty/http2/connector/package-info.java
rename to connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/package-info.java
index 960bbb6..0caf270 100644
--- a/connectors/jetty-http2-connector/src/main/java/org/glassfish/jersey/jetty/http2/connector/package-info.java
+++ b/connectors/jetty11-http2-connector/src/main/java/org/glassfish/jersey/jetty11/http2/connector/package-info.java
@@ -18,4 +18,4 @@
  * Jersey HTTP2 client {@link org.glassfish.jersey.client.spi.Connector connector} based on the
  * Jetty Client.
  */
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
diff --git a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties b/connectors/jetty11-http2-connector/src/main/resources/org/glassfish/jersey/jetty11/http2/connector/localization.properties
similarity index 64%
copy from test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
copy to connectors/jetty11-http2-connector/src/main/resources/org/glassfish/jersey/jetty11/http2/connector/localization.properties
index 2886c72..b219ef9 100644
--- a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
+++ b/connectors/jetty11-http2-connector/src/main/resources/org/glassfish/jersey/jetty11/http2/connector/localization.properties
@@ -14,5 +14,8 @@
 # SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 #
 
-# {0} - status code; {1} - status reason message
-not.supported=Jetty container is not supported on JDK version less than 11.
+# {0} - HTTP method, e.g. GET, DELETE
+method.not.supported=Method {0} not supported.
+invalid.configurable.component.type=The supplied component "{0}" is not assignable from Jersey11Client or JerseyWebTarget.
+expected.connector.provider.not.used=The supplied component is not configured to use a Jetty11ConnectorProvider.
+not.supported=Jetty connector is not supported on JDK version less than 11.
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AsyncTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/AsyncTest.java
similarity index 97%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AsyncTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/AsyncTest.java
index 76ef67b..e938d43 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AsyncTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/AsyncTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -141,7 +141,7 @@
     @Override
     protected void configureClient(ClientConfig config) {
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.HEADERS_ONLY));
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     /**
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthFilterTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/AuthFilterTest.java
similarity index 94%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthFilterTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/AuthFilterTest.java
index 5daad2d..2038901 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthFilterTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/AuthFilterTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
@@ -44,7 +44,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     @Test
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/AuthTest.java
similarity index 91%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthTest.java
copy to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/AuthTest.java
index 7fe2edf..e594c20 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/AuthTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/AuthTest.java
@@ -14,11 +14,11 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.eclipse.jetty.client.util.BasicAuthentication;
 import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.jetty.connector.JettyClientProperties;
+import org.glassfish.jersey.jetty11.connector.Jetty11ClientProperties;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
@@ -153,9 +153,9 @@
     @Test
     public void testAuthGet() {
         ClientConfig config = new ClientConfig();
-        config.property(JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+        config.property(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
                 new BasicAuthentication(getBaseUri(), "WallyWorld", "name", "password"));
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
 
         Response response = client.target(getBaseUri()).path(PATH).request().get();
@@ -166,9 +166,9 @@
     @Test
     public void testAuthPost() {
         ClientConfig config = new ClientConfig();
-        config.property(JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+        config.property(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
                 new BasicAuthentication(getBaseUri(), "WallyWorld", "name", "password"));
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
 
         Response response = client.target(getBaseUri()).path(PATH).request().post(Entity.text("POST"));
@@ -179,9 +179,9 @@
     @Test
     public void testAuthDelete() {
         ClientConfig config = new ClientConfig();
-        config.property(JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+        config.property(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
                 new BasicAuthentication(getBaseUri(), "WallyWorld", "name", "password"));
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
 
         Response response = client.target(getBaseUri()).path(PATH).request().delete();
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CookieTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/CookieTest.java
similarity index 86%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CookieTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/CookieTest.java
index eb1c653..b5cd635 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CookieTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/CookieTest.java
@@ -14,12 +14,12 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.JerseyClient;
 import org.glassfish.jersey.client.JerseyClientBuilder;
-import org.glassfish.jersey.jetty.connector.JettyClientProperties;
+import org.glassfish.jersey.jetty11.connector.Jetty11ClientProperties;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
@@ -68,7 +68,7 @@
     @Test
     public void testCookieResource() {
         ClientConfig config = new ClientConfig();
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
         WebTarget r = client.target(getBaseUri());
 
@@ -81,15 +81,15 @@
     @Test
     public void testDisabledCookies() {
         ClientConfig cc = new ClientConfig();
-        cc.property(JettyClientProperties.DISABLE_COOKIES, true);
-        cc.connectorProvider(new JettyHttp2ConnectorProvider());
+        cc.property(Jetty11ClientProperties.DISABLE_COOKIES, true);
+        cc.connectorProvider(new Jetty11Http2ConnectorProvider());
         JerseyClient client = JerseyClientBuilder.createClient(cc);
         WebTarget r = client.target(getBaseUri());
 
         assertEquals("NO-COOKIE", r.request().get(String.class));
         assertEquals("NO-COOKIE", r.request().get(String.class));
 
-        final JettyHttp2Connector connector = (JettyHttp2Connector) client.getConfiguration().getConnector();
+        final Jetty11Http2Connector connector = (Jetty11Http2Connector) client.getConfiguration().getConnector();
         if (connector.getCookieStore() != null) {
             assertTrue(connector.getCookieStore().getCookies().isEmpty());
         } else {
@@ -101,14 +101,14 @@
     @Test
     public void testCookies() {
         ClientConfig cc = new ClientConfig();
-        cc.connectorProvider(new JettyHttp2ConnectorProvider());
+        cc.connectorProvider(new Jetty11Http2ConnectorProvider());
         JerseyClient client = JerseyClientBuilder.createClient(cc);
         WebTarget r = client.target(getBaseUri());
 
         assertEquals("NO-COOKIE", r.request().get(String.class));
         assertEquals("value", r.request().get(String.class));
 
-        final JettyHttp2Connector connector = (JettyHttp2Connector) client.getConfiguration().getConnector();
+        final Jetty11Http2Connector connector = (Jetty11Http2Connector) client.getConfiguration().getConnector();
         assertNotNull(connector.getCookieStore().getCookies());
         assertEquals(1, connector.getCookieStore().getCookies().size());
         assertEquals("value", connector.getCookieStore().getCookies().get(0).getValue());
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CustomLoggingFilter.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/CustomLoggingFilter.java
similarity index 97%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CustomLoggingFilter.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/CustomLoggingFilter.java
index 369169a..45708b6 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/CustomLoggingFilter.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/CustomLoggingFilter.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import jakarta.ws.rs.client.ClientRequestContext;
 import jakarta.ws.rs.client.ClientRequestFilter;
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/EntityTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/EntityTest.java
similarity index 97%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/EntityTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/EntityTest.java
index 0f508ca..9c276e8 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/EntityTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/EntityTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.jackson.JacksonFeature;
@@ -103,7 +103,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider())
+        config.connectorProvider(new Jetty11Http2ConnectorProvider())
                 .register(JacksonFeature.class);
     }
 
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ErrorTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/ErrorTest.java
similarity index 96%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ErrorTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/ErrorTest.java
index 64d8198..bc534fe 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ErrorTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/ErrorTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -47,7 +47,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
 
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/FollowRedirectsTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/FollowRedirectsTest.java
similarity index 94%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/FollowRedirectsTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/FollowRedirectsTest.java
index 2604f9b..121a826 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/FollowRedirectsTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/FollowRedirectsTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.ClientProperties;
@@ -69,7 +69,7 @@
     @Override
     protected void configureClient(ClientConfig config) {
         config.property(ClientProperties.FOLLOW_REDIRECTS, false);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     private static class RedirectTestFilter implements ClientResponseFilter {
@@ -88,7 +88,7 @@
     public void testDoFollow() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
         Response r = t.path("test/redirect")
@@ -118,7 +118,7 @@
     public void testDontFollowPerRequestOverride() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
         Client client = ClientBuilder.newClient(config);
         WebTarget t = client.target(u);
         t.property(ClientProperties.FOLLOW_REDIRECTS, false);
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/GZIPContentEncodingTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/GZIPContentEncodingTest.java
similarity index 94%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/GZIPContentEncodingTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/GZIPContentEncodingTest.java
index 29bb444..8139643 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/GZIPContentEncodingTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/GZIPContentEncodingTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.ClientProperties;
@@ -61,7 +61,7 @@
     @Override
     protected void configureClient(ClientConfig config) {
         config.register(GZipEncoder.class);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     @Test
@@ -80,7 +80,7 @@
     public void testPostChunked() {
         ClientConfig config = new ClientConfig();
         config.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
 
         Client client = ClientBuilder.newClient(config);
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HelloWorldTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/HelloWorldTest.java
similarity index 98%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HelloWorldTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/HelloWorldTest.java
index ac6870a..0f674ac 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HelloWorldTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/HelloWorldTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -65,7 +65,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     @Test
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/Http2PresenceTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/Http2PresenceTest.java
similarity index 91%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/Http2PresenceTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/Http2PresenceTest.java
index 9823284..df7da3f 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/Http2PresenceTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/Http2PresenceTest.java
@@ -14,13 +14,12 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.spi.ConnectorProvider;
-import org.glassfish.jersey.jetty.JettyHttpContainer;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
@@ -80,7 +79,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     @Test
@@ -94,9 +93,9 @@
     @Test
     public void testHttp2Presence() {
         final ConnectorProvider provider = ((ClientConfig) target().getConfiguration()).getConnectorProvider();
-        assertTrue(provider instanceof JettyHttp2ConnectorProvider);
+        assertTrue(provider instanceof Jetty11Http2ConnectorProvider);
 
-        final HttpClient client = ((JettyHttp2ConnectorProvider) provider).getHttpClient(target());
+        final HttpClient client = ((Jetty11Http2ConnectorProvider) provider).getHttpClient(target());
         assertTrue(client.getTransport() instanceof HttpClientTransportOverHTTP2);
     }
 
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/HttpHeadersTest.java
similarity index 95%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/HttpHeadersTest.java
index cb3b319..9cdd81e 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/HttpHeadersTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -71,7 +71,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     @Test
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ManagedClientTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/ManagedClientTest.java
similarity index 98%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ManagedClientTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/ManagedClientTest.java
index 215408b..e5ba7d3 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ManagedClientTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/ManagedClientTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -225,7 +225,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     /**
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/MethodTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/MethodTest.java
similarity index 97%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/MethodTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/MethodTest.java
index 8412c41..2dabed5 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/MethodTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/MethodTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -80,7 +80,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     @Test
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/NoEntityTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/NoEntityTest.java
similarity index 95%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/NoEntityTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/NoEntityTest.java
index 1c14296..3414f2c 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/NoEntityTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/NoEntityTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -54,7 +54,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     @Test
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/SyncResponseSizeTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/SyncResponseSizeTest.java
similarity index 89%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/SyncResponseSizeTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/SyncResponseSizeTest.java
index e3b2c3d..159738e 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/SyncResponseSizeTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/SyncResponseSizeTest.java
@@ -14,11 +14,11 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.jetty.connector.JettyClientProperties;
+import org.glassfish.jersey.jetty11.connector.Jetty11ClientProperties;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
@@ -87,7 +87,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     @Test
@@ -101,7 +101,7 @@
     public void testDefaultTooBig() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
 
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
@@ -121,8 +121,8 @@
     public void testCustomBig() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
-        config.property(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
+        config.property(Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
 
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
@@ -142,8 +142,8 @@
     public void testCustomTooBig() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
-        config.property(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
+        config.property(Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
 
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TimeoutTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/TimeoutTest.java
similarity index 94%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TimeoutTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/TimeoutTest.java
index 59f242e..e3745ef 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TimeoutTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/TimeoutTest.java
@@ -14,12 +14,12 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.CommonProperties;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.jetty.connector.JettyClientProperties;
+import org.glassfish.jersey.jetty11.connector.Jetty11ClientProperties;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
@@ -121,7 +121,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
     }
 
     @Test
@@ -135,7 +135,7 @@
     public void testSlow() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
         try {
@@ -153,7 +153,7 @@
     public void testTimeoutInRequest() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig();
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new Jetty11Http2ConnectorProvider());
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
         try {
@@ -197,7 +197,7 @@
 
         try {
             target("test")
-                    .property(JettyClientProperties.TOTAL_TIMEOUT, 100L)
+                    .property(Jetty11ClientProperties.TOTAL_TIMEOUT, 100L)
                     .property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER, "-1")
                     .path("stream")
                     .queryParam("count", count)
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TraceSupportTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/TraceSupportTest.java
similarity index 98%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TraceSupportTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/TraceSupportTest.java
index 4bf0bda..815167e 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TraceSupportTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/TraceSupportTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -183,7 +183,7 @@
     }
 
     private Client getJettyClient() {
-        return ClientBuilder.newClient(new ClientConfig().connectorProvider(new JettyHttp2ConnectorProvider()));
+        return ClientBuilder.newClient(new ClientConfig().connectorProvider(new Jetty11Http2ConnectorProvider()));
     }
 
 
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/UnderlyingHttpClientAccessTest.java b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/UnderlyingHttpClientAccessTest.java
similarity index 83%
rename from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/UnderlyingHttpClientAccessTest.java
rename to connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/UnderlyingHttpClientAccessTest.java
index 29efcba..b56b536 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/UnderlyingHttpClientAccessTest.java
+++ b/connectors/jetty11-http2-connector/src/test/java/org/glassfish/jersey/jetty11/http2/connector/UnderlyingHttpClientAccessTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jetty11.http2.connector;
 
 import org.eclipse.jetty.client.HttpClient;
 import org.glassfish.jersey.client.ClientConfig;
@@ -36,13 +36,13 @@
      */
     @Test
     public void testHttpClientInstanceAccess() {
-        final Client client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new JettyHttp2ConnectorProvider()));
-        final HttpClient hcOnClient = JettyHttp2ConnectorProvider.getHttpClient(client);
+        final Client client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new Jetty11Http2ConnectorProvider()));
+        final HttpClient hcOnClient = Jetty11Http2ConnectorProvider.getHttpClient(client);
         // important: the web target instance in this test must be only created AFTER the client has been pre-initialized
         // (see org.glassfish.jersey.client.Initializable.preInitialize method). This is here achieved by calling the
         // connector provider's static getHttpClient method above.
         final WebTarget target = client.target("http://localhost/");
-        final HttpClient hcOnTarget = JettyHttp2ConnectorProvider.getHttpClient(target);
+        final HttpClient hcOnTarget = Jetty11Http2ConnectorProvider.getHttpClient(target);
 
         assertNotNull(hcOnClient, "HTTP client instance set on JerseyClient should not be null.");
         assertNotNull(hcOnTarget, "HTTP client instance set on JerseyWebTarget should not be null.");
@@ -54,11 +54,11 @@
     public void testGetProvidedClientInstance() {
         final HttpClient httpClient = new HttpClient();
         final ClientConfig clientConfig = new ClientConfig()
-                .connectorProvider(new JettyHttp2ConnectorProvider())
-                .register(new JettyHttp2ClientSupplier(httpClient));
+                .connectorProvider(new Jetty11Http2ConnectorProvider())
+                .register(new Jetty11Http2ClientSupplier(httpClient));
         final Client client = ClientBuilder.newClient(clientConfig);
         final WebTarget target = client.target("http://localhost/");
-        final HttpClient hcOnTarget = JettyHttp2ConnectorProvider.getHttpClient(target);
+        final HttpClient hcOnTarget = Jetty11Http2ConnectorProvider.getHttpClient(target);
 
         assertThat("Instance provided to a ClientConfig differs from instance provided by JettyProvider",
                 httpClient, is(hcOnTarget));
diff --git a/connectors/jnh-connector/pom.xml b/connectors/jnh-connector/pom.xml
new file mode 100644
index 0000000..450e166
--- /dev/null
+++ b/connectors/jnh-connector/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>project</artifactId>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <version>3.1.99-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jersey-jnh-connector</artifactId>
+    <packaging>jar</packaging>
+    <name>jersey-connectors-jnh</name>
+
+    <description>Jersey Client Transport via java.net.http.HttpClient introduced in Java 11</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+            <artifactId>jersey-test-framework-provider-bundle</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-jaxb</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-json-jackson</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-osgi</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.sun.istack</groupId>
+                <artifactId>istack-commons-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpClientProperties.java b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpClientProperties.java
new file mode 100644
index 0000000..a9c0248
--- /dev/null
+++ b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpClientProperties.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import org.glassfish.jersey.internal.util.PropertiesClass;
+
+import java.net.http.HttpClient;
+
+/**
+ * Provides configuration properties for a {@link JavaNetHttpConnector}.
+ *
+ * @author Steffen Nießing
+ */
+@PropertiesClass
+public class JavaNetHttpClientProperties {
+    /**
+     * <p>
+     *     Configuration of the {@link java.net.CookieHandler} that should be used by the {@link HttpClient}.
+     *     If this option is not set, {@link HttpClient#cookieHandler()} will return an empty {@link java.util.Optional}
+     *     and therefore no cookie handler will be used.
+     * </p>
+     * <p>
+     *     A provided value to this option has to be of type {@link java.net.CookieHandler}.
+     * </p>
+     * <p>
+     *     The name of the configuration property is <tt>{@value}</tt>.
+     * </p>
+     */
+    public static final String COOKIE_HANDLER = "jersey.config.jnh.client.cookieHandler";
+
+    /**
+     * <p>
+     *     Configuration of SSL parameters used by the {@link HttpClient}.
+     *     If this option is not set, then the {@link HttpClient} will use <it>implementation specific</it> default values.
+     * </p>
+     * <p>
+     *     A provided value to this option has to be of type {@link javax.net.ssl.SSLParameters}.
+     * </p>
+     * <p>
+     *     The name of the configuration property is <tt>{@value}</tt>.
+     * </p>
+     */
+    public static final String SSL_PARAMETERS = "jersey.config.jnh.client.sslParameters";
+
+    /**
+     * <p>
+     *     An instance of the {@link java.net.Authenticator} class that should be used to retrieve
+     *     credentials from a user.
+     * </p>
+     * <p>
+     *     The name of the configuration property is <tt>{@value}</tt>.
+     * </p>
+     */
+    public static final String PREEMPTIVE_BASIC_AUTHENTICATION =
+            "jersey.config.jnh.client.preemptiveBasicAuthentication";
+
+    /**
+     * <p>
+     *     A value of {@code false} indicates the client should handle cookies
+     *     automatically using HttpClient's default cookie policy. A value
+     *     of {@code false} will cause the client to ignore all cookies.
+     * </p>
+     * <p>
+     *     The value MUST be an instance of {@link java.lang.Boolean}.
+     *     If the property is absent the default value is {@code false}
+     * </p>
+     * <p>
+     *     The name of the configuration property is <tt>{@value}</tt>.
+     * </p>
+     */
+    public static final String DISABLE_COOKIES =
+            "jersey.config.jnh.client.disableCookies";
+
+    /**
+     * HTTP version - if null or instance of HttpClient.Version.HTTP_1_1 the version will be set to HTTP_1_1
+     * if version is HttpClient.Version.HTTP_2 the client will attempt to perform each request using HTTP_2 protocol
+     * but if not supported by server, the protocol will be still HTTP_1_1
+     *
+     * @since 3.1.4
+     */
+    public static final String HTTP_VERSION =
+            "jersey.config.jnh.client.httpVersion";
+
+
+    /**
+     * Prevent this class from instantiation.
+     */
+    private JavaNetHttpClientProperties() {}
+}
diff --git a/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpConnector.java b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpConnector.java
new file mode 100644
index 0000000..69d25eb
--- /dev/null
+++ b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpConnector.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.MultivaluedMap;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientRequest;
+import org.glassfish.jersey.client.ClientResponse;
+import org.glassfish.jersey.client.innate.ClientProxy;
+import org.glassfish.jersey.client.innate.Expect100ContinueUsage;
+import org.glassfish.jersey.client.innate.http.SSLParamConfigurator;
+import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
+import org.glassfish.jersey.client.spi.Connector;
+import org.glassfish.jersey.internal.Version;
+import org.glassfish.jersey.message.internal.OutboundMessageContext;
+import org.glassfish.jersey.message.internal.Statuses;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Authenticator;
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.CookiePolicy;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.ProxySelector;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.logging.Logger;
+
+/**
+ * Provides a Jersey client {@link Connector}, which internally uses Java's {@link HttpClient}.
+ * The following properties are provided to Java's {@link HttpClient.Builder} during creation of the {@link HttpClient}:
+ * <ul>
+ *     <li>{@link ClientProperties#CONNECT_TIMEOUT}</li>
+ *     <li>{@link ClientProperties#FOLLOW_REDIRECTS}</li>
+ *     <li>{@link JavaNetHttpClientProperties#COOKIE_HANDLER}</li>
+ *     <li>{@link JavaNetHttpClientProperties#SSL_PARAMETERS}</li>
+ * </ul>
+ *
+ * @author Steffen Nießing
+ */
+public class JavaNetHttpConnector implements Connector {
+    private static final Logger LOGGER = Logger.getLogger(JavaNetHttpConnector.class.getName());
+
+    private final HttpClient httpClient;
+
+    /**
+     * Constructs a new {@link Connector} for a Jersey client instance using Java's {@link HttpClient}.
+     *
+     * @param client a Jersey client instance to get additional configuration properties from (e.g. {@link SSLContext})
+     * @param configuration the configuration properties for this connector
+     */
+    public JavaNetHttpConnector(final Client client, final Configuration configuration) {
+        final HttpClient.Builder httpClientBuilder = HttpClient.newBuilder();
+        final HttpClient.Version version =
+                getPropertyOrNull(configuration, JavaNetHttpClientProperties.HTTP_VERSION, HttpClient.Version.class);
+        httpClientBuilder.version(version == null ? HttpClient.Version.HTTP_1_1 : version);
+        SSLContext sslContext = client.getSslContext();
+        if (sslContext != null) {
+            httpClientBuilder.sslContext(sslContext);
+        }
+        final CookieHandler cookieHandler =
+                getPropertyOrNull(configuration, JavaNetHttpClientProperties.COOKIE_HANDLER, CookieHandler.class);
+        if (cookieHandler != null) {
+            httpClientBuilder.cookieHandler(cookieHandler);
+        }
+        final Boolean disableCookies =
+                getPropertyOrNull(configuration, JavaNetHttpClientProperties.DISABLE_COOKIES, Boolean.class);
+        if (Boolean.TRUE.equals(disableCookies)) {
+            httpClientBuilder.cookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_NONE));
+        }
+        Boolean redirect = getPropertyOrNull(configuration, ClientProperties.FOLLOW_REDIRECTS, Boolean.class);
+        if (redirect != null) {
+            httpClientBuilder.followRedirects(redirect ? HttpClient.Redirect.ALWAYS : HttpClient.Redirect.NEVER);
+        } else {
+            httpClientBuilder.followRedirects(HttpClient.Redirect.NORMAL);
+        }
+
+        SSLParameters sslParameters =
+                getPropertyOrNull(configuration, JavaNetHttpClientProperties.SSL_PARAMETERS, SSLParameters.class);
+        sslParameters = new SniSslParameters(sslParameters).getSslParameters(client);
+        if (sslParameters != null) {
+            httpClientBuilder.sslParameters(sslParameters);
+        }
+
+        final Authenticator preemptiveAuthenticator =
+                getPropertyOrNull(configuration,
+                        JavaNetHttpClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION, Authenticator.class);
+        if (preemptiveAuthenticator != null) {
+            httpClientBuilder.authenticator(preemptiveAuthenticator);
+        }
+        configureProxy(httpClientBuilder, configuration);
+        this.httpClient = httpClientBuilder.build();
+    }
+
+    private static void configureProxy(HttpClient.Builder builder, final Configuration config) {
+
+        final Optional<ClientProxy> proxy = ClientProxy.proxyFromConfiguration(config);
+        proxy.ifPresent(clientProxy -> {
+            final URI u = clientProxy.uri();
+            final InetSocketAddress proxyAddress = new InetSocketAddress(u.getHost(),
+                    u.getPort());
+            if (clientProxy.userName() != null) {
+                final Authenticator authenticator = new Authenticator() {
+                    @Override
+                    public PasswordAuthentication getPasswordAuthentication() {
+                        return new PasswordAuthentication(clientProxy.userName(), clientProxy.password() == null
+                                ? null : clientProxy.password().toCharArray());
+                    }
+                    @Override
+                    protected RequestorType getRequestorType() {
+                        return RequestorType.PROXY;
+                    }
+                };
+                builder.authenticator(authenticator);
+            }
+            builder.proxy(ProxySelector.of(proxyAddress));
+        });
+    }
+
+    /**
+     * Implements a {@link org.glassfish.jersey.message.internal.OutboundMessageContext.StreamProvider}
+     * for a {@link ByteArrayOutputStream}.
+     */
+    private static class ByteArrayOutputStreamProvider implements OutboundMessageContext.StreamProvider {
+        private ByteArrayOutputStream byteArrayOutputStream;
+
+        public ByteArrayOutputStream getByteArrayOutputStream() {
+            return byteArrayOutputStream;
+        }
+
+        @Override
+        public OutputStream getOutputStream(int contentLength) throws IOException {
+            this.byteArrayOutputStream = contentLength > 0 ? new ByteArrayOutputStream(contentLength)
+                    : new ByteArrayOutputStream();
+            return this.byteArrayOutputStream;
+        }
+    }
+
+    /**
+     * Builds a request for the {@link HttpClient} from Jersey's {@link ClientRequest}.
+     *
+     * @param request the Jersey request to get request data from
+     * @return the {@link HttpRequest} instance for the {@link HttpClient} request
+     */
+    private HttpRequest getHttpRequest(ClientRequest request) {
+        final SSLParamConfigurator sniConfig = SSLParamConfigurator.builder()
+                .uri(request.getUri())
+                .configuration(request.getConfiguration())
+                .build();
+
+        final URI sniUri = sniConfig.isSNIRequired() ? sniConfig.toIPRequestUri() : request.getUri();
+
+        HttpRequest.Builder builder = HttpRequest.newBuilder();
+        builder.uri(sniUri);
+        HttpRequest.BodyPublisher bodyPublisher = HttpRequest.BodyPublishers.noBody();
+        if (request.hasEntity()) {
+            try {
+                ByteArrayOutputStreamProvider byteBufferStreamProvider = new ByteArrayOutputStreamProvider();
+                request.setStreamProvider(byteBufferStreamProvider);
+                request.writeEntity();
+                bodyPublisher = HttpRequest.BodyPublishers.ofByteArray(
+                        byteBufferStreamProvider.getByteArrayOutputStream().toByteArray()
+                );
+            } catch (IOException e) {
+                throw new ProcessingException(LocalizationMessages.ERROR_INVALID_ENTITY(), e);
+            }
+        }
+        builder.method(request.getMethod(), bodyPublisher);
+        for (Map.Entry<String, List<String>> entry : request.getRequestHeaders().entrySet()) {
+            String headerName = entry.getKey();
+            for (String headerValue : entry.getValue()) {
+                builder.header(headerName, headerValue);
+            }
+        }
+        final Integer connectTimeout = request.resolveProperty(ClientProperties.READ_TIMEOUT, Integer.class);
+        if (connectTimeout != null) {
+            builder.timeout(Duration.ofMillis(connectTimeout));
+        }
+        processExtensions(builder, request);
+        return builder.build();
+    }
+
+     private static void processExtensions(HttpRequest.Builder builder, ClientRequest request) {
+        builder.expectContinue(Expect100ContinueUsage.isAllowed(request, request.getMethod()));
+    }
+
+    /**
+     * Retrieves a property from the configuration, if it was provided.
+     *
+     * @param configuration the {@link Configuration} to get the property information from
+     * @param propertyKey the name of the property to retrieve
+     * @param resultClass the type to which the property value should be case
+     * @param <T> the generic type parameter of the result type
+     * @return the requested property or {@code null}, if it was not provided or has the wrong type
+     */
+    @SuppressWarnings("unchecked")
+    private <T> T getPropertyOrNull(final Configuration configuration, final String propertyKey, final Class<T> resultClass) {
+        Object propertyObject = configuration.getProperty(propertyKey);
+        if (propertyObject == null) {
+            return null;
+        }
+        if (resultClass.isEnum() && propertyObject instanceof String) {
+            return (T) Enum.valueOf(resultClass.asSubclass(Enum.class), (String) propertyObject);
+        }
+        if (!resultClass.isInstance(propertyObject)) {
+            LOGGER.warning(LocalizationMessages.ERROR_INVALID_CLASS(propertyKey, resultClass.getName()));
+            return null;
+        }
+        return (T) propertyObject;
+    }
+
+    /**
+     * Translates a {@link HttpResponse} from the {@link HttpClient} to a Jersey {@link ClientResponse}.
+     *
+     * @param request the {@link ClientRequest} to get additional information (e.g. header values) from
+     * @param response the {@link HttpClient} response object
+     * @return the translated Jersey {@link ClientResponse} object
+     */
+    private ClientResponse buildClientResponse(ClientRequest request, HttpResponse<InputStream> response) {
+        ClientResponse clientResponse = new ClientResponse(Statuses.from(response.statusCode()), request);
+        MultivaluedMap<String, String> headers = clientResponse.getHeaders();
+        for (Map.Entry<String, List<String>> entry : response.headers().map().entrySet()) {
+            String headerName = entry.getKey();
+            if (headers.get(headerName) != null) {
+                headers.get(headerName).addAll(entry.getValue());
+            } else {
+                headers.put(headerName, entry.getValue());
+            }
+        }
+        final InputStream body = response.body();
+        try {
+            clientResponse.setEntityStream(body.available() != 1 ? body : new FirstByteCachingStream(body));
+        } catch (IOException ioe) {
+            throw new ProcessingException(ioe);
+        }
+        return clientResponse;
+    }
+
+    /**
+     * Returns the underlying {@link HttpClient} instance used by this connector.
+     *
+     * @return the Java {@link HttpClient} instance
+     */
+    public HttpClient getHttpClient() {
+        return httpClient;
+    }
+
+    @Override
+    public ClientResponse apply(ClientRequest request) {
+        HttpRequest httpRequest = getHttpRequest(request);
+        try {
+            HttpResponse<InputStream> response = this.httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofInputStream());
+            return buildClientResponse(request, response);
+        } catch (IOException | InterruptedException e) {
+            throw new ProcessingException(e);
+        }
+    }
+
+    @Override
+    public Future<?> apply(ClientRequest request, AsyncConnectorCallback callback) {
+        HttpRequest httpRequest = getHttpRequest(request);
+        CompletableFuture<ClientResponse> response = this.httpClient
+                .sendAsync(httpRequest, HttpResponse.BodyHandlers.ofInputStream())
+                .thenApply(httpResponse -> buildClientResponse(request, httpResponse));
+        response.thenAccept(callback::response);
+        return response;
+    }
+
+    @Override
+    public String getName() {
+        return "Java HttpClient Connector " + Version.getVersion();
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+    public CookieHandler getCookieHandler() {
+        final Optional<CookieHandler> cookieHandler = httpClient.cookieHandler();
+        if (cookieHandler.isPresent()) {
+            return cookieHandler.get();
+        }
+        return null;
+    }
+
+    private static class SniSslParameters {
+        private final SSLParameters sslParameters;
+
+        private SniSslParameters(SSLParameters sslParameters) {
+            this.sslParameters = sslParameters;
+        }
+
+        private SSLParameters getSslParameters(Client client) {
+            SSLParamConfigurator sniConfig = SSLParamConfigurator.builder()
+                    .configuration(client.getConfiguration())
+                    .build();
+
+            if (sniConfig.isSNIRequired()) {
+                SSLParameters sslParameters = this.sslParameters;
+                if (sslParameters == null) {
+                    sslParameters = new SSLParameters();
+                }
+                sniConfig.setSNIServerName(sslParameters);
+                return sslParameters;
+            } else {
+                return sslParameters;
+            }
+        }
+    }
+
+    /*
+     * The JDK stream returns available() == 1 even when read() == -1
+     * This class is to prevent it.
+     * Otherwise, the MBR is not found for 204
+     * See https://github.com/eclipse-ee4j/jersey/issues/5307
+     */
+    private static class FirstByteCachingStream extends InputStream {
+        private final InputStream inner; //jdk.internal.net.http.ResponseSubscribers.HttpResponseInputStream
+        private volatile int zero = -1; // int on zero index
+        private final Lock lock = new ReentrantLock();
+
+        private FirstByteCachingStream(InputStream inner) {
+            this.inner = inner;
+        }
+
+        @Override
+        public int read() throws IOException {
+            lock.lock();
+            final int r = zero != -1 ? zero : inner.read();
+            zero = -1;
+            lock.unlock();
+            return r;
+        }
+
+        @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            lock.lock();
+            int r;
+            if (zero != -1) {
+                b[off] = (byte) (zero & 0xFF);
+                r = inner.read(b, off + 1, len - 1);
+            } else {
+                r = inner.read(b, off, len);
+            }
+            zero = -1;
+            lock.unlock();
+            return r;
+
+        }
+
+        @Override
+        public int available() throws IOException {
+            lock.lock();
+            if (zero != -1) {
+                lock.unlock();
+                return 1;
+            }
+
+            int available = inner.available();
+            if (available != 1) {
+                lock.unlock();
+                return available;
+            }
+
+            zero = inner.read();
+            if (zero == -1) {
+                available = 0;
+            }
+            lock.unlock();
+            return available;
+        }
+
+        @Override
+        public void close() throws IOException {
+            inner.close();
+            lock.lock();
+            zero = -1;
+            lock.unlock();
+        }
+
+        @Override
+        public boolean markSupported() {
+            return inner.markSupported();
+        }
+
+        @Override
+        public synchronized void mark(int readlimit) {
+            inner.mark(readlimit);
+        }
+
+    }
+
+}
diff --git a/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpConnectorProvider.java b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpConnectorProvider.java
new file mode 100644
index 0000000..32bde1b
--- /dev/null
+++ b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpConnectorProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.Initializable;
+import org.glassfish.jersey.client.spi.Connector;
+import org.glassfish.jersey.client.spi.ConnectorProvider;
+
+import java.net.http.HttpClient;
+
+/**
+ * A provider class for a Jersey client {@link Connector} using Java's {@link HttpClient}.
+ * <p>
+ *     The following configuration properties are available:
+ *     <ul>
+ *         <li>{@link ClientProperties#CONNECT_TIMEOUT}</li>
+ *         <li>{@link ClientProperties#FOLLOW_REDIRECTS} (defaults to {@link java.net.http.HttpClient.Redirect#NORMAL} when unset)</li>
+ *         <li>{@link JavaNetHttpClientProperties#COOKIE_HANDLER}</li>
+ *         <li>{@link JavaNetHttpClientProperties#SSL_PARAMETERS}</li>
+ *     </ul>
+ * </p>
+ *
+ * @author Steffen Nießing
+ */
+public class JavaNetHttpConnectorProvider implements ConnectorProvider {
+    @Override
+    public Connector getConnector(Client client, Configuration runtimeConfig) {
+        return new JavaNetHttpConnector(client, runtimeConfig);
+    }
+
+    /**
+     * Retrieve the Java {@link HttpClient} used by the provided {@link JavaNetHttpConnector}.
+     *
+     * @param component the component from which the {@link JavaNetHttpConnector} should be retrieved
+     * @return a Java {@link HttpClient} instance
+     * @throws java.lang.IllegalArgumentException if a {@link JavaNetHttpConnector} cannot be provided from the given {@code component}
+     */
+    public static HttpClient getHttpClient(Configurable<?> component) {
+        try {
+            final Initializable<?> initializable = (Initializable<?>) component;
+
+            Connector connector = initializable.getConfiguration().getConnector() != null
+                    ? initializable.getConfiguration().getConnector()
+                    : initializable.preInitialize().getConfiguration().getConnector();
+
+            if (connector instanceof JavaNetHttpConnector) {
+                return ((JavaNetHttpConnector) connector).getHttpClient();
+            } else {
+                throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED());
+            }
+        } catch (ClassCastException classCastException) {
+            throw new IllegalArgumentException(
+                    LocalizationMessages.INVALID_CONFIGURABLE_COMPONENT_TYPE(component.getClass().getName()),
+                    classCastException
+            );
+        }
+    }
+}
diff --git a/test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/package-info.java
similarity index 71%
copy from test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java
copy to connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/package-info.java
index cd4980f..6a5e83a 100644
--- a/test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java
+++ b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,6 +15,7 @@
  */
 
 /**
- * Jersey test framework for Jetty HTTP/2 Container.
+ * Jersey client {@link org.glassfish.jersey.client.spi.Connector connector} based on
+ * Java's {@link java.net.http.HttpClient}.
  */
-package org.glassfish.jersey.test.jetty.http2;
+package org.glassfish.jersey.jnh.connector;
\ No newline at end of file
diff --git a/connectors/jnh-connector/src/main/resources/org/glassfish/jersey/jnh/connector/localization.properties b/connectors/jnh-connector/src/main/resources/org/glassfish/jersey/jnh/connector/localization.properties
new file mode 100644
index 0000000..289b5e3
--- /dev/null
+++ b/connectors/jnh-connector/src/main/resources/org/glassfish/jersey/jnh/connector/localization.properties
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+error.body.publisher=Could not determine BodyPublisher for entity.
+error.invalid.class={0} is not an instance of {1}. Ignoring property.
+error.invalid.entity=Could not serialize entity.
+invalid.configurable.component.type=The supplied component "{0}" is not assignable from JerseyClient or JerseyWebTarget.
+expected.connector.provider.not.used=The supplied component is not configured to use a JavaConnectorProvider.
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/AbstractJavaConnectorTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/AbstractJavaConnectorTest.java
new file mode 100644
index 0000000..6d6e3c0
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/AbstractJavaConnectorTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.container.AsyncResponse;
+import jakarta.ws.rs.container.Suspended;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+
+/**
+ * An abstract base class for tests of the {@link JavaNetHttpConnector} providing common resources and utility methods.
+ */
+abstract class AbstractJavaConnectorTest extends JerseyTest {
+    private static final Logger LOGGER = Logger.getLogger(AbstractJavaConnectorTest.class.getName());
+    public static final String RESOURCE_PATH = "java-connector";
+
+    @Path(RESOURCE_PATH)
+    public static class JavaConnectorTestResource {
+        @GET
+        public String helloWorld() {
+            return "Hello World!";
+        }
+
+        @GET
+        @Path("redirect")
+        public Response redirectToHelloWorld() throws URISyntaxException {
+            return Response.seeOther(new URI(RESOURCE_PATH)).build();
+        }
+
+        @POST
+        @Path("echo")
+        @Produces(MediaType.TEXT_PLAIN)
+        @Consumes(MediaType.TEXT_PLAIN)
+        public String echo(String entity) {
+            return entity;
+        }
+
+        @POST
+        @Path("echo-byte-array")
+        @Produces(MediaType.APPLICATION_OCTET_STREAM)
+        @Consumes(MediaType.APPLICATION_OCTET_STREAM)
+        public byte[] echoByteArray(byte[] byteArray) {
+            return byteArray;
+        }
+
+        @POST
+        @Path("async")
+        public void asyncPostWithTimeout(@QueryParam("timeout") @DefaultValue("10") Long timeoutSeconds,
+                                         @Suspended final AsyncResponse asyncResponse,
+                                         String message) {
+            asyncResponse.setTimeoutHandler(asyncResponse1 ->
+                    asyncResponse1.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE).entity("Timeout").build()));
+            asyncResponse.setTimeout(timeoutSeconds, TimeUnit.SECONDS);
+            CompletableFuture.runAsync(() -> {
+                        try {
+                            Thread.sleep(3000);
+                        } catch (InterruptedException e) {
+                            Thread.currentThread().interrupt();
+                            throw new RuntimeException(e);
+                        }
+                    })
+                    .handleAsync((unused, throwable) -> throwable != null ? "INTERRUPTED" : message)
+                    .thenApplyAsync(asyncResponse::resume);
+        }
+    }
+
+    protected Response request(String path) {
+        return target().path(path).request().get();
+    }
+
+    protected Response requestWithEntity(String path, String method, Entity<?> entity) {
+        return target().path(path).request().method(method, entity);
+    }
+
+    protected Future<Response> requestAsync(String path) {
+        return target().path(path).request().async().get();
+    }
+
+    protected Future<Response> requestAsyncWithEntity(String path, String method, Entity<?> entity) {
+        return target().path(path).request().async().method(method, entity);
+    }
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(JavaConnectorTestResource.class)
+                .register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
+    }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/AsyncTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/AsyncTest.java
new file mode 100644
index 0000000..2df4ad4
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/AsyncTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.Response;
+import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.awaitility.Awaitility.await;
+
+/**
+ * Tests asynchronous and interleaved requests.
+ */
+public class AsyncTest extends AbstractJavaConnectorTest {
+    /**
+     * Checks, that 3 interleaved requests all complete and return their associated responses.
+     * Additionally checks, that all requests complete in 3 times the running time on the server.
+     */
+    @Test
+    public void testAsyncRequestsWithoutTimeout() {
+        Future<Response> request1 = this.requestAsyncWithEntity("java-connector/async", "POST", Entity.text("request1"));
+        Future<Response> request2 = this.requestAsyncWithEntity("java-connector/async", "POST", Entity.text("request2"));
+        Future<Response> request3 = this.requestAsyncWithEntity("java-connector/async", "POST", Entity.text("request3"));
+
+        assertThatCode(() -> {
+            // wait 3 times the processing time and throw if not completed until then
+            await().atMost(3 * 3000, TimeUnit.MILLISECONDS)
+                    .until(() -> request1.isDone() && request2.isDone() && request3.isDone());
+            String response1 = request1.get().readEntity(String.class);
+            String response2 = request2.get().readEntity(String.class);
+            String response3 = request3.get().readEntity(String.class);
+            assertThat(response1).isEqualTo("request1");
+            assertThat(response2).isEqualTo("request2");
+            assertThat(response3).isEqualTo("request3");
+        }).doesNotThrowAnyException();
+    }
+
+    /**
+     * Checks, that a status {@link Response.Status#SERVICE_UNAVAILABLE} is thrown, if a request computes too long.
+     */
+    @Test
+    public void testAsyncRequestsWithTimeout() throws ExecutionException, InterruptedException {
+        try {
+            Response response = target().path("java-connector").path("async").queryParam("timeout", 1)
+                    .request().async().post(Entity.text("")).get();
+            assertThat(response.getStatus()).isEqualTo(Response.Status.SERVICE_UNAVAILABLE.getStatusCode());
+            assertThat(response.readEntity(String.class)).isEqualTo("Timeout");
+        } catch (InterruptedException | ExecutionException ex) {
+            throw new RuntimeException("Could not correctly get response", ex);
+        }
+    }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/AuthTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/AuthTest.java
new file mode 100644
index 0000000..677d4d0
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/AuthTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.util.logging.Logger;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class AuthTest extends JerseyTest {
+
+        private static final Logger LOGGER = Logger.getLogger(AuthTest.class.getName());
+        private static final String PATH = "test";
+
+        @Path("/test")
+        @Singleton
+        public static class AuthResource {
+
+            int requestCount = 0;
+
+            @GET
+            public String get(@Context HttpHeaders h) {
+                requestCount++;
+                String value = h.getRequestHeaders().getFirst("Authorization");
+                if (value == null) {
+                    assertEquals(1, requestCount);
+                    throw new WebApplicationException(
+                            Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+                } else {
+                    assertTrue(requestCount > 1);
+                }
+
+                return "GET";
+            }
+
+            @GET
+            @Path("filter")
+            public String getFilter(@Context HttpHeaders h) {
+                String value = h.getRequestHeaders().getFirst("Authorization");
+                if (value == null) {
+                    throw new WebApplicationException(
+                            Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+                }
+
+                return "GET";
+            }
+
+            @POST
+            public String post(@Context HttpHeaders h, String e) {
+                requestCount++;
+                String value = h.getRequestHeaders().getFirst("Authorization");
+                if (value == null) {
+                    assertEquals(1, requestCount);
+                    throw new WebApplicationException(
+                            Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+                } else {
+                    assertTrue(requestCount > 1);
+                }
+
+                return e;
+            }
+
+            @POST
+            @Path("filter")
+            public String postFilter(@Context HttpHeaders h, String e) {
+                String value = h.getRequestHeaders().getFirst("Authorization");
+                if (value == null) {
+                    throw new WebApplicationException(
+                            Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+                }
+
+                return e;
+            }
+
+            @DELETE
+            public void delete(@Context HttpHeaders h) {
+                requestCount++;
+                String value = h.getRequestHeaders().getFirst("Authorization");
+                if (value == null) {
+                    assertEquals(1, requestCount);
+                    throw new WebApplicationException(
+                            Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+                } else {
+                    assertTrue(requestCount > 1);
+                }
+            }
+
+            @DELETE
+            @Path("filter")
+            public void deleteFilter(@Context HttpHeaders h) {
+                String value = h.getRequestHeaders().getFirst("Authorization");
+                if (value == null) {
+                    throw new WebApplicationException(
+                            Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+                }
+            }
+
+            @DELETE
+            @Path("filter/withEntity")
+            public String deleteFilterWithEntity(@Context HttpHeaders h, String e) {
+                String value = h.getRequestHeaders().getFirst("Authorization");
+                if (value == null) {
+                    throw new WebApplicationException(
+                            Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+                }
+
+                return e;
+            }
+        }
+
+        @Override
+        protected Application configure() {
+        ResourceConfig config = new ResourceConfig(AuthResource.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        return config;
+    }
+
+        @Test
+        public void testAuthGet() {
+        ClientConfig config = new ClientConfig();
+        config.property(JavaNetHttpClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+                new Authenticator() {
+                    @Override
+                    protected PasswordAuthentication getPasswordAuthentication() {
+                        return new PasswordAuthentication("name", "password".toCharArray());
+                    }
+                });
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
+        Client client = ClientBuilder.newClient(config);
+
+        Response response = client.target(getBaseUri()).path(PATH).request().get();
+        assertEquals("GET", response.readEntity(String.class));
+        client.close();
+    }
+
+        @Test
+        public void testAuthPost() {
+        ClientConfig config = new ClientConfig();
+            config.property(JavaNetHttpClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+                    new Authenticator() {
+                        @Override
+                        protected PasswordAuthentication getPasswordAuthentication() {
+                            return new PasswordAuthentication("name", "password".toCharArray());
+                        }
+                    });
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
+        Client client = ClientBuilder.newClient(config);
+
+        Response response = client.target(getBaseUri()).path(PATH).request().post(Entity.text("POST"));
+        assertEquals("POST", response.readEntity(String.class));
+        client.close();
+    }
+
+        @Test
+        public void testAuthDelete() {
+        ClientConfig config = new ClientConfig();
+            config.property(JavaNetHttpClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+                    new Authenticator() {
+                        @Override
+                        protected PasswordAuthentication getPasswordAuthentication() {
+                            return new PasswordAuthentication("name", "password".toCharArray());
+                        }
+                    });
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
+        Client client = ClientBuilder.newClient(config);
+
+        Response response = client.target(getBaseUri()).path(PATH).request().delete();
+        assertEquals(response.getStatus(), 204);
+        client.close();
+    }
+
+    }
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/BodyPublisherTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/BodyPublisherTest.java
new file mode 100644
index 0000000..b57107c
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/BodyPublisherTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.junit.jupiter.api.Test;
+
+import java.nio.charset.StandardCharsets;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+/**
+ * Checks, that request entities are correctly serialized and deserialized.
+ */
+public class BodyPublisherTest extends AbstractJavaConnectorTest {
+    /**
+     * Checks with a simple plain text entity.
+     */
+    @Test
+    public void testStringEntity() {
+        Response response = this.requestWithEntity("java-connector/echo", "POST", Entity.text("Echo"));
+        assertThat(response.getStatus()).isEqualTo(200);
+        assertThatCode(() -> {
+            assertThat(response.readEntity(String.class)).isEqualTo("Echo");
+        }).doesNotThrowAnyException();
+    }
+
+    /**
+     * Checks with an octet stream entity.
+     */
+    @Test
+    public void testByteArrayEntity() {
+        String test = "test-string";
+        Response response = this.requestWithEntity("java-connector/echo-byte-array", "POST",
+                Entity.entity(test.getBytes(StandardCharsets.UTF_8), MediaType.APPLICATION_OCTET_STREAM_TYPE));
+        assertThat(response.getStatus()).isEqualTo(200);
+        assertThatCode(() -> {
+            assertThat(response.readEntity(byte[].class))
+                    .satisfies(bytes -> assertThat(new String(bytes, StandardCharsets.UTF_8)).isEqualTo("test-string"));
+        }).doesNotThrowAnyException();
+    }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/CookieTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/CookieTest.java
new file mode 100644
index 0000000..31eda93
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/CookieTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.NewCookie;
+import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.JerseyClient;
+import org.glassfish.jersey.client.JerseyClientBuilder;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.net.CookieManager;
+import java.util.Collections;
+import java.util.logging.Logger;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class CookieTest extends JerseyTest {
+
+private static final Logger LOGGER = Logger.getLogger(CookieTest.class.getName());
+
+@Path("/")
+public static class CookieResource {
+    @GET
+    public Response get(@Context HttpHeaders h) {
+        Cookie c = h.getCookies().get("name");
+        String e = (c == null) ? "NO-COOKIE" : c.getValue();
+        return Response.ok(e)
+                .cookie(new NewCookie("name", "value")).build();
+    }
+}
+
+    @Override
+    protected Application configure() {
+        ResourceConfig config = new ResourceConfig(CookieResource.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        return config;
+    }
+
+    @Test
+    public void testCookieResource() {
+        ClientConfig config = new ClientConfig();
+        config.property(JavaNetHttpClientProperties.COOKIE_HANDLER, new CookieManager());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
+        Client client = ClientBuilder.newClient(config);
+        WebTarget r = client.target(getBaseUri());
+
+
+        assertEquals("NO-COOKIE", r.request().get(String.class));
+        assertEquals("value", r.request().get(String.class));
+        client.close();
+    }
+
+    @Test
+    public void testDisabledCookies() throws IOException {
+        ClientConfig cc = new ClientConfig();
+        cc.property(JavaNetHttpClientProperties.DISABLE_COOKIES, true);
+        cc.property(JavaNetHttpClientProperties.COOKIE_HANDLER, new CookieManager());
+        cc.connectorProvider(new JavaNetHttpConnectorProvider());
+        JerseyClient client = JerseyClientBuilder.createClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        assertEquals("NO-COOKIE", r.request().get(String.class));
+        assertEquals("NO-COOKIE", r.request().get(String.class));
+
+        CookieManager manager = new CookieManager();
+        manager.getCookieStore().getCookies();
+
+        final JavaNetHttpConnector connector = (JavaNetHttpConnector) client.getConfiguration().getConnector();
+
+        if (connector.getCookieHandler() != null) {
+            assertTrue(connector.getCookieHandler().get(getBaseUri(), Collections.emptyMap()).get("Cookie").isEmpty());
+        } else {
+            assertNull(connector.getCookieHandler());
+        }
+        client.close();
+    }
+
+    @Test
+    public void testCookies() throws IOException {
+        ClientConfig cc = new ClientConfig();
+        final CookieManager manager = new CookieManager();
+        cc.property(JavaNetHttpClientProperties.COOKIE_HANDLER, manager);
+        cc.connectorProvider(new JavaNetHttpConnectorProvider());
+        JerseyClient client = JerseyClientBuilder.createClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        assertEquals("NO-COOKIE", r.request().get(String.class));
+        assertEquals("value", r.request().get(String.class));
+
+        final JavaNetHttpConnector connector = (JavaNetHttpConnector) client.getConfiguration().getConnector();
+        assertNotNull(connector.getCookieHandler());
+        assertEquals(1, connector.getCookieHandler().get(getBaseUri(), Collections.emptyMap()).size());
+        assertEquals("value", manager.getCookieStore().getCookies().get(0).getValue());
+        client.close();
+    }
+}
\ No newline at end of file
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/EntityTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/EntityTest.java
similarity index 93%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/EntityTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/EntityTest.java
index 0f508ca..f1af21c 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/EntityTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/EntityTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,14 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
-
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.jackson.JacksonFeature;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+package org.glassfish.jersey.jnh.connector;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.POST;
@@ -31,13 +24,21 @@
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
 import jakarta.xml.bind.annotation.XmlRootElement;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 import java.util.logging.Logger;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-public class EntityTest extends JerseyTest {
+
+public class EntityTest  extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(EntityTest.class.getName());
 
@@ -65,6 +66,7 @@
         private String lastName;
 
         public Person() {
+            //For JAXB processing
         }
 
         public Person(String firstName, String lastName) {
@@ -103,8 +105,8 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider())
-                .register(JacksonFeature.class);
+        config.connectorProvider(new JavaNetHttpConnectorProvider())
+        .register(JacksonFeature.class);
     }
 
     @Test
@@ -148,4 +150,4 @@
         person = response.readEntity(Person.class);
         assertEquals("John Doe", person.toString());
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ErrorTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ErrorTest.java
similarity index 74%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ErrorTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ErrorTest.java
index 64d8198..960f063 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ErrorTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ErrorTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,13 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
-
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+package org.glassfish.jersey.jnh.connector;
 
 import jakarta.ws.rs.ClientErrorException;
 import jakarta.ws.rs.POST;
@@ -29,6 +23,16 @@
 import jakarta.ws.rs.client.WebTarget;
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 import java.util.logging.Logger;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -47,7 +51,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
     }
 
 
@@ -67,13 +71,11 @@
 
     @Test
     public void testPostError() {
-        WebTarget r = target("test");
+        final WebTarget target = target("test");
 
         for (int i = 0; i < 100; i++) {
-            try {
-                r.request().post(Entity.text("POST"));
-            } catch (ClientErrorException ex) {
-            }
+            final Response resp = target.request().post(Entity.text("POST"));
+            assertEquals(500, resp.getStatus());
         }
     }
 
@@ -92,13 +94,18 @@
     }
 
     @Test
-    public void testPostErrorAsync() {
-        WebTarget r = target("test");
+    public void testPostErrorAsync() throws ExecutionException, InterruptedException {
+        final WebTarget target = target("test");
+
+        final List<Future<Response>> responses = new ArrayList<>(100);
 
         for (int i = 0; i < 100; i++) {
-            try {
-                r.request().async().post(Entity.text("POST"));
-            } catch (ClientErrorException ex) {
+                responses.add(target.request().async().post(Entity.text("POST")));
+        }
+        for (int i = responses.size() - 1; i >= 0;) {
+            if (responses.get(i).isDone()) {
+                assertEquals(500, responses.remove(i).get().getStatus());
+                i--;
             }
         }
     }
@@ -116,4 +123,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/FirstByteCachingStreamTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/FirstByteCachingStreamTest.java
new file mode 100644
index 0000000..b6119f5
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/FirstByteCachingStreamTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+
+class FirstByteCachingStreamTest {
+    private static InputStream createFirstByteCachingStream(InputStream inner) throws Exception {
+        Class[] classes = JavaNetHttpConnector.class.getDeclaredClasses();
+        for (Class<?> clazz : classes) {
+            if (clazz.getName().contains("FirstByteCachingStream")) {
+                Constructor constructor = clazz.getDeclaredConstructor(InputStream.class);
+                constructor.setAccessible(true);
+                return (InputStream) constructor.newInstance(inner);
+            }
+        }
+        throw new IllegalArgumentException("JavaNetHttpConnector inner class FirstByteCachingStream not found");
+    }
+
+    @Test
+    void testNoByte() throws Exception {
+        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(new byte[0]);
+        InputStream testIs = createFirstByteCachingStream(byteArrayInputStream);
+        Assertions.assertEquals(0, testIs.available());
+    }
+
+    @Test
+    void testOneByte() throws Exception {
+        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(new byte[]{'A'});
+        InputStream testIs = createFirstByteCachingStream(byteArrayInputStream);
+        Assertions.assertEquals(1, testIs.available());
+        Assertions.assertEquals(1, testIs.available()); // idempotency
+        Assertions.assertEquals('A', testIs.read());
+        Assertions.assertEquals(0, testIs.available());
+    }
+
+    @Test
+    void testTwoBytes() throws Exception {
+        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(new byte[]{'A', 'B'});
+        InputStream testIs = createFirstByteCachingStream(byteArrayInputStream);
+        Assertions.assertEquals(2, testIs.available());
+        Assertions.assertEquals(2, testIs.available()); // idempotency
+        Assertions.assertEquals('A', testIs.read());
+        Assertions.assertEquals(1, testIs.available());
+        Assertions.assertEquals(1, testIs.available()); // idempotency
+        Assertions.assertEquals('B', testIs.read());
+        Assertions.assertEquals(0, testIs.available());
+    }
+
+    @Test
+    void testTwoBytesReadAtOnce() throws Exception {
+        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(new byte[]{'A', 'B'});
+        InputStream testIs = createFirstByteCachingStream(byteArrayInputStream);
+        Assertions.assertEquals(2, testIs.available());
+
+        byte[] bytes = new byte[2];
+        testIs.read(bytes);
+        Assertions.assertEquals('A', bytes[0]);
+        Assertions.assertEquals('B', bytes[1]);
+        Assertions.assertEquals(0, testIs.available());
+    }
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/FollowRedirectsTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/FollowRedirectsTest.java
similarity index 88%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/FollowRedirectsTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/FollowRedirectsTest.java
index 2604f9b..f6432a3 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/FollowRedirectsTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/FollowRedirectsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,15 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
-
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.client.ClientResponse;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+package org.glassfish.jersey.jnh.connector;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
@@ -35,12 +27,21 @@
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.UriBuilder;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientResponse;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
 import java.io.IOException;
 import java.net.URI;
 import java.util.logging.Logger;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+
 public class FollowRedirectsTest extends JerseyTest {
 
     private static final Logger LOGGER = Logger.getLogger(FollowRedirectsTest.class.getName());
@@ -69,7 +70,7 @@
     @Override
     protected void configureClient(ClientConfig config) {
         config.property(ClientProperties.FOLLOW_REDIRECTS, false);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
     }
 
     private static class RedirectTestFilter implements ClientResponseFilter {
@@ -88,7 +89,7 @@
     public void testDoFollow() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
         Client c = ClientBuilder.newClient(config);
         WebTarget t = c.target(u);
         Response r = t.path("test/redirect")
@@ -96,6 +97,11 @@
                 .request().get();
         assertEquals(200, r.getStatus());
         assertEquals("GET", r.readEntity(String.class));
+// TODO uncomment as part of JERSEY-2388 fix.
+//        assertEquals(
+//                UriBuilder.fromUri(getBaseUri()).path(RedirectResource.class).build().toString(),
+//                r.getHeaderString(RedirectTestFilter.RESOLVED_URI_HEADER));
+
         c.close();
     }
 
@@ -118,7 +124,7 @@
     public void testDontFollowPerRequestOverride() {
         final URI u = target().getUri();
         ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
         Client client = ClientBuilder.newClient(config);
         WebTarget t = client.target(u);
         t.property(ClientProperties.FOLLOW_REDIRECTS, false);
@@ -126,4 +132,4 @@
         assertEquals(303, r.getStatus());
         client.close();
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/GZIPContentEncodingTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/GZIPContentEncodingTest.java
similarity index 88%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/GZIPContentEncodingTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/GZIPContentEncodingTest.java
index 29bb444..8d94f25 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/GZIPContentEncodingTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/GZIPContentEncodingTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,15 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
-
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.message.GZipEncoder;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+package org.glassfish.jersey.jnh.connector;
 
 import jakarta.ws.rs.POST;
 import jakarta.ws.rs.Path;
@@ -33,6 +25,14 @@
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.message.GZipEncoder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
 import java.util.Arrays;
 import java.util.logging.Logger;
 
@@ -40,7 +40,7 @@
 
 public class GZIPContentEncodingTest extends JerseyTest {
 
-    private static final Logger LOGGER = Logger.getLogger(EntityTest.class.getName());
+    private static final Logger LOGGER = Logger.getLogger(GZIPContentEncodingTest.class.getName());
 
     @Path("/")
     public static class Resource {
@@ -61,13 +61,14 @@
     @Override
     protected void configureClient(ClientConfig config) {
         config.register(GZipEncoder.class);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
     }
 
     @Test
     public void testPost() {
         WebTarget r = target();
         byte[] content = new byte[1024 * 1024];
+        content[0] = 1;
         assertTrue(Arrays.equals(content,
                 r.request().post(Entity.entity(content, MediaType.APPLICATION_OCTET_STREAM_TYPE)).readEntity(byte[].class)));
 
@@ -80,7 +81,7 @@
     public void testPostChunked() {
         ClientConfig config = new ClientConfig();
         config.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024);
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
 
         Client client = ClientBuilder.newClient(config);
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HelloWorldTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HelloWorldTest.java
similarity index 64%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HelloWorldTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HelloWorldTest.java
index ac6870a..5143ec7 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HelloWorldTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HelloWorldTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,19 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jnh.connector;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.client.InvocationCallback;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -22,20 +34,6 @@
 import org.glassfish.jersey.test.JerseyTest;
 import org.junit.jupiter.api.Test;
 
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.ClientBuilder;
-import jakarta.ws.rs.client.InvocationCallback;
-import jakarta.ws.rs.client.WebTarget;
-import jakarta.ws.rs.core.Application;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
-
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -65,7 +63,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
     }
 
     @Test
@@ -157,64 +155,4 @@
         response.close();
     }
 
-    @Test
-    public void testLoggingFilterClientClass() {
-        Client client = client();
-        client.register(CustomLoggingFilter.class).property("foo", "bar");
-        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
-        String s = target().path(ROOT_PATH).request().get(String.class);
-        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
-        assertEquals(1, CustomLoggingFilter.preFilterCalled);
-        assertEquals(1, CustomLoggingFilter.postFilterCalled);
-        client.close();
-    }
-
-    @Test
-    public void testLoggingFilterClientInstance() {
-        Client client = client();
-        client.register(new CustomLoggingFilter()).property("foo", "bar");
-        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
-        String s = target().path(ROOT_PATH).request().get(String.class);
-        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
-        assertEquals(1, CustomLoggingFilter.preFilterCalled);
-        assertEquals(1, CustomLoggingFilter.postFilterCalled);
-        client.close();
-    }
-
-    @Test
-    public void testLoggingFilterTargetClass() {
-        WebTarget target = target().path(ROOT_PATH);
-        target.register(CustomLoggingFilter.class).property("foo", "bar");
-        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
-        String s = target.request().get(String.class);
-        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
-        assertEquals(1, CustomLoggingFilter.preFilterCalled);
-        assertEquals(1, CustomLoggingFilter.postFilterCalled);
-    }
-
-    @Test
-    public void testLoggingFilterTargetInstance() {
-        WebTarget target = target().path(ROOT_PATH);
-        target.register(new CustomLoggingFilter()).property("foo", "bar");
-        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
-        String s = target.request().get(String.class);
-        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
-        assertEquals(1, CustomLoggingFilter.preFilterCalled);
-        assertEquals(1, CustomLoggingFilter.postFilterCalled);
-    }
-
-    @Test
-    public void testConfigurationUpdate() {
-        Client client1 = client();
-        client1.register(CustomLoggingFilter.class).property("foo", "bar");
-
-        Client client = ClientBuilder.newClient(client1.getConfiguration());
-        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
-        String s = target().path(ROOT_PATH).request().get(String.class);
-        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
-        assertEquals(1, CustomLoggingFilter.preFilterCalled);
-        assertEquals(1, CustomLoggingFilter.postFilterCalled);
-        client.close();
-    }
-
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/Http2PresenceTest.java
similarity index 71%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/Http2PresenceTest.java
index cb3b319..a2eaa3b 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/Http2PresenceTest.java
@@ -14,43 +14,38 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jnh.connector;
 
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
 import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.spi.ConnectorProvider;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.junit.jupiter.api.Test;
 
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.HeaderParam;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.Application;
-import jakarta.ws.rs.core.Context;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.Response;
+import java.net.http.HttpClient;
 import java.util.List;
 import java.util.logging.Logger;
 
+import static java.net.http.HttpClient.Version.HTTP_2;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-public class HttpHeadersTest extends JerseyTest {
+/**
+ * Tests the HTTP2 presence.
+ *
+ */
+public class Http2PresenceTest extends JerseyTest {
 
-    private static final Logger LOGGER = Logger.getLogger(HttpHeadersTest.class.getName());
+    private static final Logger LOGGER = Logger.getLogger(Http2PresenceTest.class.getName());
 
     @Path("/test")
     public static class HttpMethodResource {
-        @POST
-        public String post(
-                @HeaderParam("Transfer-Encoding") String transferEncoding,
-                @HeaderParam("X-CLIENT") String xClient,
-                @HeaderParam("X-WRITER") String xWriter,
-                String entity) {
-            assertEquals("client", xClient);
-            return "POST";
-        }
 
         @GET
         public String testUserAgent(@Context HttpHeaders httpHeaders) {
@@ -71,15 +66,16 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.property(JavaNetHttpClientProperties.HTTP_VERSION, HTTP_2).connectorProvider(new JavaNetHttpConnectorProvider());
     }
 
     @Test
-    public void testPost() {
-        Response response = target().path("test").request().header("X-CLIENT", "client").post(null);
+    public void testHttp2Presence() {
+        final ConnectorProvider provider = ((ClientConfig) target().getConfiguration()).getConnectorProvider();
+        assertTrue(provider instanceof JavaNetHttpConnectorProvider);
 
-        assertEquals(200, response.getStatus());
-        assertTrue(response.hasEntity());
+        final HttpClient client = ((JavaNetHttpConnectorProvider) provider).getHttpClient(target());
+        assertEquals(HTTP_2, client.version());
     }
 
     /**
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HttpHeadersTest.java
similarity index 83%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HttpHeadersTest.java
index cb3b319..550183c 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/HttpHeadersTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HttpHeadersTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,13 +14,15 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jnh.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.HeaderParam;
@@ -30,8 +32,7 @@
 import jakarta.ws.rs.core.Context;
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.Response;
-import java.util.List;
-import java.util.logging.Logger;
+import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -44,10 +45,10 @@
     public static class HttpMethodResource {
         @POST
         public String post(
-                @HeaderParam("Transfer-Encoding") String transferEncoding,
-                @HeaderParam("X-CLIENT") String xClient,
-                @HeaderParam("X-WRITER") String xWriter,
-                String entity) {
+            @HeaderParam("Transfer-Encoding") String transferEncoding,
+            @HeaderParam("X-CLIENT") String xClient,
+            @HeaderParam("X-WRITER") String xWriter,
+            String entity) {
             assertEquals("client", xClient);
             return "POST";
         }
@@ -71,7 +72,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
     }
 
     @Test
@@ -88,6 +89,7 @@
     @Test
     public void testUserAgent() {
         String response = target().path("test").request().get(String.class);
-        assertTrue(response.startsWith("Jersey"), "User-agent header should start with 'Jersey', but was " + response);
+        assertTrue(response.startsWith("Jersey"),
+                "User-agent header should start with 'Jersey', but was " + response);
     }
 }
\ No newline at end of file
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HttpsTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HttpsTest.java
new file mode 100644
index 0000000..4f6a035
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HttpsTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import java.net.URI;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory;
+import org.glassfish.jersey.test.spi.TestContainerFactory;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.UriBuilder;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class HttpsTest extends JerseyTest {
+
+    private static final Logger LOGGER = Logger.getLogger(HttpsTest.class.getName());
+    private static final String ROOT_PATH = "test";
+
+    @Path(ROOT_PATH)
+    public static class Resource {
+        @GET
+        public String get() {
+            return "GET";
+        }
+    }
+
+    @Override
+    protected TestContainerFactory getTestContainerFactory() {
+        return new GrizzlyTestContainerFactory();
+    }
+
+    @Override
+    protected URI getBaseUri() {
+        return UriBuilder.fromUri("https://localhost").port(getPort()).build();
+    }
+
+    @Override
+    protected Application configure() {
+        ResourceConfig config = new ResourceConfig(Resource.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        return config;
+    }
+
+    @Override
+    protected Optional<SSLContext> getSslContext() {
+        return Optional.of(SslUtils.createServerSslContext(true, true));
+    }
+
+    @Override
+    protected Optional<SSLParameters> getSslParameters() {
+        SSLParameters serverSslParameters = new SSLParameters();
+        serverSslParameters.setNeedClientAuth(true);
+        return Optional.of(serverSslParameters);
+    }
+
+    private SSLContext clientSslContext() {
+        return SslUtils.createClientSslContext(true, true);
+    }
+
+    @Test
+    public void testConnection() {
+        ClientConfig cc = new ClientConfig()
+                .connectorProvider(new JavaNetHttpConnectorProvider());
+        Client client = ClientBuilder.newBuilder()
+            .withConfig(cc)
+            .sslContext(clientSslContext())
+            .register(LoggingFeature.class)
+            .build();
+        Response response = client.target(getBaseUri()).path(ROOT_PATH).request().get();
+        assertEquals(200, response.getStatus());
+        assertEquals("GET", response.readEntity(String.class));
+    }
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ManagedClientTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ManagedClientTest.java
similarity index 92%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ManagedClientTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ManagedClientTest.java
index 215408b..8eca289 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/ManagedClientTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ManagedClientTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jnh.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -22,7 +22,14 @@
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.server.Uri;
 import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
@@ -38,13 +45,7 @@
 import jakarta.ws.rs.core.FeatureContext;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
-import java.io.IOException;
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.logging.Logger;
+import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
@@ -91,12 +92,12 @@
             /**
              * Expected custom header name to be validated by the {@link CustomHeaderFilter}.
              */
-            public String headerName();
+            String headerName();
 
             /**
              * Expected custom header value to be validated by the {@link CustomHeaderFilter}.
              */
-            public String headerValue();
+            String headerValue();
         }
 
         @Override
@@ -135,10 +136,10 @@
         public void filter(ContainerRequestContext ctx) throws IOException { // validate
             if (!headerValue.equals(ctx.getHeaderString(headerName))) {
                 ctx.abortWith(Response.status(Response.Status.FORBIDDEN)
-                        .type(MediaType.TEXT_PLAIN)
-                        .entity(String
-                                .format("Expected header '%s' not present or value not equal to '%s'", headerName, headerValue))
-                        .build());
+                                  .type(MediaType.TEXT_PLAIN)
+                                  .entity(String
+                                  .format("Expected header '%s' not present or value not equal to '%s'", headerName, headerValue))
+                                  .build());
             }
         }
 
@@ -204,7 +205,7 @@
     @Override
     protected Application configure() {
         ResourceConfig config = new ResourceConfig(PublicResource.class, InternalResource.class, CustomHeaderFeature.class)
-                .property(ClientA.class.getName() + ".baseUri", this.getBaseUri().toString() + "internal");
+            .property(ClientA.class.getName() + ".baseUri", this.getBaseUri().toString() + "internal");
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
         return config;
     }
@@ -225,7 +226,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
     }
 
     /**
@@ -247,4 +248,4 @@
         assertEquals("b", response.readEntity(String.class));
     }
 
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/MethodTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/MethodTest.java
similarity index 95%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/MethodTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/MethodTest.java
index 8412c41..a4837ee 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/MethodTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/MethodTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,13 +14,15 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jnh.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.DELETE;
 import jakarta.ws.rs.GET;
@@ -32,8 +34,7 @@
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
-import java.util.concurrent.ExecutionException;
-import java.util.logging.Logger;
+import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
@@ -80,7 +81,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
     }
 
     @Test
@@ -143,4 +144,4 @@
         assertEquals(200, response.getStatus());
         response.close();
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/NoEntityTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/NoEntityTest.java
similarity index 71%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/NoEntityTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/NoEntityTest.java
index 1c14296..6635a61 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/NoEntityTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/NoEntityTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,13 +14,15 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jnh.connector;
 
+import jakarta.ws.rs.core.GenericType;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.POST;
@@ -28,7 +30,7 @@
 import jakarta.ws.rs.client.WebTarget;
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.Response;
-import java.util.logging.Logger;
+import org.junit.jupiter.api.Test;
 
 public class NoEntityTest extends JerseyTest {
     private static final Logger LOGGER = Logger.getLogger(NoEntityTest.class.getName());
@@ -43,6 +45,13 @@
         @POST
         public void post(String entity) {
         }
+
+        @GET
+        @Path("/success")
+        public Response getSuccessfully() {
+            return Response.status(Response.Status.NO_CONTENT).build();
+        }
+
     }
 
     @Override
@@ -54,7 +63,7 @@
 
     @Override
     protected void configureClient(ClientConfig config) {
-        config.connectorProvider(new JettyHttp2ConnectorProvider());
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
     }
 
     @Test
@@ -77,6 +86,32 @@
     }
 
     @Test
+    public void testGetVoidWithClose() {
+        WebTarget r = target("test");
+        for (int i = 0; i < 5; i++) {
+            Response cr = r.request().get();
+            cr.close();
+        }
+    }
+
+    @Test
+    public void testGetVoid() {
+        WebTarget r = target("test/success");
+        for (int i = 0; i < 5; i++) {
+            r.request().get(void.class);
+        }
+    }
+
+    @Test
+    public void testGetGenericVoid() {
+        WebTarget r = target("test/success");
+        for (int i = 0; i < 5; i++) {
+            r.request().get(new GenericType<Void>() {
+            });
+        }
+    }
+
+    @Test
     public void testPost() {
         WebTarget r = target("test");
         for (int i = 0; i < 5; i++) {
@@ -92,4 +127,4 @@
             cr.close();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/OptionsMethodTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/OptionsMethodTest.java
new file mode 100644
index 0000000..a333bd1
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/OptionsMethodTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import jakarta.ws.rs.core.Response;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Checks, that an {@code OPTIONS} request may be sent to a {@code GET} endpoint.
+ */
+public class OptionsMethodTest extends AbstractJavaConnectorTest {
+    /**
+     * Sends an {@code OPTIONS} request to the root {@code GET} endpoint and assumes a code 200.
+     */
+    @Test
+    public void testOptionsMethod() {
+        assertThat(this.requestWithEntity("java-connector", "OPTIONS", null).getStatus())
+                .isEqualTo(Response.Status.OK.getStatusCode());
+    }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/RedirectTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/RedirectTest.java
new file mode 100644
index 0000000..e1edc24
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/RedirectTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientProperties;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Checks that the connector provider correctly handles redirects.
+ */
+public class RedirectTest extends AbstractJavaConnectorTest {
+    /**
+     * Checks, that without further configuration redirects are taken.
+     */
+    @Test
+    public void testRedirect() {
+        assertThat(this.request("java-connector/redirect").readEntity(String.class)).isEqualTo("Hello World!");
+    }
+
+    /**
+     * Checks, that no redirect happens, if the redirects are switched off.
+     */
+    @Test
+    public void testNotFollowRedirects() {
+        Response response = target().path("java-connector").path("redirect")
+                .property(ClientProperties.FOLLOW_REDIRECTS, false)
+                .request()
+                .get();
+        assertThat(response.getStatus()).isEqualTo(Response.Status.SEE_OTHER.getStatusCode());
+    }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/RetrieveHttpClientFromConnectorProviderTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/RetrieveHttpClientFromConnectorProviderTest.java
new file mode 100644
index 0000000..8592bd7
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/RetrieveHttpClientFromConnectorProviderTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import org.junit.jupiter.api.Test;
+
+import java.net.http.HttpClient;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests access to the {@link HttpClient} instance provided from the {@link JavaNetHttpConnectorProvider}.
+ */
+public class RetrieveHttpClientFromConnectorProviderTest extends AbstractJavaConnectorTest {
+    /**
+     * Checks, that the {@link jakarta.ws.rs.client.Client} and {@link jakarta.ws.rs.client.WebTarget} instances
+     * correctly return the internally used {@link HttpClient}.
+     */
+    @Test
+    public void testClientUsesJavaConnector() {
+        assertThat(JavaNetHttpConnectorProvider.getHttpClient(client())).isInstanceOf(HttpClient.class);
+        assertThat(JavaNetHttpConnectorProvider.getHttpClient(target())).isInstanceOf(HttpClient.class);
+        assertThat(JavaNetHttpConnectorProvider.getHttpClient(client()))
+                .isEqualTo(JavaNetHttpConnectorProvider.getHttpClient(target()));
+    }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/SslUtils.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/SslUtils.java
new file mode 100644
index 0000000..469959a
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/SslUtils.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.InputStream;
+import java.security.KeyStore;
+
+public final class SslUtils {
+
+    private static final String SERVER_IDENTITY_PATH = "server-identity.jks";
+    private static final char[] SERVER_IDENTITY_PASSWORD = "secret".toCharArray();
+    private static final String SERVER_TRUSTSTORE_PATH = "server-truststore.jks";
+    private static final char[] SERVER_TRUSTSTORE_PASSWORD = "secret".toCharArray();
+
+    private static final String CLIENT_IDENTITY_PATH = "client-identity.jks";
+    private static final char[] CLIENT_IDENTITY_PASSWORD = "secret".toCharArray();
+    private static final String CLIENT_TRUSTSTORE_PATH = "client-truststore.jks";
+    private static final char[] CLIENT_TRUSTSTORE_PASSWORD = "secret".toCharArray();
+
+    private static final String KEYSTORE_TYPE = "PKCS12";
+
+    private SslUtils() {}
+
+    public static SSLContext createServerSslContext(boolean includeKeyMaterial, boolean includeTrustMaterial) {
+        return createSslContext(
+                includeKeyMaterial,
+                includeTrustMaterial,
+                SERVER_IDENTITY_PATH,
+                SERVER_IDENTITY_PASSWORD,
+                SERVER_TRUSTSTORE_PATH,
+                SERVER_TRUSTSTORE_PASSWORD
+        );
+    }
+
+    public static SSLContext createClientSslContext(boolean includeKeyMaterial, boolean includeTrustMaterial) {
+        return createSslContext(
+                includeKeyMaterial,
+                includeTrustMaterial,
+                CLIENT_IDENTITY_PATH,
+                CLIENT_IDENTITY_PASSWORD,
+                CLIENT_TRUSTSTORE_PATH,
+                CLIENT_TRUSTSTORE_PASSWORD
+        );
+    }
+
+    private static SSLContext createSslContext(
+            boolean includeKeyMaterial,
+            boolean includeTrustMaterial,
+            String keyStorePath,
+            char[] keyStorePassword,
+            String trustStorePath,
+            char[] trustStorePassword) {
+
+        try {
+            KeyManager[] keyManagers = null;
+            TrustManager[] trustManagers = null;
+
+            if (includeKeyMaterial) {
+                keyManagers = createKeyManagers(keyStorePath, keyStorePassword);
+            }
+
+            if (includeTrustMaterial) {
+                trustManagers = createTrustManagers(trustStorePath, trustStorePassword);
+            }
+
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(keyManagers, trustManagers, null);
+            return sslContext;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static TrustManager[] createTrustManagers(String keyStorePath, char[] keyStorePassword) throws Exception {
+        KeyStore trustStore = getKeyStore(keyStorePath, keyStorePassword);
+
+        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        trustManagerFactory.init(trustStore);
+        return trustManagerFactory.getTrustManagers();
+    }
+
+    private static KeyManager[] createKeyManagers(String keyStorePath, char[] keyStorePassword) throws Exception {
+        KeyStore keyStore = getKeyStore(keyStorePath, keyStorePassword);
+
+        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+        keyManagerFactory.init(keyStore, keyStorePassword);
+        return keyManagerFactory.getKeyManagers();
+    }
+
+    private static KeyStore getKeyStore(String path, char[] keyStorePassword) throws Exception {
+        try (InputStream inputStream = getResource(path)) {
+            KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
+            keyStore.load(inputStream, keyStorePassword);
+            return keyStore;
+        }
+    }
+
+    private static InputStream getResource(String path) {
+        return SslUtils.class.getClassLoader().getResourceAsStream(path);
+    }
+
+}
\ No newline at end of file
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/TimeoutTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/TimeoutTest.java
new file mode 100644
index 0000000..b32f122
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/TimeoutTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import java.net.URI;
+import java.net.http.HttpTimeoutException;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.fail;
+
+public class TimeoutTest extends JerseyTest {
+    private static final Logger LOGGER = Logger.getLogger(TimeoutTest.class.getName());
+
+    @Path("/test")
+    public static class TimeoutResource {
+        @GET
+        public String get() {
+            return "GET";
+        }
+
+        @GET
+        @Path("timeout")
+        public String getTimeout() {
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            return "GET";
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        ResourceConfig config = new ResourceConfig(TimeoutResource.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        return config;
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
+    }
+
+    @Test
+    public void testFast() {
+        Response r = target("test").request().get();
+        assertEquals(200, r.getStatus());
+        assertEquals("GET", r.readEntity(String.class));
+    }
+
+    @Test
+    public void testSlow() {
+        final URI u = target().getUri();
+        ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
+        Client c = ClientBuilder.newClient(config);
+        WebTarget t = c.target(u);
+        try {
+            t.path("test/timeout").request().get();
+            fail("Timeout expected.");
+        } catch (ProcessingException e) {
+            assertInstanceOf(HttpTimeoutException.class, e.getCause(),
+                    "Unexpected processing exception cause");
+        } finally {
+            c.close();
+        }
+    }
+
+    @Test
+    public void testTimeoutInRequest() {
+        final URI u = target().getUri();
+        ClientConfig config = new ClientConfig();
+        config.connectorProvider(new JavaNetHttpConnectorProvider());
+        Client c = ClientBuilder.newClient(config);
+        WebTarget t = c.target(u);
+        try {
+            t.path("test/timeout").request().property(ClientProperties.READ_TIMEOUT, 1_000).get();
+            fail("Timeout expected.");
+        } catch (ProcessingException e) {
+            assertInstanceOf(HttpTimeoutException.class, e.getCause(),
+                    "Unexpected processing exception cause");
+        } finally {
+            c.close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TraceSupportTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/TraceSupportTest.java
similarity index 90%
copy from connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TraceSupportTest.java
copy to connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/TraceSupportTest.java
index 4bf0bda..b8a079a 100644
--- a/connectors/jetty-http2-connector/src/test/java/org/glassfish/jersey/jetty/http2/connector/TraceSupportTest.java
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/TraceSupportTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2.connector;
+package org.glassfish.jersey.jnh.connector;
 
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -23,7 +23,14 @@
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.server.model.Resource;
 import org.glassfish.jersey.test.JerseyTest;
-import org.junit.jupiter.api.Test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
 
 import jakarta.ws.rs.HttpMethod;
 import jakarta.ws.rs.Path;
@@ -37,13 +44,7 @@
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Request;
 import jakarta.ws.rs.core.Response;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
+import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -102,10 +103,10 @@
     }
 
     private String[] expectedFragmentsProgrammatic = new String[]{
-            "TRACE http://localhost:" + this.getPort() + "/tracing/programmatic"
+        "TRACE http://localhost:" + this.getPort() + "/tracing/programmatic"
     };
     private String[] expectedFragmentsAnnotated = new String[]{
-            "TRACE http://localhost:" + this.getPort() + "/tracing/annotated"
+        "TRACE http://localhost:" + this.getPort() + "/tracing/annotated"
     };
 
     private WebTarget prepareTarget(String path) {
@@ -122,9 +123,10 @@
 
         String responseEntity = response.readEntity(String.class);
         for (String expectedFragment : expectedFragmentsProgrammatic) {
-            assertTrue(// toLowerCase - http header field names are case insensitive
-                    responseEntity.contains(expectedFragment),
-                    "Expected fragment '" + expectedFragment + "' not found in response:\n" + responseEntity);
+            assertTrue(
+                    // toLowerCase - http header field names are case insensitive
+                    responseEntity.contains(expectedFragment), "Expected fragment '"
+                            + expectedFragment + "' not found in response:\n" + responseEntity);
         }
     }
 
@@ -136,8 +138,8 @@
 
         String responseEntity = response.readEntity(String.class);
         for (String expectedFragment : expectedFragmentsAnnotated) {
-            assertTrue(// toLowerCase - http header field names are case insensitive
-                    responseEntity.contains(expectedFragment),
+            assertTrue(responseEntity.contains(expectedFragment),
+                    // toLowerCase - http header field names are case insensitive
                     "Expected fragment '" + expectedFragment + "' not found in response:\n" + responseEntity);
         }
     }
@@ -183,7 +185,7 @@
     }
 
     private Client getJettyClient() {
-        return ClientBuilder.newClient(new ClientConfig().connectorProvider(new JettyHttp2ConnectorProvider()));
+        return ClientBuilder.newClient(new ClientConfig().connectorProvider(new JavaNetHttpConnectorProvider()));
     }
 
 
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/UnderlyingHttpClientAccessTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/UnderlyingHttpClientAccessTest.java
new file mode 100644
index 0000000..8bf9f46
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/UnderlyingHttpClientAccessTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jnh.connector;
+
+import org.glassfish.jersey.client.ClientConfig;
+
+import java.net.http.HttpClient;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+public class UnderlyingHttpClientAccessTest {
+
+    @Test
+    public void testHttpClientInstanceAccess() {
+        final Client client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new JavaNetHttpConnectorProvider()));
+        final HttpClient hcOnClient = JavaNetHttpConnectorProvider.getHttpClient(client);
+        // important: the web target instance in this test must be only created AFTER the client has been pre-initialized
+        // (see org.glassfish.jersey.client.Initializable.preInitialize method). This is here achieved by calling the
+        // connector provider's static getHttpClient method above.
+        final WebTarget target = client.target("http://localhost/");
+        final HttpClient hcOnTarget = JavaNetHttpConnectorProvider.getHttpClient(target);
+
+        assertNotNull(hcOnClient, "HTTP client instance set on JerseyClient should not be null.");
+        assertNotNull(hcOnTarget, "HTTP client instance set on JerseyWebTarget should not be null.");
+        assertSame(hcOnClient, hcOnTarget,
+                "HTTP client instance set on JerseyClient should be the same instance as the one set on JerseyWebTarget"
+                   + "(provided the target instance has not been further configured)."
+        );
+    }
+
+}
\ No newline at end of file
diff --git a/connectors/jnh-connector/src/test/resources/client-identity.jks b/connectors/jnh-connector/src/test/resources/client-identity.jks
new file mode 100644
index 0000000..d3922a1
--- /dev/null
+++ b/connectors/jnh-connector/src/test/resources/client-identity.jks
Binary files differ
diff --git a/connectors/jnh-connector/src/test/resources/client-truststore.jks b/connectors/jnh-connector/src/test/resources/client-truststore.jks
new file mode 100644
index 0000000..539185f
--- /dev/null
+++ b/connectors/jnh-connector/src/test/resources/client-truststore.jks
Binary files differ
diff --git a/connectors/jnh-connector/src/test/resources/server-identity.jks b/connectors/jnh-connector/src/test/resources/server-identity.jks
new file mode 100644
index 0000000..76a21aa
--- /dev/null
+++ b/connectors/jnh-connector/src/test/resources/server-identity.jks
Binary files differ
diff --git a/connectors/jnh-connector/src/test/resources/server-truststore.jks b/connectors/jnh-connector/src/test/resources/server-truststore.jks
new file mode 100644
index 0000000..22285ab
--- /dev/null
+++ b/connectors/jnh-connector/src/test/resources/server-truststore.jks
Binary files differ
diff --git a/connectors/netty-connector/pom.xml b/connectors/netty-connector/pom.xml
index 2da917f..a4a5ee4 100644
--- a/connectors/netty-connector/pom.xml
+++ b/connectors/netty-connector/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.connectors</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-netty-connector</artifactId>
diff --git a/connectors/pom.xml b/connectors/pom.xml
index 49c9ecf..ad4afa3 100644
--- a/connectors/pom.xml
+++ b/connectors/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.connectors</groupId>
@@ -40,7 +40,9 @@
         <module>helidon-connector</module>
         <module>jdk-connector</module>
         <module>jetty-connector</module>
-        <module>jetty-http2-connector</module>
+        <module>jetty11-http2-connector</module>
+        <module>jetty11-connector</module>
+        <module>jnh-connector</module>
         <module>netty-connector</module>
     </modules>
 
diff --git a/containers/glassfish/jersey-gf-ejb/pom.xml b/containers/glassfish/jersey-gf-ejb/pom.xml
index 84b147d..0189bdb 100644
--- a/containers/glassfish/jersey-gf-ejb/pom.xml
+++ b/containers/glassfish/jersey-gf-ejb/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers.glassfish</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-gf-ejb</artifactId>
@@ -61,6 +61,26 @@
             <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
+        <!-- TODO remove versions when org.glassfish.exousia:exousia:jar in central-->
+        <dependency>
+            <groupId>org.glassfish.main.ejb</groupId>
+            <artifactId>ejb-container</artifactId>
+            <version>6.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>container-common</artifactId>
+            <version>6.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.main.hk2</groupId>
+            <artifactId>hk2-config</artifactId>
+            <version>6.0.0</version>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
     </dependencies>
 
     <build>
@@ -111,59 +131,4 @@
             </plugin>
         </plugins>
     </build>
-
-    <profiles>
-        <profile>
-            <id>jdk8</id>
-            <activation>
-                <jdk>1.8</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>org.glassfish.main.ejb</groupId>
-                    <artifactId>ejb-container</artifactId>
-                    <version>6.0.0</version>
-                    <scope>provided</scope>
-                </dependency>
-                <dependency>
-                    <groupId>org.glassfish.main.common</groupId>
-                    <artifactId>container-common</artifactId>
-                    <version>6.0.0</version>
-                    <scope>provided</scope>
-                </dependency>
-                <dependency>
-                    <groupId>org.glassfish.main.hk2</groupId>
-                    <artifactId>hk2-config</artifactId>
-                    <version>6.0.0</version>
-                    <scope>provided</scope>
-                    <optional>true</optional>
-                </dependency>
-            </dependencies>
-        </profile>
-        <profile>
-            <id>jdk11</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>org.glassfish.main.ejb</groupId>
-                    <artifactId>ejb-container</artifactId>
-                    <scope>provided</scope>
-                </dependency>
-                <dependency>
-                    <groupId>org.glassfish.main.common</groupId>
-                    <artifactId>container-common</artifactId>
-                    <scope>provided</scope>
-                </dependency>
-                <dependency>
-                    <groupId>org.glassfish.main.hk2</groupId>
-                    <artifactId>hk2-config</artifactId>
-                    <scope>provided</scope>
-                    <optional>true</optional>
-                </dependency>
-            </dependencies>
-        </profile>
-    </profiles>
-
-</project>
+ </project>
diff --git a/containers/glassfish/pom.xml b/containers/glassfish/pom.xml
index 5e70c3a..011e493 100644
--- a/containers/glassfish/pom.xml
+++ b/containers/glassfish/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.containers.glassfish</groupId>
diff --git a/containers/grizzly2-http/pom.xml b/containers/grizzly2-http/pom.xml
index 36723d6..8d3dbd1 100644
--- a/containers/grizzly2-http/pom.xml
+++ b/containers/grizzly2-http/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-container-grizzly2-http</artifactId>
@@ -50,6 +50,11 @@
             <groupId>org.glassfish.grizzly</groupId>
             <artifactId>grizzly-http-server</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <scope>test</scope>
+        </dependency>
 
         <dependency>
             <groupId>org.glassfish.grizzly</groupId>
@@ -69,7 +74,7 @@
         </dependency>
         <dependency>
             <groupId>org.eclipse.jetty.http2</groupId>
-            <artifactId>http2-http-client-transport</artifactId>
+            <artifactId>jetty-http2-client-transport</artifactId>
             <version>${jetty.version}</version>
             <scope>test</scope>
         </dependency>
@@ -102,6 +107,15 @@
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                 <inherited>true</inherited>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            org.glassfish.grizzly.*;version="[3.0,5.0)",
+                            *
+                        </Import-Package>
+                    </instructions>
+                    <unpackBundle>true</unpackBundle>
+                </configuration>
             </plugin>
 
             <plugin>
@@ -136,7 +150,7 @@
         <profile>
             <id>jdk11</id>
             <activation>
-                <jdk>[11,)</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <build>
                 <pluginManagement>
@@ -147,35 +161,6 @@
                                 <execution>
                                     <id>default-testCompile</id>
                                     <configuration>
-                                        <source>11</source>
-                                        <target>11</target>
-                                    </configuration>
-                                </execution>
-                            </executions>
-                        </plugin>
-                    </plugins>
-                </pluginManagement>
-            </build>
-        </profile>
-        <profile>
-            <id>jdk8</id>
-            <activation>
-                <jdk>1.8</jdk>
-            </activation>
-            <build>
-                <pluginManagement>
-                    <plugins>
-                        <plugin>
-                            <artifactId>maven-compiler-plugin</artifactId>
-                            <executions>
-                                <execution>
-                                    <id>default-testCompile</id>
-                                    <configuration>
-                                        <!--
-                                        Jetty client is not compatible with JDK8, older versions need different setup
-                                        JDK HTTP client is not in JDK8 at all
-                                        Jersey Client doesn't support HTTP/2 (at least not directly)
-                                        -->
                                         <skip>true</skip>
                                     </configuration>
                                 </execution>
diff --git a/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpContainer.java b/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpContainer.java
index d0f65c3..33d3770 100644
--- a/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpContainer.java
+++ b/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpContainer.java
@@ -307,9 +307,16 @@
      * @param application JAX-RS / Jersey application to be deployed on Grizzly HTTP container.
      */
     /* package */ GrizzlyHttpContainer(final Application application) {
-        this.appHandler = new ApplicationHandler(application, new GrizzlyBinder());
-        cacheConfigSetStatusOverSendError();
-        cacheConfigEnableLeadingContextPathSlashes();
+        this(new ApplicationHandler(application, new GrizzlyBinder()));
+    }
+
+    /**
+     * Create a new Grizzly HTTP container.
+     *
+     * @param applicationClass JAX-RS / Jersey application to be deployed on Grizzly HTTP container.
+     */
+    /* package */ GrizzlyHttpContainer(final Class<? extends Application> applicationClass) {
+        this(new ApplicationHandler(applicationClass, new GrizzlyBinder()));
     }
 
     /**
@@ -319,7 +326,11 @@
      * @param parentContext DI provider specific context with application's registered bindings.
      */
     /* package */ GrizzlyHttpContainer(final Application application, final Object parentContext) {
-        this.appHandler = new ApplicationHandler(application, new GrizzlyBinder(), parentContext);
+        this(new ApplicationHandler(application, new GrizzlyBinder(), parentContext));
+    }
+
+    private GrizzlyHttpContainer(ApplicationHandler applicationHandler) {
+        this.appHandler = applicationHandler;
         cacheConfigSetStatusOverSendError();
         cacheConfigEnableLeadingContextPathSlashes();
     }
diff --git a/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServer.java b/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServer.java
new file mode 100644
index 0000000..68d7048
--- /dev/null
+++ b/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServer.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.grizzly2.httpserver;
+
+import static jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication.MANDATORY;
+import static jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication.OPTIONAL;
+
+import java.io.IOException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+
+/**
+ * Jersey {@code Server} implementation based on Grizzly {@link HttpServer}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+final class GrizzlyHttpServer implements WebServer {
+
+    private final GrizzlyHttpContainer container;
+
+    private final HttpServer httpServer;
+
+    GrizzlyHttpServer(final Application application, final JerseySeBootstrapConfiguration configuration) {
+        this(new GrizzlyHttpContainer(application), configuration);
+    }
+
+    GrizzlyHttpServer(final Class<? extends Application> applicationClass,
+                      final JerseySeBootstrapConfiguration configuration) {
+        this(new GrizzlyHttpContainer(applicationClass), configuration);
+    }
+
+    private GrizzlyHttpServer(final GrizzlyHttpContainer container, final JerseySeBootstrapConfiguration configuration) {
+        final SSLContext sslContext = configuration.sslContext();
+        final SeBootstrap.Configuration.SSLClientAuthentication sslClientAuthentication = configuration
+                .sslClientAuthentication();
+
+        this.container = container;
+        this.httpServer = GrizzlyHttpServerFactory.createHttpServer(
+                configuration.uri(true),
+                this.container,
+                configuration.isHttps(),
+                configuration.isHttps() ? new SSLEngineConfigurator(sslContext, false,
+                        sslClientAuthentication == MANDATORY,
+                        sslClientAuthentication == OPTIONAL) : null,
+                configuration.autoStart());
+    }
+
+    @Override
+    public final GrizzlyHttpContainer container() {
+        return this.container;
+    }
+
+    @Override
+    public final int port() {
+        return this.httpServer.getListener("grizzly").getPort();
+    }
+
+    @Override
+    public final CompletableFuture<Void> start() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                this.httpServer.start();
+            } catch (final IOException e) {
+                throw new CompletionException(e);
+            }
+        });
+    }
+
+    @Override
+    public final CompletableFuture<Void> stop() {
+        return CompletableFuture.runAsync(this.httpServer::shutdownNow);
+    }
+
+    @Override
+    public final <T> T unwrap(final Class<T> nativeClass) {
+        return nativeClass.cast(this.httpServer);
+    }
+
+}
diff --git a/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServerProvider.java b/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServerProvider.java
new file mode 100644
index 0000000..f9cfac2
--- /dev/null
+++ b/containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServerProvider.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.grizzly2.httpserver;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+
+/**
+ * Server provider for servers based on Grizzly {@link HttpServer}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class GrizzlyHttpServerProvider implements WebServerProvider {
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Application application,
+                                                      final SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(GrizzlyHttpServer.class, type, configuration)
+                ? type.cast(new GrizzlyHttpServer(application, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+
+    @Override
+    public <T extends WebServer> T createServer(Class<T> type, Class<? extends Application> applicationClass,
+                                                SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(GrizzlyHttpServer.class, type, configuration)
+                ? type.cast(new GrizzlyHttpServer(applicationClass, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+}
diff --git a/containers/grizzly2-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider b/containers/grizzly2-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
new file mode 100644
index 0000000..dea5f90
--- /dev/null
+++ b/containers/grizzly2-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerProvider
\ No newline at end of file
diff --git a/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServerProviderTest.java b/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServerProviderTest.java
new file mode 100644
index 0000000..1c75de1
--- /dev/null
+++ b/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServerProviderTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.grizzly2.httpserver;
+
+import static java.lang.Boolean.TRUE;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.instanceOf;
+
+import java.security.AccessController;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.UriBuilder;
+
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+/**
+ * Unit tests for {@link GrizzlyHttpServerProvider}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class GrizzlyHttpServerProviderTest {
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServer() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        shouldProvideServer(ShouldProvideServerApplication.class, resource);
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServerWithClass() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        final Application application = new ShouldProvideServerApplication();
+        shouldProvideServer(application.getClass(), resource);
+    }
+
+    private void shouldProvideServer(final Object application, final Resource resource)
+            throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new GrizzlyHttpServerProvider();
+        final SeBootstrap.Configuration configuration = configuration(getPort());
+
+        // when
+        final WebServer webServer = Application.class.isInstance(application)
+                ? webServerProvider.createServer(WebServer.class, (Application) application, configuration)
+                : webServerProvider.createServer(WebServer.class, (Class<Application>) application, configuration);
+        final Object nativeHandle = webServer.unwrap(Object.class);
+        final CompletionStage<?> start = webServer.start();
+        final Object startResult = start.toCompletableFuture().get();
+        final Container container = webServer.container();
+        final int port = webServer.port();
+        final String entity = ClientBuilder.newClient()
+                .target(UriBuilder.newInstance().scheme("http").host("localhost").port(port).build()).request()
+                .get(String.class);
+        final CompletionStage<?> stop = webServer.stop();
+        final Object stopResult = stop.toCompletableFuture().get();
+
+        // then
+        assertThat(webServer, is(instanceOf(GrizzlyHttpServer.class)));
+        assertThat(nativeHandle, is(instanceOf(HttpServer.class)));
+        assertThat(startResult, is(nullValue()));
+        assertThat(container, is(instanceOf(GrizzlyHttpContainer.class)));
+        assertThat(port, is(greaterThan(0)));
+        assertThat(entity, is(resource.toString()));
+        assertThat(stopResult, is(nullValue()));
+    }
+
+    @Path("/")
+    protected static final class Resource {
+        @GET
+        @Override
+        public String toString() {
+            return Resource.class.getName();
+        }
+    }
+
+    protected static class ShouldProvideServerApplication extends Application {
+        @Override
+        public final Set<Object> getSingletons() {
+            return Collections.singleton(new Resource());
+        }
+    }
+
+    private static final Logger LOGGER = Logger.getLogger(GrizzlyHttpServerProviderTest.class.getName());
+
+    private static final int DEFAULT_PORT = 0;
+
+    private static int getPort() {
+        final String value = AccessController
+                .doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
+        if (value != null) {
+            try {
+                final int i = Integer.parseInt(value);
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
+                }
+                return i;
+            } catch (final NumberFormatException e) {
+                LOGGER.log(Level.CONFIG,
+                        "Value of 'jersey.config.test.container.port'"
+                                + " property is not a valid non-negative integer [" + value + "]."
+                                + " Reverting to default [" + DEFAULT_PORT + "].",
+                        e);
+            }
+        }
+
+        return DEFAULT_PORT;
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldScanFreePort() {
+        // given
+        final WebServerProvider webServerProvider = new GrizzlyHttpServerProvider();
+        final Application application = new Application();
+        final SeBootstrap.Configuration configuration = configuration(SeBootstrap.Configuration.FREE_PORT);
+
+        // when
+        final WebServer webServer = webServerProvider.createServer(WebServer.class, application, configuration);
+
+        // then
+        assertThat(webServer.port(), is(greaterThan(0)));
+    }
+
+    private SeBootstrap.Configuration configuration(int port) {
+        return (SeBootstrap.Configuration) name -> {
+            switch (name) {
+                case SeBootstrap.Configuration.PROTOCOL:
+                    return "HTTP";
+                case SeBootstrap.Configuration.HOST:
+                    return "localhost";
+                case SeBootstrap.Configuration.PORT:
+                    return port;
+                case SeBootstrap.Configuration.ROOT_PATH:
+                    return "/";
+                case SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION:
+                    return SSLClientAuthentication.NONE;
+                case SeBootstrap.Configuration.SSL_CONTEXT:
+                    try {
+                        return SSLContext.getDefault();
+                    } catch (final NoSuchAlgorithmException e) {
+                        throw new RuntimeException(e);
+                    }
+                case ServerProperties.WEBSERVER_AUTO_START:
+                    return TRUE;
+                default:
+                    return null;
+            }
+        };
+    }
+
+}
\ No newline at end of file
diff --git a/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/application/TestedEndpoint.java b/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/application/TestedEndpoint.java
index 3ad7fb8..0a195f1 100644
--- a/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/application/TestedEndpoint.java
+++ b/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/application/TestedEndpoint.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022 Payara Foundation and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/tools/JettyHttpClientThread.java b/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/tools/JettyHttpClientThread.java
index 6a09e52..ec3f174 100644
--- a/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/tools/JettyHttpClientThread.java
+++ b/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/tools/JettyHttpClientThread.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -20,12 +20,12 @@
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.eclipse.jetty.client.ContentResponse;
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.HttpClientTransport;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
+import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
 import org.eclipse.jetty.http2.client.HTTP2Client;
-import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
+import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
 import org.eclipse.jetty.io.ClientConnector;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 import static org.junit.jupiter.api.Assertions.assertEquals;
diff --git a/containers/grizzly2-servlet/pom.xml b/containers/grizzly2-servlet/pom.xml
index d989aad..f45013e 100644
--- a/containers/grizzly2-servlet/pom.xml
+++ b/containers/grizzly2-servlet/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-container-grizzly2-servlet</artifactId>
@@ -36,7 +36,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
         </dependency>
 
         <dependency>
@@ -72,6 +71,7 @@
                     <instructions>
                         <Import-Package>
                             jakarta.servlet.*;version="[5.0,7.0)",
+                            org.glassfish.grizzly.*;version="[3.0,5.0)",
                             *
                         </Import-Package>
                     </instructions>
diff --git a/containers/jdk-http/pom.xml b/containers/jdk-http/pom.xml
index 3cc6912..a9547d7 100644
--- a/containers/jdk-http/pom.xml
+++ b/containers/jdk-http/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-container-jdk-http</artifactId>
@@ -80,45 +80,8 @@
         </resources>
     </build>
 
-    <profiles>
-        <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <properties>
-                <!-- https://bugs.openjdk.java.net/browse/JDK-8211426 -->
-                <surefire.security.argline>-Djdk.tls.client.protocols=TLSv1.2</surefire.security.argline>
-            </properties>
-        </profile>
-        <profile>
-            <id>windows</id>
-            <activation>
-                <jdk>1.8</jdk>
-                <os>
-                    <family>windows</family>
-                </os>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <configuration>
-                            <!-- Exclude unit tests regarding JDK HTTP Server because of failing a server shutdown in a class
-                            with several tests. "java.net.BindException: Address already in use: bind"
-                            bug reported on https://bugs.openjdk.java.net/browse/JDK-8015692 -->
-                            <excludes>
-                                <exclude>org/glassfish/jersey/jdkhttp/BasicJdkHttpServerTest.java</exclude>
-                                <exclude>org/glassfish/jersey/jdkhttp/JdkHttpPackageTest.java</exclude>
-                                <exclude>org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java</exclude>
-                                <exclude>org/glassfish/jersey/jdkhttp/LifecycleListenerTest.java</exclude>
-                            </excludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-
+    <properties>
+        <!-- https://bugs.openjdk.java.net/browse/JDK-8211426 -->
+        <surefire.security.argline>-Djdk.tls.client.protocols=TLSv1.2</surefire.security.argline>
+    </properties>
 </project>
diff --git a/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpHandlerContainer.java b/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpHandlerContainer.java
index 1470f22..6349533 100644
--- a/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpHandlerContainer.java
+++ b/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpHandlerContainer.java
@@ -64,7 +64,7 @@
     private volatile ApplicationHandler appHandler;
 
     /**
-     * Create new lightweight Java SE HTTP server container.
+     * Create new lightweight Java SE HTTP server container.
      *
      * @param application JAX-RS / Jersey application to be deployed on the container.
      */
@@ -73,7 +73,16 @@
     }
 
     /**
-     * Create new lightweight Java SE HTTP server container.
+     * Create new lightweight Java SE HTTP server container.
+     *
+     * @param applicationClass class of JAX-RS / Jersey application to be deployed on the container.
+     */
+    JdkHttpHandlerContainer(final Class<? extends Application> applicationClass) {
+        this.appHandler = new ApplicationHandler(applicationClass);
+    }
+
+    /**
+     * Create new lightweight Java SE HTTP server container.
      *
      * @param application   JAX-RS / Jersey application to be deployed on the container.
      * @param parentContext DI provider specific context with application's registered bindings.
diff --git a/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServer.java b/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServer.java
new file mode 100644
index 0000000..33d0bcf
--- /dev/null
+++ b/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServer.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jdkhttp;
+
+import static jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication.MANDATORY;
+import static jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication.OPTIONAL;
+
+import java.util.concurrent.CompletableFuture;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+
+import com.sun.net.httpserver.HttpServer;
+
+/**
+ * Jersey {@code Server} implementation based on JDK {@link HttpServer}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+final class JdkHttpServer implements WebServer {
+
+    private final JdkHttpHandlerContainer container;
+
+    private final HttpServer httpServer;
+
+    JdkHttpServer(final Application application, final JerseySeBootstrapConfiguration configuration) {
+        this(new JdkHttpHandlerContainer(application), configuration);
+    }
+
+    JdkHttpServer(final Class<? extends Application> applicationClass,
+                  final JerseySeBootstrapConfiguration configuration) {
+        this(new JdkHttpHandlerContainer(applicationClass), configuration);
+    }
+
+    JdkHttpServer(final JdkHttpHandlerContainer container, final JerseySeBootstrapConfiguration configuration) {
+        final SeBootstrap.Configuration.SSLClientAuthentication sslClientAuthentication = configuration
+                .sslClientAuthentication();
+
+        this.container = container;
+        this.httpServer = JdkHttpServerFactory.createHttpServer(
+                configuration.uri(true),
+                this.container,
+                configuration.sslContext(),
+                sslClientAuthentication == OPTIONAL,
+                sslClientAuthentication == MANDATORY,
+                configuration.autoStart());
+    }
+
+    @Override
+    public final JdkHttpHandlerContainer container() {
+        return this.container;
+    }
+
+    @Override
+    public final int port() {
+        return this.httpServer.getAddress().getPort();
+    }
+
+    @Override
+    public final CompletableFuture<Void> start() {
+        return CompletableFuture.runAsync(this.httpServer::start);
+    }
+
+    @Override
+    public final CompletableFuture<Void> stop() {
+        return CompletableFuture.runAsync(() -> this.httpServer.stop(0));
+    }
+
+    @Override
+    public final <T> T unwrap(final Class<T> nativeClass) {
+        return nativeClass.cast(this.httpServer);
+    }
+
+}
diff --git a/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServerFactory.java b/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServerFactory.java
index 9b5f8b7..5de6973 100644
--- a/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServerFactory.java
+++ b/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServerFactory.java
@@ -26,6 +26,7 @@
 import jakarta.ws.rs.ProcessingException;
 
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLParameters;
 
 import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
 import org.glassfish.jersey.jdkhttp.internal.LocalizationMessages;
@@ -37,6 +38,7 @@
 import com.sun.net.httpserver.HttpHandler;
 import com.sun.net.httpserver.HttpServer;
 import com.sun.net.httpserver.HttpsConfigurator;
+import com.sun.net.httpserver.HttpsParameters;
 import com.sun.net.httpserver.HttpsServer;
 
 /**
@@ -177,8 +179,17 @@
     }
 
     private static HttpServer createHttpServer(final URI uri,
+            final JdkHttpHandlerContainer handler,
+            final SSLContext sslContext,
+            final boolean start) {
+        return createHttpServer(uri, handler, sslContext, false, false, start);
+    }
+
+    static HttpServer createHttpServer(final URI uri,
                                                final JdkHttpHandlerContainer handler,
                                                final SSLContext sslContext,
+                                               final boolean sslClientAuthWanted,
+                                               final boolean sslClientAuthNeeded,
                                                final boolean start) {
         if (uri == null) {
             throw new IllegalArgumentException(LocalizationMessages.ERROR_CONTAINER_URI_NULL());
@@ -187,7 +198,14 @@
         final String scheme = uri.getScheme();
         final boolean isHttp = "http".equalsIgnoreCase(scheme);
         final boolean isHttps = "https".equalsIgnoreCase(scheme);
-        final HttpsConfigurator httpsConfigurator = sslContext != null ? new HttpsConfigurator(sslContext) : null;
+        final HttpsConfigurator httpsConfigurator = sslContext != null ? new HttpsConfigurator(sslContext) {
+            public final void configure(final HttpsParameters httpsParameters) {
+                final SSLParameters sslParameters = sslContext.getDefaultSSLParameters();
+                sslParameters.setWantClientAuth(sslClientAuthWanted);
+                sslParameters.setNeedClientAuth(sslClientAuthNeeded);
+                httpsParameters.setSSLParameters(sslParameters);
+            }
+        } : null;
 
         if (isHttp) {
             if (httpsConfigurator != null) {
diff --git a/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServerProvider.java b/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServerProvider.java
new file mode 100644
index 0000000..b9edb30
--- /dev/null
+++ b/containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServerProvider.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jdkhttp;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+
+import com.sun.net.httpserver.HttpServer;
+
+/**
+ * Server provider for servers based on JDK {@link HttpServer}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class JdkHttpServerProvider implements WebServerProvider {
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Application application,
+                                                      final SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(JdkHttpServer.class, type, configuration)
+                ? type.cast(new JdkHttpServer(application, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Class<? extends Application> applicationClass,
+                                                final SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(JdkHttpServer.class, type, configuration)
+                ? type.cast(new JdkHttpServer(applicationClass, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+}
diff --git a/containers/jdk-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider b/containers/jdk-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
new file mode 100644
index 0000000..2d8abc3
--- /dev/null
+++ b/containers/jdk-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.jdkhttp.JdkHttpServerProvider
\ No newline at end of file
diff --git a/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/AbstractJdkHttpServerTester.java b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/AbstractJdkHttpServerTester.java
index 3886ea9..ad11787 100644
--- a/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/AbstractJdkHttpServerTester.java
+++ b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/AbstractJdkHttpServerTester.java
@@ -21,6 +21,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import javax.net.ssl.SSLContext;
 import jakarta.ws.rs.RuntimeType;
 import jakarta.ws.rs.core.UriBuilder;
 
@@ -51,20 +52,21 @@
         if (server != null) {
             return server.getAddress().getPort();
         }
-        final String value =
-                AccessController.doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
+
+        final String value = AccessController.doPrivileged(
+                PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
         if (value != null) {
 
             try {
                 final int i = Integer.parseInt(value);
-                if (i <= 0) {
-                    throw new NumberFormatException("Value not positive.");
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
                 }
                 return i;
             } catch (NumberFormatException e) {
                 LOGGER.log(Level.CONFIG,
                         "Value of 'jersey.config.test.container.port'"
-                                + " property is not a valid positive integer [" + value + "]."
+                                + " property is not a valid non-negative integer [" + value + "]."
                                 + " Reverting to default [" + DEFAULT_PORT + "].",
                         e);
             }
@@ -90,17 +92,23 @@
 
     public void startServer(Class... resources) {
         ResourceConfig config = new ResourceConfig(resources);
-        config.register(LoggingFeature.class);
-        final URI baseUri = getBaseUri();
-        server = JdkHttpServerFactory.createHttpServer(baseUri, config);
-        LOGGER.log(Level.INFO, "jdk-http server started on base uri: " + server.getAddress());
+        startServer(config);
     }
 
     public void startServer(ResourceConfig config) {
         final URI baseUri = getBaseUri();
         config.register(LoggingFeature.class);
         server = JdkHttpServerFactory.createHttpServer(baseUri, config);
-        LOGGER.log(Level.INFO, "jdk-http server started on base uri: " + server.getAddress());
+        LOGGER.log(Level.INFO, "jdk-http server started on base uri: " + getBaseUri());
+    }
+
+    public HttpServer startServer(final URI uri, final ResourceConfig config,
+            final SSLContext sslContext, final boolean start) {
+        config.register(LoggingFeature.class);
+        server = JdkHttpServerFactory.createHttpServer(uri, config, sslContext, start);
+        LOGGER.log(Level.INFO,
+                "jdk-http server started on base uri: " + UriBuilder.fromUri(uri).port(getPort()).build());
+        return server;
     }
 
     public URI getBaseUri() {
diff --git a/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpServerProviderTest.java b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpServerProviderTest.java
new file mode 100644
index 0000000..f831890
--- /dev/null
+++ b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpServerProviderTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jdkhttp;
+
+import static java.lang.Boolean.FALSE;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.instanceOf;
+
+import java.security.AccessController;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+
+import com.sun.net.httpserver.HttpServer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+/**
+ * Unit tests for {@link JdkHttpServerProvider}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class JdkHttpServerProviderTest {
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServer() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        shouldProvideServer(ShouldProvideServerApplication.class, resource);
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServerWithClass() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        final Application application = new ShouldProvideServerApplication();
+        shouldProvideServer(application.getClass(), resource);
+    }
+
+    private void shouldProvideServer(final Object application, final Resource resource)
+            throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new JdkHttpServerProvider();
+        final SeBootstrap.Configuration configuration = configuration(getPort());
+
+        // when
+        final WebServer webServer = Application.class.isInstance(application)
+                ? webServerProvider.createServer(WebServer.class, (Application) application, configuration)
+                : webServerProvider.createServer(WebServer.class, (Class<Application>) application, configuration);
+        final Object nativeHandle = webServer.unwrap(Object.class);
+        final CompletionStage<?> start = webServer.start();
+        final Object startResult = start.toCompletableFuture().get();
+        final Container container = webServer.container();
+        final int port = webServer.port();
+        final String entity = ClientBuilder.newClient()
+                .target(UriBuilder.newInstance().scheme("http").host("localhost").port(port).build()).request()
+                .get(String.class);
+        final CompletionStage<?> stop = webServer.stop();
+        final Object stopResult = stop.toCompletableFuture().get();
+
+        // then
+        assertThat(webServer, is(instanceOf(JdkHttpServer.class)));
+        assertThat(nativeHandle, is(instanceOf(HttpServer.class)));
+        assertThat(startResult, is(nullValue()));
+        assertThat(container, is(instanceOf(JdkHttpHandlerContainer.class)));
+        assertThat(port, is(greaterThan(0)));
+        assertThat(entity, is(resource.toString()));
+        assertThat(stopResult, is(nullValue()));
+    }
+
+    @Path("/")
+    protected static final class Resource {
+        @GET
+        @Override
+        public String toString() {
+            return Resource.class.getName();
+        }
+    }
+
+    protected static class ShouldProvideServerApplication extends Application {
+        @Override
+        public Set<Object> getSingletons() {
+            return Collections.singleton(new Resource());
+        }
+    }
+
+    private static final Logger LOGGER = Logger.getLogger(JdkHttpServerProviderTest.class.getName());
+
+    private static final int DEFAULT_PORT = 0;
+
+    private static final int getPort() {
+        final String value = AccessController
+                .doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
+        if (value != null) {
+            try {
+                final int i = Integer.parseInt(value);
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
+                }
+                return i;
+            } catch (final NumberFormatException e) {
+                LOGGER.log(Level.CONFIG,
+                        "Value of 'jersey.config.test.container.port'"
+                                + " property is not a valid non-negative integer [" + value + "]."
+                                + " Reverting to default [" + DEFAULT_PORT + "].",
+                        e);
+            }
+        }
+
+        return DEFAULT_PORT;
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public final void shouldScanFreePort() throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new JdkHttpServerProvider();
+        final Application application = new Application();
+        final SeBootstrap.Configuration configuration = configuration(SeBootstrap.Configuration.FREE_PORT);
+
+        // when
+        final WebServer webServer = webServerProvider.createServer(WebServer.class, application, configuration);
+
+        // then
+        assertThat(webServer.port(), is(greaterThan(0)));
+    }
+
+    private SeBootstrap.Configuration configuration(int port) {
+        return (SeBootstrap.Configuration) name -> {
+            switch (name) {
+                case SeBootstrap.Configuration.PROTOCOL:
+                    return "HTTP";
+                case SeBootstrap.Configuration.HOST:
+                    return "localhost";
+                case SeBootstrap.Configuration.PORT:
+                    return port;
+                case SeBootstrap.Configuration.ROOT_PATH:
+                    return "/";
+                case SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION:
+                    return SSLClientAuthentication.NONE;
+                case SeBootstrap.Configuration.SSL_CONTEXT:
+                    try {
+                        return SSLContext.getDefault();
+                    } catch (final NoSuchAlgorithmException e) {
+                        throw new RuntimeException(e);
+                    }
+                case ServerProperties.WEBSERVER_AUTO_START:
+                    return FALSE;
+                default:
+                    return null;
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java
index 01e9e34..2b912d8 100644
--- a/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java
+++ b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java
@@ -99,7 +99,7 @@
     @Test
     public void testStartHttpServerNoSslContext() throws Exception {
         assertThrows(IllegalArgumentException.class,
-            () -> JdkHttpServerFactory.createHttpServer(httpsUri, rc, null, true));
+                () -> JdkHttpServerFactory.createHttpServer(httpsUri, rc, null, true));
     }
 
     /**
@@ -228,4 +228,4 @@
             server = null;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/containers/jersey-servlet-core/pom.xml b/containers/jersey-servlet-core/pom.xml
index b218191..57fa115 100644
--- a/containers/jersey-servlet-core/pom.xml
+++ b/containers/jersey-servlet-core/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-container-servlet-core</artifactId>
@@ -36,7 +36,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/ServletContainer.java b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/ServletContainer.java
index 13702a9..56cf0ea 100644
--- a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/ServletContainer.java
+++ b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/ServletContainer.java
@@ -317,8 +317,7 @@
         final Response.Status badRequest = Response.Status.BAD_REQUEST;
         if (webComponent.configSetStatusOverSendError) {
             response.reset();
-            //noinspection deprecation
-            response.setStatus(badRequest.getStatusCode(), badRequest.getReasonPhrase());
+            response.setStatus(badRequest.getStatusCode());
         } else {
             response.sendError(badRequest.getStatusCode(), badRequest.getReasonPhrase());
         }
diff --git a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/WebComponent.java b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/WebComponent.java
index 59b1da9..584aef0 100644
--- a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/WebComponent.java
+++ b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/WebComponent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -401,8 +401,7 @@
 
             if (configSetStatusOverSendError) {
                 servletResponse.reset();
-                //noinspection deprecation
-                servletResponse.setStatus(status.getStatusCode(), status.getReasonPhrase());
+                servletResponse.setStatus(status.getStatusCode());
             } else {
                 servletResponse.sendError(status.getStatusCode(), status.getReasonPhrase());
             }
diff --git a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/internal/ResponseWriter.java b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/internal/ResponseWriter.java
index 31b8f93..5059c30 100644
--- a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/internal/ResponseWriter.java
+++ b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/internal/ResponseWriter.java
@@ -144,7 +144,7 @@
 
         final String reasonPhrase = responseContext.getStatusInfo().getReasonPhrase();
         if (reasonPhrase != null) {
-            response.setStatus(responseContext.getStatus(), reasonPhrase);
+            response.setStatus(responseContext.getStatus());
         } else {
             response.setStatus(responseContext.getStatus());
         }
@@ -217,7 +217,7 @@
                     if (configSetStatusOverSendError) {
                         response.reset();
                         //noinspection deprecation
-                        response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "Request failed.");
+                        response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
                     } else {
                         response.sendError(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), "Request failed.");
                     }
diff --git a/containers/jersey-servlet/pom.xml b/containers/jersey-servlet/pom.xml
index 91b4ce8..ad26879 100644
--- a/containers/jersey-servlet/pom.xml
+++ b/containers/jersey-servlet/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-container-servlet</artifactId>
@@ -36,7 +36,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
             <scope>provided</scope>
         </dependency>
 
diff --git a/containers/jetty-http/pom.xml b/containers/jetty-http/pom.xml
index 36519f5..a8c1a77 100644
--- a/containers/jetty-http/pom.xml
+++ b/containers/jetty-http/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.containers</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-container-jetty-http</artifactId>
@@ -32,6 +32,13 @@
 
     <description>Jetty Http Container</description>
 
+    <properties>
+        <java11.build.outputDirectory>${project.basedir}/target</java11.build.outputDirectory>
+        <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
+        <java17.build.outputDirectory>${project.basedir}/target17</java17.build.outputDirectory>
+        <java17.sourceDirectory>${project.basedir}/src/main/java17</java17.sourceDirectory>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>jakarta.inject</groupId>
@@ -59,12 +66,11 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-util</artifactId>
+            <artifactId>jetty-security</artifactId>
             <exclusions>
                 <exclusion>
                     <groupId>org.slf4j</groupId>
@@ -119,83 +125,15 @@
         </resources>
     </build>
 
-    <properties>
-        <java8.build.outputDirectory>${project.basedir}/target</java8.build.outputDirectory>
-        <java8.sourceDirectory>${project.basedir}/src/main/java8</java8.sourceDirectory>
-        <java11.build.outputDirectory>${project.basedir}/target11</java11.build.outputDirectory>
-        <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
-    </properties>
-
     <profiles>
         <profile>
             <id>JettyExclude</id>
             <activation>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <properties>
-                <jetty.version>${jetty9.version}</jetty.version>
+                <jetty.version>${jetty11.version}</jetty.version>
             </properties>
-            <dependencies>
-                <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-client</artifactId>
-                    <version>${jetty.version}</version>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-                <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-util</artifactId>
-                    <version>${jetty.version}</version>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-            </dependencies>
-            <build>
-                <directory>${java8.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java8.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <configuration>
-                            <testExcludes>
-                                <testExclude>org/glassfish/jersey/jetty/*.java</testExclude>
-                            </testExcludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>Jetty11</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
             <build>
                 <directory>${java11.build.outputDirectory}</directory>
                 <plugins>
@@ -216,17 +154,54 @@
                             </execution>
                         </executions>
                     </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <configuration>
+                            <testExcludes>
+                                <testExclude>org/glassfish/jersey/jetty/*.java</testExclude>
+                            </testExcludes>
+                        </configuration>
+                    </plugin>
                 </plugins>
             </build>
         </profile>
         <profile>
-            <id>copyJDK11FilesToMultiReleaseJar</id>
+            <id>JettyInclude</id>
+            <activation>
+                <jdk>[17,)</jdk>
+            </activation>
+            <build>
+                <directory>${java17.build.outputDirectory}</directory>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>add-source</goal>
+                                </goals>
+                                <configuration>
+                                    <sources>
+                                        <source>${java17.sourceDirectory}</source>
+                                    </sources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>copyJDK17FilesToMultiReleaseJar</id>
             <activation>
                 <file>
-                    <!-- ${java11.build.outputDirectory} does not work here -->
-                    <exists>target11/classes/org/glassfish/jersey/jetty/JettyHttpContainer.class</exists>
+                    <!-- ${java17.build.outputDirectory} does not work here -->
+                    <exists>target17/classes/org/glassfish/jersey/jetty/JettyHttpContainer.class</exists>
                 </file>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <build>
                 <plugins>
@@ -247,16 +222,16 @@
                         <inherited>true</inherited>
                         <executions>
                             <execution>
-                                <id>copy-jdk11-classes</id>
+                                <id>copy-jdk17-classes</id>
                                 <phase>prepare-package</phase>
                                 <goals>
                                     <goal>copy-resources</goal>
                                 </goals>
                                 <configuration>
-                                    <outputDirectory>${java8.build.outputDirectory}/classes/META-INF/versions/11</outputDirectory>
+                                    <outputDirectory>${java11.build.outputDirectory}/classes/META-INF/versions/17</outputDirectory>
                                     <resources>
                                         <resource>
-                                            <directory>${java11.build.outputDirectory}/classes</directory>
+                                            <directory>${java17.build.outputDirectory}/classes</directory>
                                         </resource>
                                     </resources>
                                 </configuration>
@@ -268,14 +243,14 @@
                         <artifactId>maven-antrun-plugin</artifactId>
                         <executions>
                             <execution>
-                                <id>copy-jdk11-sources</id>
+                                <id>copy-jdk17-sources</id>
                                 <phase>package</phase>
                                 <configuration>
                                     <target>
-                                        <property name="sources-jar" value="${java8.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+                                        <property name="sources-jar" value="${java11.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
                                         <echo>sources-jar: ${sources-jar}</echo>
                                         <zip destfile="${sources-jar}" update="true">
-                                            <zipfileset dir="${java11.sourceDirectory}" prefix="META-INF/versions/11"/>
+                                            <zipfileset dir="${java17.sourceDirectory}" prefix="META-INF/versions/17"/>
                                         </zip>
                                     </target>
                                 </configuration>
@@ -289,4 +264,5 @@
             </build>
         </profile>
     </profiles>
+
 </project>
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerProvider.java b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerProvider.java
index 4b80825..2e8b5c5 100644
--- a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerProvider.java
+++ b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerProvider.java
@@ -34,7 +34,7 @@
     public static final String HANDLER_NAME = "org.eclipse.jetty.server.Handler";
     @Override
     public <T> T createContainer(final Class<T> type, final Application application) throws ProcessingException {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
+        if (JdkVersion.getJdkVersion().getMajor() < 17) {
             throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
         }
         if (type != null && (HANDLER_NAME.equalsIgnoreCase(type.getCanonicalName()) || JettyHttpContainer.class == type)) {
@@ -45,7 +45,7 @@
 
     public <T> T createContainer(final Class<T> type, final Application application,
                                  Object parentContext) throws ProcessingException {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
+        if (JdkVersion.getJdkVersion().getMajor() < 17) {
             throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
         }
         if (type != null && (HANDLER_NAME.equalsIgnoreCase(type.getCanonicalName()) || JettyHttpContainer.class == type)) {
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServerProvider.java b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServerProvider.java
new file mode 100644
index 0000000..5022fee
--- /dev/null
+++ b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServerProvider.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.internal.util.JdkVersion;
+import org.glassfish.jersey.jetty.internal.LocalizationMessages;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+
+/**
+ * Server provider for servers based on Jetty
+ * {@link org.eclipse.jetty.server.Server Server}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class JettyHttpServerProvider implements WebServerProvider {
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Application application,
+                                                      final SeBootstrap.Configuration configuration) {
+        if (JdkVersion.getJdkVersion().getMajor() < 17) {
+            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+        }
+        return WebServerProvider.isSupportedWebServer(JettyHttpServer.class, type, configuration)
+                ? type.cast(new JettyHttpServer(application, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Class<? extends Application> applicationClass,
+                                                final SeBootstrap.Configuration configuration) {
+        if (JdkVersion.getJdkVersion().getMajor() < 17) {
+            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+        }
+        return WebServerProvider.isSupportedWebServer(JettyHttpServer.class, type, configuration)
+                ? type.cast(new JettyHttpServer(applicationClass, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+}
diff --git a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
index 1205576..55258ea 100644
--- a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
+++ b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
@@ -16,454 +16,41 @@
 
 package org.glassfish.jersey.jetty;
 
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.Principal;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import jakarta.servlet.AsyncContext;
-import jakarta.servlet.AsyncEvent;
-import jakarta.servlet.AsyncListener;
+import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.core.Application;
-import jakarta.ws.rs.core.GenericType;
-import jakarta.ws.rs.core.Response.Status;
-import jakarta.ws.rs.core.SecurityContext;
-
-import jakarta.inject.Inject;
-import jakarta.inject.Provider;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-
-import org.glassfish.jersey.internal.MapPropertiesDelegate;
-import org.glassfish.jersey.internal.inject.AbstractBinder;
-import org.glassfish.jersey.internal.inject.ReferencingFactory;
-import org.glassfish.jersey.internal.util.ExtendedLogger;
-import org.glassfish.jersey.internal.util.collection.Ref;
+import org.eclipse.jetty.server.Handler;
 import org.glassfish.jersey.jetty.internal.LocalizationMessages;
-import org.glassfish.jersey.process.internal.RequestScoped;
 import org.glassfish.jersey.server.ApplicationHandler;
-import org.glassfish.jersey.server.ContainerException;
-import org.glassfish.jersey.server.ContainerRequest;
-import org.glassfish.jersey.server.ContainerResponse;
 import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.ServerProperties;
-import org.glassfish.jersey.server.internal.ContainerUtils;
 import org.glassfish.jersey.server.spi.Container;
-import org.glassfish.jersey.server.spi.ContainerResponseWriter;
-
-import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Response;
-import org.eclipse.jetty.server.handler.AbstractHandler;
 
 /**
- * Jersey {@code Container} implementation based on Jetty {@link org.eclipse.jetty.server.Handler}.
+ * Jersey {@code Container} implementation based on Jetty {@link Handler}.
  *
  * @author Arul Dhesiaseelan (aruld@acm.org)
  * @author Libor Kramolis
  * @author Marek Potociar
  */
-public final class JettyHttpContainer extends AbstractHandler implements Container {
-
-    private static final ExtendedLogger LOGGER =
-            new ExtendedLogger(Logger.getLogger(JettyHttpContainer.class.getName()), Level.FINEST);
-
-    private static final Type REQUEST_TYPE = (new GenericType<Ref<Request>>() {}).getType();
-    private static final Type RESPONSE_TYPE = (new GenericType<Ref<Response>>() {}).getType();
-
-    private static final int INTERNAL_SERVER_ERROR = jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
-    private static final jakarta.ws.rs.core.Response.Status BAD_REQUEST_STATUS = jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
-
-    /**
-     * Cached value of configuration property
-     * {@link org.glassfish.jersey.server.ServerProperties#RESPONSE_SET_STATUS_OVER_SEND_ERROR}.
-     * If {@code true} method {@link HttpServletResponse#setStatus} is used over {@link HttpServletResponse#sendError}.
-     */
-    private boolean configSetStatusOverSendError;
-
-    /**
-     * Referencing factory for Jetty request.
-     */
-    private static class JettyRequestReferencingFactory extends ReferencingFactory<Request> {
-        @Inject
-        public JettyRequestReferencingFactory(final Provider<Ref<Request>> referenceFactory) {
-            super(referenceFactory);
-        }
-    }
-
-    /**
-     * Referencing factory for Jetty response.
-     */
-    private static class JettyResponseReferencingFactory extends ReferencingFactory<Response> {
-        @Inject
-        public JettyResponseReferencingFactory(final Provider<Ref<Response>> referenceFactory) {
-            super(referenceFactory);
-        }
-    }
-
-    /**
-     * An internal binder to enable Jetty HTTP container specific types injection.
-     * This binder allows to inject underlying Jetty HTTP request and response instances.
-     * Note that since Jetty {@code Request} class is not proxiable as it does not expose an empty constructor,
-     * the injection of Jetty request instance into singleton JAX-RS and Jersey providers is only supported via
-     * {@link jakarta.inject.Provider injection provider}.
-     */
-    private static class JettyBinder extends AbstractBinder {
-
-        @Override
-        protected void configure() {
-            bindFactory(JettyRequestReferencingFactory.class).to(Request.class)
-                    .proxy(false).in(RequestScoped.class);
-            bindFactory(ReferencingFactory.<Request>referenceFactory()).to(new GenericType<Ref<Request>>() {})
-                    .in(RequestScoped.class);
-
-            bindFactory(JettyResponseReferencingFactory.class).to(Response.class)
-                    .proxy(false).in(RequestScoped.class);
-            bindFactory(ReferencingFactory.<Response>referenceFactory()).to(new GenericType<Ref<Response>>() {})
-                    .in(RequestScoped.class);
-        }
-    }
-
-    private volatile ApplicationHandler appHandler;
-
-    @Override
-    public void handle(final String target, final Request request, final HttpServletRequest httpServletRequest,
-                       final HttpServletResponse httpServletResponse) throws IOException, ServletException {
-
-        if (request.isHandled()) {
-            return;
-        }
-
-        final Response response = request.getResponse();
-        final ResponseWriter responseWriter = new ResponseWriter(request, response, configSetStatusOverSendError);
-        try {
-            final URI baseUri = getBaseUri(request);
-            final URI requestUri = getRequestUri(request, baseUri);
-            final ContainerRequest requestContext = new ContainerRequest(
-                    baseUri,
-                    requestUri,
-                    request.getMethod(),
-                    getSecurityContext(request),
-                    new MapPropertiesDelegate(),
-                    appHandler.getConfiguration());
-            requestContext.setEntityStream(request.getInputStream());
-            final Enumeration<String> headerNames = request.getHeaderNames();
-            while (headerNames.hasMoreElements()) {
-                final String headerName = headerNames.nextElement();
-                String headerValue = request.getHeader(headerName);
-                requestContext.headers(headerName, headerValue == null ? "" : headerValue);
-            }
-            requestContext.setWriter(responseWriter);
-            requestContext.setRequestScopedInitializer(injectionManager -> {
-                injectionManager.<Ref<Request>>getInstance(REQUEST_TYPE).set(request);
-                injectionManager.<Ref<Response>>getInstance(RESPONSE_TYPE).set(response);
-            });
-
-            // Mark the request as handled before generating the body of the response
-            request.setHandled(true);
-            appHandler.handle(requestContext);
-        } catch (URISyntaxException e) {
-            setResponseForInvalidUri(response, e);
-        } catch (final Exception ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-
-    private URI getRequestUri(final Request request, final URI baseUri) throws URISyntaxException {
-        final String serverAddress = getServerAddress(baseUri);
-        String uri = request.getRequestURI();
-
-        final String queryString = request.getQueryString();
-        if (queryString != null) {
-            uri = uri + "?" + ContainerUtils.encodeUnsafeCharacters(queryString);
-        }
-
-        return new URI(serverAddress + uri);
-    }
-
-    private void setResponseForInvalidUri(final HttpServletResponse response, final Throwable throwable) throws IOException {
-        LOGGER.log(Level.FINER, "Error while processing request.", throwable);
-
-        if (configSetStatusOverSendError) {
-            response.reset();
-            //noinspection deprecation
-            response.setStatus(BAD_REQUEST_STATUS.getStatusCode(), BAD_REQUEST_STATUS.getReasonPhrase());
-        } else {
-            response.sendError(BAD_REQUEST_STATUS.getStatusCode(), BAD_REQUEST_STATUS.getReasonPhrase());
-        }
-    }
-
-    private String getServerAddress(URI baseUri) {
-        String serverAddress = baseUri.toString();
-        if (serverAddress.charAt(serverAddress.length() - 1) == '/') {
-            return serverAddress.substring(0, serverAddress.length() - 1);
-        }
-        return serverAddress;
-    }
-
-    private SecurityContext getSecurityContext(final Request request) {
-        return new SecurityContext() {
-
-            @Override
-            public boolean isUserInRole(final String role) {
-                return request.isUserInRole(role);
-            }
-
-            @Override
-            public boolean isSecure() {
-                return request.isSecure();
-            }
-
-            @Override
-            public Principal getUserPrincipal() {
-                return request.getUserPrincipal();
-            }
-
-            @Override
-            public String getAuthenticationScheme() {
-                return request.getAuthType();
-            }
-        };
-    }
-
-
-    private URI getBaseUri(final Request request) throws URISyntaxException {
-        return new URI(request.getScheme(), null, request.getServerName(),
-                request.getServerPort(), getBasePath(request), null, null);
-    }
-
-    private String getBasePath(final Request request) {
-        final String contextPath = request.getContextPath();
-
-        if (contextPath == null || contextPath.isEmpty()) {
-            return "/";
-        } else if (contextPath.charAt(contextPath.length() - 1) != '/') {
-            return contextPath + "/";
-        } else {
-            return contextPath;
-        }
-    }
-
-    private static final class ResponseWriter implements ContainerResponseWriter {
-
-        private final Response response;
-        private final AsyncContext context;
-        private final boolean configSetStatusOverSendError;
-
-        ResponseWriter(final Request request, final Response response, final boolean configSetStatusOverSendError) {
-            this.response = response;
-            this.context = request.startAsync();
-            this.configSetStatusOverSendError = configSetStatusOverSendError;
-        }
-
-        @Override
-        public OutputStream writeResponseStatusAndHeaders(final long contentLength, final ContainerResponse context)
-                throws ContainerException {
-
-            final jakarta.ws.rs.core.Response.StatusType statusInfo = context.getStatusInfo();
-
-            final int code = statusInfo.getStatusCode();
-            final String reason = statusInfo.getReasonPhrase() == null
-                    ? HttpStatus.getMessage(code) : statusInfo.getReasonPhrase();
-
-            response.setStatusWithReason(code, reason);
-
-            if (contentLength != -1 && contentLength < Integer.MAX_VALUE) {
-                response.setContentLength((int) contentLength);
-            }
-            for (final Map.Entry<String, List<String>> e : context.getStringHeaders().entrySet()) {
-                for (final String value : e.getValue()) {
-                    response.addHeader(e.getKey(), value);
-                }
-            }
-
-            try {
-                return response.getOutputStream();
-            } catch (final IOException ioe) {
-                throw new ContainerException("Error during writing out the response headers.", ioe);
-            }
-        }
-
-        @Override
-        public boolean suspend(final long timeOut, final TimeUnit timeUnit, final TimeoutHandler timeoutHandler) {
-            try {
-                if (timeOut > 0) {
-                    final long timeoutMillis = TimeUnit.MILLISECONDS.convert(timeOut, timeUnit);
-                    context.setTimeout(timeoutMillis);
-                }
-                context.addListener(new AsyncListener() {
-                    @Override
-                    public void onComplete(AsyncEvent asyncEvent) throws IOException {
-
-                    }
-
-                    @Override
-                    public void onTimeout(AsyncEvent asyncEvent) throws IOException {
-                        if (timeoutHandler != null) {
-                            timeoutHandler.onTimeout(ResponseWriter.this);
-                        }
-                    }
-
-                    @Override
-                    public void onError(AsyncEvent asyncEvent) throws IOException {
-
-                    }
-
-                    @Override
-                    public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
-
-                    }
-                });
-                return true;
-            } catch (final Exception ex) {
-                return false;
-            }
-        }
-
-        @Override
-        public void setSuspendTimeout(final long timeOut, final TimeUnit timeUnit) throws IllegalStateException {
-            if (timeOut > 0) {
-                final long timeoutMillis = TimeUnit.MILLISECONDS.convert(timeOut, timeUnit);
-                context.setTimeout(timeoutMillis);
-            }
-        }
-
-        @Override
-        public void commit() {
-            try {
-                closeOutput(response);
-            } catch (final IOException e) {
-                LOGGER.log(Level.WARNING, LocalizationMessages.UNABLE_TO_CLOSE_RESPONSE(), e);
-            } finally {
-                if (context.getRequest().isAsyncStarted()) {
-                    context.complete();
-                }
-                LOGGER.log(Level.FINEST, "commit() called");
-            }
-        }
-
-        private void closeOutput(Response response) throws IOException {
-            try {
-                response.completeOutput();
-            } catch (final IOException e) {
-                throw e;
-            } catch (NoSuchMethodError e) {
-                // try older Jetty Response#closeOutput
-                try {
-                    Method method = response.getClass().getMethod("closeOutput");
-                    method.invoke(response);
-                } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
-                    throw new IOException(ex);
-                }
-            }
-        }
-
-        @Override
-        public void failure(final Throwable error) {
-            try {
-                if (!response.isCommitted()) {
-                    try {
-                        if (configSetStatusOverSendError) {
-                            response.reset();
-                            //noinspection deprecation
-                            response.setStatus(INTERNAL_SERVER_ERROR, "Request failed.");
-                        } else {
-                            response.sendError(INTERNAL_SERVER_ERROR, "Request failed.");
-                        }
-                    } catch (final IllegalStateException ex) {
-                        // a race condition externally committing the response can still occur...
-                        LOGGER.log(Level.FINER, "Unable to reset failed response.", ex);
-                    } catch (final IOException ex) {
-                        throw new ContainerException(LocalizationMessages.EXCEPTION_SENDING_ERROR_RESPONSE(INTERNAL_SERVER_ERROR,
-                                "Request failed."), ex);
-                    }
-                }
-            } finally {
-                LOGGER.log(Level.FINEST, "failure(...) called");
-                commit();
-                rethrow(error);
-            }
-        }
-
-        @Override
-        public boolean enableResponseBuffering() {
-            return false;
-        }
-
-        /**
-         * Rethrow the original exception as required by JAX-RS, 3.3.4.
-         *
-         * @param error throwable to be re-thrown
-         */
-        private void rethrow(final Throwable error) {
-            if (error instanceof RuntimeException) {
-                throw (RuntimeException) error;
-            } else {
-                throw new ContainerException(error);
-            }
-        }
-
-    }
+public final class JettyHttpContainer implements Container {
 
     @Override
     public ResourceConfig getConfiguration() {
-        return appHandler.getConfiguration();
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 
     @Override
     public void reload() {
-        reload(new ResourceConfig(getConfiguration()));
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 
     @Override
     public void reload(final ResourceConfig configuration) {
-        appHandler.onShutdown(this);
-
-        appHandler = new ApplicationHandler(configuration.register(new JettyBinder()));
-        appHandler.onReload(this);
-        appHandler.onStartup(this);
-        cacheConfigSetStatusOverSendError();
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 
     @Override
     public ApplicationHandler getApplicationHandler() {
-        return appHandler;
-    }
-
-    /**
-     * Inform this container that the server has been started.
-     * This method must be implicitly called after the server containing this container is started.
-     *
-     * @throws java.lang.Exception if a problem occurred during server startup.
-     */
-    @Override
-    protected void doStart() throws Exception {
-        super.doStart();
-        appHandler.onStartup(this);
-    }
-
-    /**
-     * Inform this container that the server is being stopped.
-     * This method must be implicitly called before the server containing this container is stopped.
-     *
-     * @throws java.lang.Exception if a problem occurred during server shutdown.
-     */
-    @Override
-    public void doStop() throws Exception {
-        super.doStop();
-        appHandler.onShutdown(this);
-        appHandler = null;
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 
     /**
@@ -473,7 +60,7 @@
      * @param parentContext DI provider specific context with application's registered bindings.
      */
     JettyHttpContainer(final Application application, final Object parentContext) {
-        this.appHandler = new ApplicationHandler(application, new JettyBinder(), parentContext);
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 
     /**
@@ -482,18 +69,16 @@
      * @param application JAX-RS / Jersey application to be deployed on Jetty HTTP container.
      */
     JettyHttpContainer(final Application application) {
-        this.appHandler = new ApplicationHandler(application, new JettyBinder());
-
-        cacheConfigSetStatusOverSendError();
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 
     /**
-     * The method reads and caches value of configuration property
-     * {@link ServerProperties#RESPONSE_SET_STATUS_OVER_SEND_ERROR} for future purposes.
+     * Create a new Jetty HTTP container.
+     *
+     * @param applicationClass JAX-RS / Jersey class of application to be deployed on Jetty HTTP container.
      */
-    private void cacheConfigSetStatusOverSendError() {
-        this.configSetStatusOverSendError = ServerProperties.getValue(getConfiguration().getProperties(),
-                ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, false, Boolean.class);
+    JettyHttpContainer(final Class<? extends Application> applicationClass) {
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 
 }
diff --git a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
index 39f23e8..61e1977 100644
--- a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
+++ b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,32 +16,20 @@
 
 package org.glassfish.jersey.jetty;
 
-import java.net.URI;
-import java.util.concurrent.ThreadFactory;
-
 import jakarta.ws.rs.ProcessingException;
-
-import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.glassfish.jersey.jetty.internal.LocalizationMessages;
-import org.glassfish.jersey.process.JerseyProcessingUncaughtExceptionHandler;
 import org.glassfish.jersey.server.ContainerFactory;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.server.spi.Container;
 
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.SecureRequestCustomizer;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.SslConnectionFactory;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import java.net.URI;
 
 /**
  * Factory for creating and starting Jetty server handlers. This returns
  * a handle to the started server as {@link Server} instances, which allows
- * the server to be stopped by invoking the {@link org.eclipse.jetty.server.Server#stop()} method.
+ * the server to be stopped by invoking the {@link Server#stop()} method.
  * <p/>
  * To start the server in HTTPS mode an {@link SslContextFactory} can be provided.
  * This will be used to decrypt and encrypt information sent over the
@@ -91,7 +79,7 @@
      * resource configuration.
      * <p/>
      * This implementation defers to the
-     * {@link org.glassfish.jersey.server.ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+     * {@link ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
      * for creating an Container that manages the root resources.
      *
      * @param uri    the URI to create the http server. The URI scheme must be
@@ -117,7 +105,7 @@
      * resource configuration.
      * <p/>
      * This implementation defers to the
-     * {@link org.glassfish.jersey.server.ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+     * {@link ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
      * for creating an Container that manages the root resources.
      *
      * @param uri           URI on which the Jersey web application will be deployed. Only first path segment will be
@@ -196,7 +184,7 @@
      * @param uri               the URI to create the http server. The URI scheme must be
      *                          equal to {@code https}. The URI user information and host
      *                          are ignored. If the URI port is not present then port
-     *                          {@value org.glassfish.jersey.server.spi.Container#DEFAULT_HTTPS_PORT} will be
+     *                          {@value Container#DEFAULT_HTTPS_PORT} will be
      *                          used. The URI path, query and fragment components are ignored.
      * @param sslContextFactory this is the SSL context factory used to configure SSL connector
      * @param config            the resource configuration.
@@ -220,7 +208,7 @@
      * @param uri               the URI to create the http server. The URI scheme must be
      *                          equal to {@code https}. The URI user information and host
      *                          are ignored. If the URI port is not present then port
-     *                          {@value org.glassfish.jersey.server.spi.Container#DEFAULT_HTTPS_PORT} will be
+     *                          {@value Container#DEFAULT_HTTPS_PORT} will be
      *                          used. The URI path, query and fragment components are ignored.
      * @param sslContextFactory this is the SSL context factory used to configure SSL connector
      * @param handler           the container that handles all HTTP requests
@@ -236,70 +224,6 @@
                                       final SslContextFactory.Server sslContextFactory,
                                       final JettyHttpContainer handler,
                                       final boolean start) {
-        if (uri == null) {
-            throw new IllegalArgumentException(LocalizationMessages.URI_CANNOT_BE_NULL());
-        }
-        final String scheme = uri.getScheme();
-        int defaultPort = Container.DEFAULT_HTTP_PORT;
-
-        if (sslContextFactory == null) {
-            if (!"http".equalsIgnoreCase(scheme)) {
-                throw new IllegalArgumentException(LocalizationMessages.WRONG_SCHEME_WHEN_USING_HTTP());
-            }
-        } else {
-            if (!"https".equalsIgnoreCase(scheme)) {
-                throw new IllegalArgumentException(LocalizationMessages.WRONG_SCHEME_WHEN_USING_HTTPS());
-            }
-            defaultPort = Container.DEFAULT_HTTPS_PORT;
-        }
-        final int port = (uri.getPort() == -1) ? defaultPort : uri.getPort();
-
-        final Server server = new Server(new JettyConnectorThreadPool());
-        final HttpConfiguration config = new HttpConfiguration();
-        if (sslContextFactory != null) {
-            config.setSecureScheme("https");
-            config.setSecurePort(port);
-            config.addCustomizer(new SecureRequestCustomizer());
-
-            final ServerConnector https = new ServerConnector(server,
-                    new SslConnectionFactory(sslContextFactory, "http/1.1"),
-                    new HttpConnectionFactory(config));
-            https.setPort(port);
-            server.setConnectors(new Connector[]{https});
-
-        } else {
-            final ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(config));
-            http.setPort(port);
-            server.setConnectors(new Connector[]{http});
-        }
-        if (handler != null) {
-            server.setHandler(handler);
-        }
-
-        if (start) {
-            try {
-                // Start the server.
-                server.start();
-            } catch (final Exception e) {
-                throw new ProcessingException(LocalizationMessages.ERROR_WHEN_CREATING_SERVER(), e);
-            }
-        }
-        return server;
-    }
-
-    // TODO: Use https://www.eclipse.org/jetty/javadoc/current/org/eclipse/jetty/util/thread/QueuedThreadPool.html
-    //  #%3Cinit%3E(int,int,int,int,java.util.concurrent.BlockingQueue,java.lang.ThreadGroup,java.util.concurrent.ThreadFactory)
-    //
-    //  Keeping this for backwards compatibility for the time being
-    private static final class JettyConnectorThreadPool extends QueuedThreadPool {
-        private final ThreadFactory threadFactory = new ThreadFactoryBuilder()
-                .setNameFormat("jetty-http-server-%d")
-                .setUncaughtExceptionHandler(new JerseyProcessingUncaughtExceptionHandler())
-                .build();
-
-        @Override
-        public Thread newThread(Runnable runnable) {
-            return threadFactory.newThread(runnable);
-        }
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 }
diff --git a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpServer.java b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpServer.java
new file mode 100644
index 0000000..70fcc56
--- /dev/null
+++ b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpServer.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.Application;
+import org.glassfish.jersey.jetty.internal.LocalizationMessages;
+import org.glassfish.jersey.server.ContainerFactory;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Jersey {@code Server} implementation based on Jetty
+ * {@link org.eclipse.jetty.server.Server Server}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+final class JettyHttpServer implements WebServer {
+
+    private final JettyHttpContainer container;
+
+    private final org.eclipse.jetty.server.Server httpServer;
+
+    JettyHttpServer(final Application application, final JerseySeBootstrapConfiguration configuration) {
+        this(ContainerFactory.createContainer(JettyHttpContainer.class, application), configuration);
+    }
+
+    JettyHttpServer(final Class<? extends Application> applicationClass,
+                    final JerseySeBootstrapConfiguration configuration) {
+        this(new JettyHttpContainer(applicationClass), configuration);
+    }
+
+    JettyHttpServer(final JettyHttpContainer container, final JerseySeBootstrapConfiguration configuration) {
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+    }
+
+    @Override
+    public final JettyHttpContainer container() {
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+    }
+
+    @Override
+    public final int port() {
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+    }
+
+    @Override
+    public final CompletableFuture<Void> start() {
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+    }
+
+    @Override
+    public final CompletableFuture<Void> stop() {
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+    }
+
+    @Override
+    public final <T> T unwrap(final Class<T> nativeClass) {
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+    }
+
+}
diff --git a/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainer.java b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainer.java
new file mode 100644
index 0000000..dfe20f2
--- /dev/null
+++ b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainer.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty;
+
+import java.io.OutputStream;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.Principal;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.SecurityContext;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Provider;
+
+import org.eclipse.jetty.http.HttpField;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.io.Content;
+import org.eclipse.jetty.security.AuthenticationState;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.util.Callback;
+import org.glassfish.jersey.internal.MapPropertiesDelegate;
+import org.glassfish.jersey.internal.inject.AbstractBinder;
+import org.glassfish.jersey.internal.inject.ReferencingFactory;
+import org.glassfish.jersey.internal.util.ExtendedLogger;
+import org.glassfish.jersey.internal.util.collection.Ref;
+import org.glassfish.jersey.process.internal.RequestScoped;
+import org.glassfish.jersey.server.ApplicationHandler;
+import org.glassfish.jersey.server.ContainerException;
+import org.glassfish.jersey.server.ContainerRequest;
+import org.glassfish.jersey.server.ContainerResponse;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.internal.ContainerUtils;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.ContainerResponseWriter;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+
+/**
+ * Jersey {@code Container} implementation based on Jetty {@link org.eclipse.jetty.server.Handler}.
+ *
+ * @author Arul Dhesiaseelan (aruld@acm.org)
+ * @author Libor Kramolis
+ * @author Marek Potociar
+ */
+public final class JettyHttpContainer extends Handler.Abstract implements Container {
+
+    private static final ExtendedLogger LOGGER =
+            new ExtendedLogger(Logger.getLogger(JettyHttpContainer.class.getName()), Level.FINEST);
+
+    private static final Type REQUEST_TYPE = (new GenericType<Ref<Request>>() {}).getType();
+    private static final Type RESPONSE_TYPE = (new GenericType<Ref<Response>>() {}).getType();
+
+    private static final int INTERNAL_SERVER_ERROR = jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
+    private static final jakarta.ws.rs.core.Response.Status BAD_REQUEST_STATUS = jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
+
+    /**
+     * Cached value of configuration property
+     * {@link org.glassfish.jersey.server.ServerProperties#RESPONSE_SET_STATUS_OVER_SEND_ERROR}.
+     * If {@code true} method {@link Response#setStatus(int)} is used over {@link Response#writeError(Request, Response, Callback, int)}
+     */
+    private boolean configSetStatusOverSendError;
+
+    /**
+     * Referencing factory for Jetty request.
+     */
+    private static class JettyRequestReferencingFactory extends ReferencingFactory<Request> {
+        @Inject
+        public JettyRequestReferencingFactory(final Provider<Ref<Request>> referenceFactory) {
+            super(referenceFactory);
+        }
+    }
+
+    /**
+     * Referencing factory for Jetty response.
+     */
+    private static class JettyResponseReferencingFactory extends ReferencingFactory<Response> {
+        @Inject
+        public JettyResponseReferencingFactory(final Provider<Ref<Response>> referenceFactory) {
+            super(referenceFactory);
+        }
+    }
+
+    /**
+     * An internal binder to enable Jetty HTTP container specific types injection.
+     * This binder allows to inject underlying Jetty HTTP request and response instances.
+     * Note that since Jetty {@code Request} class is not proxiable as it does not expose an empty constructor,
+     * the injection of Jetty request instance into singleton JAX-RS and Jersey providers is only supported via
+     * {@link jakarta.inject.Provider injection provider}.
+     */
+    private static class JettyBinder extends AbstractBinder {
+
+        @Override
+        protected void configure() {
+            bindFactory(JettyRequestReferencingFactory.class).to(Request.class)
+                    .proxy(false).in(RequestScoped.class);
+            bindFactory(ReferencingFactory.<Request>referenceFactory()).to(new GenericType<Ref<Request>>() {})
+                    .in(RequestScoped.class);
+
+            bindFactory(JettyResponseReferencingFactory.class).to(Response.class)
+                    .proxy(false).in(RequestScoped.class);
+            bindFactory(ReferencingFactory.<Response>referenceFactory()).to(new GenericType<Ref<Response>>() {})
+                    .in(RequestScoped.class);
+        }
+    }
+
+    private volatile ApplicationHandler appHandler;
+
+    @Override
+    public boolean handle(Request request, Response response, Callback callback) throws Exception {
+
+        final ResponseWriter responseWriter = new ResponseWriter(request, response, callback, configSetStatusOverSendError);
+        try {
+            final URI baseUri = getBaseUri(request);
+            final URI requestUri = getRequestUri(request, baseUri);
+            final ContainerRequest requestContext = new ContainerRequest(
+                    baseUri,
+                    requestUri,
+                    request.getMethod(),
+                    getSecurityContext(request),
+                    new MapPropertiesDelegate(),
+                    appHandler.getConfiguration());
+            requestContext.setEntityStream(Request.asInputStream(request));
+            request.getHeaders().forEach(httpField ->
+                    requestContext.headers(httpField.getName(), httpField.getValue() == null ? "" : httpField.getValue()));
+            requestContext.setWriter(responseWriter);
+            requestContext.setRequestScopedInitializer(injectionManager -> {
+                injectionManager.<Ref<Request>>getInstance(REQUEST_TYPE).set(request);
+                injectionManager.<Ref<Response>>getInstance(RESPONSE_TYPE).set(response);
+            });
+
+            appHandler.handle(requestContext);
+            return true;
+        } catch (URISyntaxException e) {
+            setResponseForInvalidUri(request, response, callback, e);
+            return true;
+        } catch (final Exception ex) {
+            callback.failed(ex);
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private URI getRequestUri(final Request request, final URI baseUri) throws URISyntaxException {
+        final String serverAddress = getServerAddress(baseUri);
+        String uri = request.getHttpURI().getPath();
+
+        final String queryString = request.getHttpURI().getQuery();
+        if (queryString != null) {
+            uri = uri + "?" + ContainerUtils.encodeUnsafeCharacters(queryString);
+        }
+
+        return new URI(serverAddress + uri);
+    }
+
+    private void setResponseForInvalidUri(final Request request, final Response response,
+                                          final Callback callback, final Throwable throwable) {
+        LOGGER.log(Level.FINER, "Error while processing request.", throwable);
+
+        if (configSetStatusOverSendError) {
+            response.reset();
+            response.setStatus(BAD_REQUEST_STATUS.getStatusCode());
+            callback.failed(throwable);
+        } else {
+            Response.writeError(request, response, callback, BAD_REQUEST_STATUS.getStatusCode(),
+                    BAD_REQUEST_STATUS.getReasonPhrase(), throwable);
+        }
+    }
+
+    private String getServerAddress(URI baseUri) {
+        String serverAddress = baseUri.toString();
+        if (serverAddress.charAt(serverAddress.length() - 1) == '/') {
+            return serverAddress.substring(0, serverAddress.length() - 1);
+        }
+        return serverAddress;
+    }
+
+    private SecurityContext getSecurityContext(final Request request) {
+
+        AuthenticationState.Succeeded authenticationState = AuthenticationState.authenticate(request);
+
+        return new SecurityContext() {
+
+            @Override
+            public boolean isUserInRole(final String role) {
+                return authenticationState != null && authenticationState.isUserInRole(role);
+            }
+
+            @Override
+            public boolean isSecure() {
+                return request.isSecure();
+            }
+
+            @Override
+            public Principal getUserPrincipal() {
+                return authenticationState != null ? authenticationState.getUserIdentity().getUserPrincipal() : null;
+            }
+
+            @Override
+            public String getAuthenticationScheme() {
+                return authenticationState != null ? authenticationState.getAuthenticationType() : null;
+            }
+        };
+    }
+
+
+    private URI getBaseUri(final Request request) throws URISyntaxException {
+        return new URI(request.getHttpURI().getScheme(), null, Request.getServerName(request),
+                Request.getServerPort(request), getBasePath(request), null, null);
+    }
+
+    private String getBasePath(final Request request) {
+        final String contextPath = Request.getContextPath(request);
+
+        if (contextPath == null || contextPath.isEmpty()) {
+            return "/";
+        } else if (contextPath.charAt(contextPath.length() - 1) != '/') {
+            return contextPath + "/";
+        } else {
+            return contextPath;
+        }
+    }
+
+    private static final class ResponseWriter implements ContainerResponseWriter {
+
+        private final Request request;
+        private final Response response;
+        private final Callback callback;
+        private final boolean configSetStatusOverSendError;
+        private final Timer timer = new Timer();
+        private final long asyncStartTimeMillis;
+        private final ConcurrentLinkedQueue<TimeoutHandler> timeoutHandlerQueue = new ConcurrentLinkedQueue<>();
+        private TimerTask currentTimerTask;
+
+        ResponseWriter(final Request request, final Response response, final Callback callback,
+                       final boolean configSetStatusOverSendError) {
+            this.request = request;
+            this.response = response;
+            this.callback = callback;
+            this.asyncStartTimeMillis = System.currentTimeMillis();
+            this.configSetStatusOverSendError = configSetStatusOverSendError;
+        }
+
+        private synchronized void setNewTimeout(long timeOut, TimeUnit timeUnit) {
+            long timeOutMillis = timeUnit.toMillis(timeOut);
+            if (currentTimerTask != null) {
+                currentTimerTask.cancel();
+            }
+            currentTimerTask = new TimerTask() {
+                @Override
+                public void run() {
+                    timeoutHandlerQueue.forEach(timeoutHandler -> timeoutHandler.onTimeout(ResponseWriter.this));
+                }
+            };
+            timer.schedule(currentTimerTask, Math.max(0, timeOutMillis + asyncStartTimeMillis - System.currentTimeMillis()));
+        }
+
+        @Override
+        public OutputStream writeResponseStatusAndHeaders(final long contentLength, final ContainerResponse context)
+                throws ContainerException {
+
+            final jakarta.ws.rs.core.Response.StatusType statusInfo = context.getStatusInfo();
+
+            final int code = statusInfo.getStatusCode();
+
+            response.setStatus(code);
+
+            if (contentLength != -1 && contentLength < Integer.MAX_VALUE && !"HEAD".equals(request.getMethod())) {
+                response.getHeaders().add(new HttpField(HttpHeader.CONTENT_LENGTH, String.valueOf((int) contentLength)));
+            }
+            for (final Map.Entry<String, List<String>> e : context.getStringHeaders().entrySet()) {
+                for (final String value : e.getValue()) {
+                    response.getHeaders().add(new HttpField(e.getKey(), value));
+                }
+            }
+
+            return Content.Sink.asOutputStream(response);
+        }
+
+        @Override
+        public boolean suspend(final long timeOut, final TimeUnit timeUnit, final TimeoutHandler timeoutHandler) {
+            if (timeOut > 0) {
+                setNewTimeout(timeOut, timeUnit);
+            }
+            if (timeoutHandler != null) {
+                timeoutHandlerQueue.add(timeoutHandler);
+            }
+            return true;
+        }
+
+        @Override
+        public void setSuspendTimeout(final long timeOut, final TimeUnit timeUnit) throws IllegalStateException {
+            if (timeOut > 0) {
+                setNewTimeout(timeOut, timeUnit);
+            }
+        }
+
+        @Override
+        public void commit() {
+            callback.succeeded();
+            LOGGER.log(Level.FINEST, "commit() called");
+        }
+
+        @Override
+        public void failure(final Throwable error) {
+            try {
+                if (!response.isCommitted()) {
+                    try {
+                        if (configSetStatusOverSendError) {
+                            response.reset();
+                            response.setStatus(INTERNAL_SERVER_ERROR);
+                            callback.failed(error);
+                        } else {
+                            Response.writeError(request, response, callback, INTERNAL_SERVER_ERROR, "Request failed.", error);
+                        }
+                    } catch (final IllegalStateException ex) {
+                        // a race condition externally committing the response can still occur...
+                        LOGGER.log(Level.FINER, "Unable to reset failed response.", ex);
+                    }
+                }
+            } finally {
+                LOGGER.log(Level.FINEST, "failure(...) called");
+                rethrow(error);
+            }
+        }
+
+        @Override
+        public boolean enableResponseBuffering() {
+            return false;
+        }
+
+        /**
+         * Rethrow the original exception as required by JAX-RS, 3.3.4.
+         *
+         * @param error throwable to be re-thrown
+         */
+        private void rethrow(final Throwable error) {
+            if (error instanceof RuntimeException) {
+                throw (RuntimeException) error;
+            } else {
+                throw new ContainerException(error);
+            }
+        }
+
+    }
+
+    @Override
+    public ResourceConfig getConfiguration() {
+        return appHandler.getConfiguration();
+    }
+
+    @Override
+    public void reload() {
+        reload(new ResourceConfig(getConfiguration()));
+    }
+
+    @Override
+    public void reload(final ResourceConfig configuration) {
+        appHandler.onShutdown(this);
+
+        appHandler = new ApplicationHandler(configuration.register(new JettyBinder()));
+        appHandler.onReload(this);
+        appHandler.onStartup(this);
+        cacheConfigSetStatusOverSendError();
+    }
+
+    @Override
+    public ApplicationHandler getApplicationHandler() {
+        return appHandler;
+    }
+
+    /**
+     * Inform this container that the server has been started.
+     * This method must be implicitly called after the server containing this container is started.
+     *
+     * @throws java.lang.Exception if a problem occurred during server startup.
+     */
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        appHandler.onStartup(this);
+    }
+
+    /**
+     * Inform this container that the server is being stopped.
+     * This method must be implicitly called before the server containing this container is stopped.
+     *
+     * @throws java.lang.Exception if a problem occurred during server shutdown.
+     */
+    @Override
+    public void doStop() throws Exception {
+        super.doStop();
+        appHandler.onShutdown(this);
+        appHandler = null;
+    }
+
+    /**
+     * Create a new Jetty HTTP container.
+     *
+     * @param application   JAX-RS / Jersey application to be deployed on Jetty HTTP container.
+     * @param parentContext DI provider specific context with application's registered bindings.
+     */
+    JettyHttpContainer(final Application application, final Object parentContext) {
+        this.appHandler = new ApplicationHandler(application, new JettyBinder(), parentContext);
+    }
+
+    /**
+     * Create a new Jetty HTTP container.
+     *
+     * @param application JAX-RS / Jersey application to be deployed on Jetty HTTP container.
+     */
+    JettyHttpContainer(final Application application) {
+        this.appHandler = new ApplicationHandler(application, new JettyBinder());
+
+        cacheConfigSetStatusOverSendError();
+    }
+
+    /**
+     * Create a new Jetty HTTP container.
+     *
+     * @param applicationClass JAX-RS / Jersey class of application to be deployed on Jetty HTTP container.
+     */
+    JettyHttpContainer(final Class<? extends Application> applicationClass) {
+        this.appHandler = new ApplicationHandler(applicationClass, new JettyBinder());
+
+        cacheConfigSetStatusOverSendError();
+    }
+
+    /**
+     * The method reads and caches value of configuration property
+     * {@link ServerProperties#RESPONSE_SET_STATUS_OVER_SEND_ERROR} for future purposes.
+     */
+    private void cacheConfigSetStatusOverSendError() {
+        this.configSetStatusOverSendError = ServerProperties.getValue(getConfiguration().getProperties(),
+                ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, false, Boolean.class);
+    }
+
+}
diff --git a/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
new file mode 100644
index 0000000..26a4b79
--- /dev/null
+++ b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty;
+
+import java.net.URI;
+import java.util.concurrent.ThreadFactory;
+
+import jakarta.ws.rs.ProcessingException;
+
+import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
+import org.glassfish.jersey.jetty.internal.LocalizationMessages;
+import org.glassfish.jersey.process.JerseyProcessingUncaughtExceptionHandler;
+import org.glassfish.jersey.server.ContainerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.spi.Container;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+
+/**
+ * Factory for creating and starting Jetty server handlers. This returns
+ * a handle to the started server as {@link Server} instances, which allows
+ * the server to be stopped by invoking the {@link org.eclipse.jetty.server.Server#stop()} method.
+ * <p/>
+ * To start the server in HTTPS mode an {@link SslContextFactory} can be provided.
+ * This will be used to decrypt and encrypt information sent over the
+ * connected TCP socket channel.
+ *
+ * @author Arul Dhesiaseelan (aruld@acm.org)
+ * @author Marek Potociar
+ */
+public final class JettyHttpContainerFactory {
+
+    private JettyHttpContainerFactory() {
+    }
+
+    /**
+     * Creates a {@link Server} instance that registers an {@link org.eclipse.jetty.server.Handler}.
+     *
+     * @param uri uri on which the {@link org.glassfish.jersey.server.ApplicationHandler} will be deployed. Only first path
+     *            segment will be used as context path, the rest will be ignored.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri) throws ProcessingException {
+        return createServer(uri, null, null, true);
+    }
+
+    /**
+     * Creates a {@link Server} instance that registers an {@link org.eclipse.jetty.server.Handler}.
+     *
+     * @param uri   uri on which the {@link org.glassfish.jersey.server.ApplicationHandler} will be deployed. Only first path
+     *              segment will be used as context path, the rest will be ignored.
+     * @param start if set to false, server will not get started, which allows to configure the underlying transport
+     *              layer, see above for details.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri, final boolean start) throws ProcessingException {
+        return createServer(uri, null, null, start);
+    }
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     * <p/>
+     * This implementation defers to the
+     * {@link org.glassfish.jersey.server.ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+     * for creating an Container that manages the root resources.
+     *
+     * @param uri    the URI to create the http server. The URI scheme must be
+     *               equal to "http". The URI user information and host
+     *               are ignored If the URI port is not present then port 80 will be
+     *               used. The URI path, query and fragment components are ignored.
+     * @param config the resource configuration.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri, final ResourceConfig config)
+            throws ProcessingException {
+
+        final JettyHttpContainer container = ContainerFactory.createContainer(JettyHttpContainer.class, config);
+        return createServer(uri, null, container, true);
+    }
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     * <p/>
+     * This implementation defers to the
+     * {@link org.glassfish.jersey.server.ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+     * for creating an Container that manages the root resources.
+     *
+     * @param uri           URI on which the Jersey web application will be deployed. Only first path segment will be
+     *                      used as context path, the rest will be ignored.
+     * @param configuration web application configuration.
+     * @param start         if set to false, server will not get started, which allows to configure the underlying
+     *                      transport layer, see above for details.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri, final ResourceConfig configuration, final boolean start)
+            throws ProcessingException {
+        return createServer(uri, null, ContainerFactory.createContainer(JettyHttpContainer.class, configuration), start);
+    }
+
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     *
+     * @param uri           the URI to create the http server. The URI scheme must be
+     *                      equal to "https". The URI user information and host
+     *                      are ignored If the URI port is not present then port 143 will be
+     *                      used. The URI path, query and fragment components are ignored.
+     * @param config        the resource configuration.
+     * @param parentContext DI provider specific context with application's registered bindings.
+     * @param start         if set to false, server will not get started, this allows end users to set
+     *                      additional properties on the underlying listener.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     * @see JettyHttpContainer
+     * @since 2.12
+     */
+    public static Server createServer(final URI uri, final ResourceConfig config, final boolean start,
+                                      final Object parentContext) {
+        return createServer(uri, null, new JettyHttpContainer(config, parentContext), start);
+    }
+
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     *
+     * @param uri           the URI to create the http server. The URI scheme must be
+     *                      equal to "https". The URI user information and host
+     *                      are ignored If the URI port is not present then port 143 will be
+     *                      used. The URI path, query and fragment components are ignored.
+     * @param config        the resource configuration.
+     * @param parentContext DI provider specific context with application's registered bindings.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     * @see JettyHttpContainer
+     * @since 2.12
+     */
+    public static Server createServer(final URI uri, final ResourceConfig config, final Object parentContext) {
+        return createServer(uri, null, new JettyHttpContainer(config, parentContext), true);
+    }
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     * <p/>
+     * This implementation defers to the
+     * {@link ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+     * for creating an Container that manages the root resources.
+     *
+     * @param uri               the URI to create the http server. The URI scheme must be
+     *                          equal to {@code https}. The URI user information and host
+     *                          are ignored. If the URI port is not present then port
+     *                          {@value org.glassfish.jersey.server.spi.Container#DEFAULT_HTTPS_PORT} will be
+     *                          used. The URI path, query and fragment components are ignored.
+     * @param sslContextFactory this is the SSL context factory used to configure SSL connector
+     * @param config            the resource configuration.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri, final SslContextFactory.Server sslContextFactory,
+                                      final ResourceConfig config)
+            throws ProcessingException {
+        final JettyHttpContainer container = ContainerFactory.createContainer(JettyHttpContainer.class, config);
+        return createServer(uri, sslContextFactory, container, true);
+    }
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes found by searching the
+     * classes referenced in the java classpath.
+     *
+     * @param uri               the URI to create the http server. The URI scheme must be
+     *                          equal to {@code https}. The URI user information and host
+     *                          are ignored. If the URI port is not present then port
+     *                          {@value org.glassfish.jersey.server.spi.Container#DEFAULT_HTTPS_PORT} will be
+     *                          used. The URI path, query and fragment components are ignored.
+     * @param sslContextFactory this is the SSL context factory used to configure SSL connector
+     * @param handler           the container that handles all HTTP requests
+     * @param start             if set to false, server will not get started, this allows end users to set
+     *                          additional properties on the underlying listener.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     * @see JettyHttpContainer
+     */
+    public static Server createServer(final URI uri,
+                                      final SslContextFactory.Server sslContextFactory,
+                                      final JettyHttpContainer handler,
+                                      final boolean start) {
+        if (uri == null) {
+            throw new IllegalArgumentException(LocalizationMessages.URI_CANNOT_BE_NULL());
+        }
+        final String scheme = uri.getScheme();
+        int defaultPort = Container.DEFAULT_HTTP_PORT;
+
+        if (sslContextFactory == null) {
+            if (!"http".equalsIgnoreCase(scheme)) {
+                throw new IllegalArgumentException(LocalizationMessages.WRONG_SCHEME_WHEN_USING_HTTP());
+            }
+        } else {
+            if (!"https".equalsIgnoreCase(scheme)) {
+                throw new IllegalArgumentException(LocalizationMessages.WRONG_SCHEME_WHEN_USING_HTTPS());
+            }
+            defaultPort = Container.DEFAULT_HTTPS_PORT;
+        }
+        final int port = (uri.getPort() == -1) ? defaultPort : uri.getPort();
+
+        final Server server = new Server(new JettyConnectorThreadPool());
+        final HttpConfiguration config = new HttpConfiguration();
+        if (sslContextFactory != null) {
+            config.setSecureScheme("https");
+            config.setSecurePort(port);
+            config.addCustomizer(new SecureRequestCustomizer());
+
+            final ServerConnector https = new ServerConnector(server,
+                    new SslConnectionFactory(sslContextFactory, "http/1.1"),
+                    new HttpConnectionFactory(config));
+            https.setPort(port);
+            server.setConnectors(new Connector[]{https});
+
+        } else {
+            final ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(config));
+            http.setPort(port);
+            server.setConnectors(new Connector[]{http});
+        }
+        if (handler != null) {
+            server.setHandler(handler);
+        }
+
+        if (start) {
+            try {
+                // Start the server.
+                server.start();
+            } catch (final Exception e) {
+                throw new ProcessingException(LocalizationMessages.ERROR_WHEN_CREATING_SERVER(), e);
+            }
+        }
+        return server;
+    }
+
+    // TODO: Use https://www.eclipse.org/jetty/javadoc/current/org/eclipse/jetty/util/thread/QueuedThreadPool.html
+    //  #%3Cinit%3E(int,int,int,int,java.util.concurrent.BlockingQueue,java.lang.ThreadGroup,java.util.concurrent.ThreadFactory)
+    //
+    //  Keeping this for backwards compatibility for the time being
+    private static final class JettyConnectorThreadPool extends QueuedThreadPool {
+        private final ThreadFactory threadFactory = new ThreadFactoryBuilder()
+                .setNameFormat("jetty-http-server-%d")
+                .setUncaughtExceptionHandler(new JerseyProcessingUncaughtExceptionHandler())
+                .build();
+
+        @Override
+        public Thread newThread(Runnable runnable) {
+            return threadFactory.newThread(runnable);
+        }
+    }
+}
diff --git a/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpServer.java b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpServer.java
new file mode 100644
index 0000000..9734342
--- /dev/null
+++ b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpServer.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty;
+
+import static jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication.MANDATORY;
+import static jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication.OPTIONAL;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.glassfish.jersey.server.ContainerFactory;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+
+/**
+ * Jersey {@code Server} implementation based on Jetty
+ * {@link org.eclipse.jetty.server.Server Server}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+final class JettyHttpServer implements WebServer {
+
+    private final JettyHttpContainer container;
+
+    private final org.eclipse.jetty.server.Server httpServer;
+
+    JettyHttpServer(final Application application, final JerseySeBootstrapConfiguration configuration) {
+        this(ContainerFactory.createContainer(JettyHttpContainer.class, application), configuration);
+    }
+
+    JettyHttpServer(final Class<? extends Application> applicationClass,
+                    final JerseySeBootstrapConfiguration configuration) {
+        this(new JettyHttpContainer(applicationClass), configuration);
+    }
+
+    JettyHttpServer(final JettyHttpContainer container, final JerseySeBootstrapConfiguration configuration) {
+        final SeBootstrap.Configuration.SSLClientAuthentication sslClientAuthentication = configuration
+                .sslClientAuthentication();
+        final SslContextFactory.Server sslContextFactory;
+        if (configuration.isHttps()) {
+            sslContextFactory = new SslContextFactory.Server();
+            sslContextFactory.setSslContext(configuration.sslContext());
+            sslContextFactory.setWantClientAuth(sslClientAuthentication == OPTIONAL);
+            sslContextFactory.setNeedClientAuth(sslClientAuthentication == MANDATORY);
+        } else {
+            sslContextFactory = null;
+        }
+        this.container = container;
+        this.httpServer = JettyHttpContainerFactory.createServer(
+                configuration.uri(true),
+                sslContextFactory,
+                this.container,
+                configuration.autoStart());
+    }
+
+    @Override
+    public final JettyHttpContainer container() {
+        return this.container;
+    }
+
+    @Override
+    public final int port() {
+        final ServerConnector serverConnector = (ServerConnector) this.httpServer.getConnectors()[0];
+        final int configuredPort = serverConnector.getPort();
+        final int localPort = serverConnector.getLocalPort();
+        return localPort < 0 ? configuredPort : localPort;
+    }
+
+    @Override
+    public final CompletableFuture<Void> start() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                this.httpServer.start();
+            } catch (final Exception e) {
+                throw new CompletionException(e);
+            }
+        });
+    }
+
+    @Override
+    public final CompletableFuture<Void> stop() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                this.httpServer.stop();
+            } catch (final Exception e) {
+                throw new CompletionException(e);
+            }
+        });
+    }
+
+    @Override
+    public final <T> T unwrap(final Class<T> nativeClass) {
+        return nativeClass.cast(this.httpServer);
+    }
+
+}
diff --git a/containers/jetty-http/src/main/java8/org/glassfish/jersey/jetty/JettyHttpContainer.java b/containers/jetty-http/src/main/java8/org/glassfish/jersey/jetty/JettyHttpContainer.java
deleted file mode 100644
index a2159c8..0000000
--- a/containers/jetty-http/src/main/java8/org/glassfish/jersey/jetty/JettyHttpContainer.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2020, 2023 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.jetty;
-
-import jakarta.ws.rs.ProcessingException;
-import jakarta.ws.rs.core.Application;
-import org.glassfish.jersey.jetty.internal.LocalizationMessages;
-import org.glassfish.jersey.server.ApplicationHandler;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.spi.Container;
-
-/**
- * Jersey {@code Container} stub based on Jetty {@link org.eclipse.jetty.server.Handler}.
- *
- * For JDK 1.8 only since Jetty 11 does not support JDKs below 11
- *
- */
-public final class JettyHttpContainer implements Container {
-
-    public JettyHttpContainer(Application application) {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    public JettyHttpContainer(Application application, final Object parentContext) {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    @Override
-    public ResourceConfig getConfiguration() {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    @Override
-    public ApplicationHandler getApplicationHandler() {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    @Override
-    public void reload() {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    @Override
-    public void reload(ResourceConfig configuration) {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-}
diff --git a/containers/jetty-http/src/main/java8/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java b/containers/jetty-http/src/main/java8/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
deleted file mode 100644
index 1218c2e..0000000
--- a/containers/jetty-http/src/main/java8/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.jetty;
-
-import jakarta.ws.rs.ProcessingException;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.glassfish.jersey.internal.util.JdkVersion;
-import org.glassfish.jersey.jetty.internal.LocalizationMessages;
-import org.glassfish.jersey.server.ResourceConfig;
-
-import java.net.URI;
-
-/**
- * Jersey {@code Container} stub.
- *
- * For JDK 1.8 only since Jetty 11 does not support JDKs below 11
- *
- */
-public final class JettyHttpContainerFactory {
-
-    private JettyHttpContainerFactory() {
-    }
-
-    public static Server createServer(final URI uri) throws ProcessingException {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createServer(final URI uri, final boolean start) throws ProcessingException {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createServer(final URI uri, final ResourceConfig config)
-            throws ProcessingException {
-
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createServer(final URI uri, final ResourceConfig configuration, final boolean start)
-            throws ProcessingException {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createServer(final URI uri, final ResourceConfig config, final boolean start,
-                                      final Object parentContext) {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createServer(final URI uri, final ResourceConfig config, final Object parentContext) {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createServer(final URI uri, final SslContextFactory.Server sslContextFactory,
-                                      final ResourceConfig config)
-            throws ProcessingException {
-        validateJdk();
-        return null; // does not work at JDK 1.8    }
-    }
-
-    public static Server createServer(final URI uri,
-                                      final SslContextFactory.Server sslContextFactory,
-                                      final JettyHttpContainer handler,
-                                      final boolean start) {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    private static void validateJdk() {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
-            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-        }
-    }
-}
diff --git a/containers/jetty-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider b/containers/jetty-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
new file mode 100644
index 0000000..403cc50
--- /dev/null
+++ b/containers/jetty-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.jetty.JettyHttpServerProvider
\ No newline at end of file
diff --git a/containers/jetty-http/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties b/containers/jetty-http/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
index 6d0d06c..8d507d5 100644
--- a/containers/jetty-http/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
+++ b/containers/jetty-http/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
 #
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License v. 2.0, which is available at
@@ -21,4 +21,4 @@
 uri.cannot.be.null=The URI must not be null.
 wrong.scheme.when.using.http=The URI scheme should be 'http' when not using SSL.
 wrong.scheme.when.using.https=The URI scheme should be 'https' when using SSL.
-not.supported=Jetty container is not supported on JDK version less than 11.
+not.supported=Jetty container is not supported on JDK version less than 17.
diff --git a/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/AbstractJettyServerTester.java b/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/AbstractJettyServerTester.java
index 3a953e1..7519624 100644
--- a/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/AbstractJettyServerTester.java
+++ b/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/AbstractJettyServerTester.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -29,6 +30,7 @@
 import org.glassfish.jersey.server.ResourceConfig;
 
 import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
 import org.junit.jupiter.api.AfterEach;
 
 /**
@@ -51,20 +53,24 @@
      * @return The HTTP port of the URI
      */
     protected final int getPort() {
+        if (server != null) {
+            return ((ServerConnector) server.getConnectors()[0]).getLocalPort();
+        }
+
         final String value = AccessController
                 .doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
         if (value != null) {
 
             try {
                 final int i = Integer.parseInt(value);
-                if (i <= 0) {
-                    throw new NumberFormatException("Value not positive.");
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
                 }
                 return i;
             } catch (NumberFormatException e) {
                 LOGGER.log(Level.CONFIG,
                         "Value of 'jersey.config.test.container.port'"
-                                + " property is not a valid positive integer [" + value + "]."
+                                + " property is not a valid non-negative integer [" + value + "]."
                                 + " Reverting to default [" + DEFAULT_PORT + "].",
                         e);
             }
@@ -89,18 +95,16 @@
         return UriBuilder.fromUri("http://localhost").port(getPort(RuntimeType.CLIENT)).path(CONTEXT);
     }
 
-    public void startServer(Class... resources) {
+    public void startServer(Class<?>... resources) {
         ResourceConfig config = new ResourceConfig(resources);
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
-        final URI baseUri = getBaseUri();
-        server = JettyHttpContainerFactory.createServer(baseUri, config);
-        LOGGER.log(Level.INFO, "Jetty-http server started on base uri: " + server.getURI());
+        startServer(config);
     }
 
     public void startServer(ResourceConfig config) {
         final URI baseUri = getBaseUri();
         server = JettyHttpContainerFactory.createServer(baseUri, config);
-        LOGGER.log(Level.INFO, "Jetty-http server started on base uri: " + server.getURI());
+        LOGGER.log(Level.INFO, "Jetty-http server started on base uri: " + getBaseUri());
     }
 
     public URI getBaseUri() {
diff --git a/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/JettyHttpServerProviderTest.java b/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/JettyHttpServerProviderTest.java
new file mode 100644
index 0000000..004a334
--- /dev/null
+++ b/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/JettyHttpServerProviderTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty;
+
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+
+import java.security.AccessController;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLContext;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+/**
+ * Unit tests for {@link JettyHttpServerProvider}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class JettyHttpServerProviderTest {
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServer() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        shouldProvideServer(ShouldProvideServerApplication.class, resource);
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServerWithClass() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        final Application application = new ShouldProvideServerApplication();
+        shouldProvideServer(application.getClass(), resource);
+    }
+
+    private void shouldProvideServer(final Object application, final Resource resource)
+            throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new JettyHttpServerProvider();
+        final SeBootstrap.Configuration configuration = configuration(getPort(), FALSE);
+
+        // when
+        final WebServer webServer = Application.class.isInstance(application)
+                ? webServerProvider.createServer(WebServer.class, (Application) application, configuration)
+                : webServerProvider.createServer(WebServer.class, (Class<Application>) application, configuration);
+        final Object nativeHandle = webServer.unwrap(Object.class);
+        final CompletionStage<?> start = webServer.start();
+        final Object startResult = start.toCompletableFuture().get();
+        final Container container = webServer.container();
+        final int port = webServer.port();
+        final String entity = ClientBuilder.newClient()
+                .target(UriBuilder.newInstance().scheme("http").host("localhost").port(port).build()).request()
+                .get(String.class);
+        final CompletionStage<?> stop = webServer.stop();
+        final Object stopResult = stop.toCompletableFuture().get();
+
+        // then
+        assertThat(webServer, is(instanceOf(JettyHttpServer.class)));
+        assertThat(nativeHandle, is(instanceOf(org.eclipse.jetty.server.Server.class)));
+        assertThat(startResult, is(nullValue()));
+        assertThat(container, is(instanceOf(JettyHttpContainer.class)));
+        assertThat(port, is(greaterThan(0)));
+        assertThat(entity, is(resource.toString()));
+        assertThat(stopResult, is(nullValue()));
+    }
+
+    @Path("/")
+    protected static final class Resource {
+        @GET
+        @Override
+        public String toString() {
+            return Resource.class.getName();
+        }
+    }
+
+    protected static class ShouldProvideServerApplication extends Application {
+        @Override
+        public Set<Object> getSingletons() {
+            return Collections.singleton(new Resource());
+        }
+    }
+
+    private static final Logger LOGGER = Logger.getLogger(JettyHttpServerProviderTest.class.getName());
+
+    private static final int DEFAULT_PORT = 0;
+
+    private static final int getPort() {
+        final String value = AccessController
+                .doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
+        if (value != null) {
+            try {
+                final int i = Integer.parseInt(value);
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
+                }
+                return i;
+            } catch (final NumberFormatException e) {
+                LOGGER.log(Level.CONFIG,
+                        "Value of 'jersey.config.test.container.port'"
+                                + " property is not a valid non-negative integer [" + value + "]."
+                                + " Reverting to default [" + DEFAULT_PORT + "].",
+                        e);
+            }
+        }
+
+        return DEFAULT_PORT;
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public final void shouldScanFreePort() throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new JettyHttpServerProvider();
+        final Application application = new Application();
+        final SeBootstrap.Configuration configuration = configuration(SeBootstrap.Configuration.FREE_PORT, TRUE);
+
+        // when
+        final WebServer webServer = webServerProvider.createServer(WebServer.class, application, configuration);
+
+        // then
+        assertThat(webServer.port(), is(greaterThan(0)));
+    }
+
+    private SeBootstrap.Configuration configuration(int port, boolean autoStart) {
+        return (SeBootstrap.Configuration) name -> {
+            switch (name) {
+                case SeBootstrap.Configuration.PROTOCOL:
+                    return "HTTP";
+                case SeBootstrap.Configuration.HOST:
+                    return "localhost";
+                case SeBootstrap.Configuration.PORT:
+                    return port;
+                case SeBootstrap.Configuration.ROOT_PATH:
+                    return "/";
+                case SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION:
+                    return SSLClientAuthentication.NONE;
+                case SeBootstrap.Configuration.SSL_CONTEXT:
+                    try {
+                        return SSLContext.getDefault();
+                    } catch (final NoSuchAlgorithmException e) {
+                        throw new RuntimeException(e);
+                    }
+                case ServerProperties.WEBSERVER_AUTO_START:
+                    return autoStart;
+                default:
+                    return null;
+            }
+        };
+    }
+
+}
\ No newline at end of file
diff --git a/containers/jetty-http2/pom.xml b/containers/jetty-http2/pom.xml
deleted file mode 100644
index e5a083f..0000000
--- a/containers/jetty-http2/pom.xml
+++ /dev/null
@@ -1,304 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
-
-    This program and the accompanying materials are made available under the
-    terms of the Eclipse Public License v. 2.0, which is available at
-    http://www.eclipse.org/legal/epl-2.0.
-
-    This Source Code may also be made available under the following Secondary
-    Licenses when the conditions for such availability set forth in the
-    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
-    version 2 with the GNU Classpath Exception, which is available at
-    https://www.gnu.org/software/classpath/license.html.
-
-    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
-
--->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <artifactId>project</artifactId>
-        <groupId>org.glassfish.jersey.containers</groupId>
-        <version>3.0.99-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>jersey-container-jetty-http2</artifactId>
-    <packaging>jar</packaging>
-    <name>jersey-container-jetty-http2</name>
-
-    <description>Jetty Http2 Container</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.glassfish.jersey.containers</groupId>
-            <artifactId>jersey-container-jetty-http</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>jakarta.inject</groupId>
-            <artifactId>jakarta.inject-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-api</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-util</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-api</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty.http2</groupId>
-            <artifactId>http2-server</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-api</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-alpn-conscrypt-server</artifactId>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-api</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpclient</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>com.sun.istack</groupId>
-                <artifactId>istack-commons-maven-plugin</artifactId>
-                <inherited>true</inherited>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>build-helper-maven-plugin</artifactId>
-                <inherited>true</inherited>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <inherited>true</inherited>
-                <configuration>
-                    <instructions>
-                        <Import-Package>
-                            ${jetty.osgi.version},
-                            *
-                        </Import-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-
-        <resources>
-            <resource>
-                <directory>${basedir}/src/main/resources</directory>
-                <filtering>true</filtering>
-            </resource>
-        </resources>
-    </build>
-
-    <properties>
-        <java8.build.outputDirectory>${project.basedir}/target</java8.build.outputDirectory>
-        <java8.sourceDirectory>${project.basedir}/src/main/java8</java8.sourceDirectory>
-        <java11.build.outputDirectory>${project.basedir}/target11</java11.build.outputDirectory>
-        <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
-    </properties>
-
-
-    <profiles>
-        <profile>
-            <id>JettyExclude</id>
-            <activation>
-                <jdk>1.8</jdk>
-            </activation>
-            <properties>
-                <jetty.version>${jetty9.version}</jetty.version>
-            </properties>
-            <dependencies>
-                <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-client</artifactId>
-                    <version>${jetty.version}</version>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-                <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-util</artifactId>
-                    <version>${jetty.version}</version>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-            </dependencies>
-            <build>
-                <directory>${java8.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java8.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <configuration>
-                            <testExcludes>
-                                <testExclude>org/glassfish/jersey/jetty/http2/*.java</testExclude>
-                            </testExcludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>Jetty11</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <build>
-                <directory>${java11.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java11.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>copyJDK11FilesToMultiReleaseJar</id>
-            <activation>
-                <file>
-                    <!-- ${java11.build.outputDirectory} does not work here -->
-                    <exists>target11/classes/org/glassfish/jersey/jetty/JettyHttp2ContainerFactory.class</exists>
-                </file>
-                <jdk>1.8</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.felix</groupId>
-                        <artifactId>maven-bundle-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <extensions>true</extensions>
-                        <configuration>
-                            <instructions>
-                                <Multi-Release>true</Multi-Release>
-                            </instructions>
-                        </configuration>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-resources-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <executions>
-                            <execution>
-                                <id>copy-jdk11-classes</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${java8.build.outputDirectory}/classes/META-INF/versions/11</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>${java11.build.outputDirectory}/classes</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-antrun-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <id>copy-jdk11-sources</id>
-                                <phase>package</phase>
-                                <configuration>
-                                    <target>
-                                        <property name="sources-jar" value="${java8.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
-                                        <echo>sources-jar: ${sources-jar}</echo>
-                                        <zip destfile="${sources-jar}" update="true">
-                                            <zipfileset dir="${java11.sourceDirectory}" prefix="META-INF/versions/11"/>
-                                        </zip>
-                                    </target>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-
-</project>
diff --git a/containers/jetty-http2/src/main/java8/org/glassfish/jersey/jetty/http2/JettyHttp2ContainerFactory.java b/containers/jetty-http2/src/main/java8/org/glassfish/jersey/jetty/http2/JettyHttp2ContainerFactory.java
deleted file mode 100644
index 6b148ed..0000000
--- a/containers/jetty-http2/src/main/java8/org/glassfish/jersey/jetty/http2/JettyHttp2ContainerFactory.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.jetty.http2;
-
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-
-import org.glassfish.jersey.internal.util.JdkVersion;
-import org.glassfish.jersey.jetty.JettyHttpContainer;
-import org.glassfish.jersey.jetty.http2.LocalizationMessages;
-import org.glassfish.jersey.server.ContainerFactory;
-import org.glassfish.jersey.server.ResourceConfig;
-
-import jakarta.ws.rs.ProcessingException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-public final class JettyHttp2ContainerFactory {
-
-    private JettyHttp2ContainerFactory() {
-
-    }
-
-    public static Server createHttp2Server(final URI uri) throws ProcessingException {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createHttp2Server(final URI uri, final ResourceConfig configuration, final boolean start)
-            throws ProcessingException {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createHttp2Server(final URI uri, final boolean start) throws ProcessingException {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createHttp2Server(final URI uri, final ResourceConfig config, final boolean start,
-                                           final Object parentContext) {
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    public static Server createHttp2Server(final URI uri,
-                                           final SslContextFactory.Server sslContextFactory,
-                                           final JettyHttpContainer handler,
-                                           final boolean start) {
-
-        validateJdk();
-        return null; // does not work at JDK 1.8
-    }
-
-    private static void validateJdk() {
-        if (JdkVersion.getJdkVersion().getMajor() < 11) {
-            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-        }
-    }
-}
diff --git a/containers/jetty-http2/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ContainerProvider b/containers/jetty-http2/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ContainerProvider
deleted file mode 100644
index 4d2a88d..0000000
--- a/containers/jetty-http2/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ContainerProvider
+++ /dev/null
@@ -1 +0,0 @@
-org.glassfish.jersey.jetty.http2.JettyHttp2ContainerProvider
\ No newline at end of file
diff --git a/containers/jetty-servlet/pom.xml b/containers/jetty-servlet/pom.xml
index 58a2d63..1f3c4db 100644
--- a/containers/jetty-servlet/pom.xml
+++ b/containers/jetty-servlet/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-container-jetty-servlet</artifactId>
@@ -32,6 +32,13 @@
 
     <description>Jetty Servlet Container</description>
 
+    <properties>
+        <java11.build.outputDirectory>${project.basedir}/target</java11.build.outputDirectory>
+        <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
+        <java17.build.outputDirectory>${project.basedir}/target17</java17.build.outputDirectory>
+        <java17.sourceDirectory>${project.basedir}/src/main/java17</java17.sourceDirectory>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>org.glassfish.jersey.containers</groupId>
@@ -46,7 +53,21 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.ee10</groupId>
+            <artifactId>jetty-ee10-webapp</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-jetty-http</artifactId>
+            <version>${project.version}</version>
         </dependency>
     </dependencies>
 
@@ -76,108 +97,54 @@
         </plugins>
     </build>
 
-    <properties>
-        <java8.build.outputDirectory>${project.basedir}/target</java8.build.outputDirectory>
-        <java8.sourceDirectory>${project.basedir}/src/main/java8</java8.sourceDirectory>
-        <java11.build.outputDirectory>${project.basedir}/target11</java11.build.outputDirectory>
-        <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
-        <jetty.javax.version>${jetty9.version}</jetty.javax.version>
-    </properties>
-
     <profiles>
         <profile>
             <id>JettyExclude</id>
             <activation>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <dependencies>
                 <dependency>
                     <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>jetty-webapp</artifactId>
+                    <version>${jetty11.version}</version>
+                    <scope>provided</scope>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>org.slf4j</groupId>
+                            <artifactId>slf4j-api</artifactId>
+                        </exclusion>
+                    </exclusions>
+                </dependency>
+                <dependency>
+                    <groupId>org.eclipse.jetty.ee10</groupId>
+                    <artifactId>jetty-ee10-webapp</artifactId>
+                    <scope>provided</scope>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>*</groupId>
+                            <artifactId>*</artifactId>
+                        </exclusion>
+                    </exclusions>
+                </dependency>
+                <dependency>
+                    <groupId>org.eclipse.jetty</groupId>
                     <artifactId>jetty-server</artifactId>
-                    <version>${jetty.javax.version}</version>
+                    <version>${jetty11.version}</version>
                     <scope>provided</scope>
                 </dependency>
                 <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-webapp</artifactId>
-                    <version>${jetty.javax.version}</version>
+                    <groupId>org.glassfish.jersey.containers</groupId>
+                    <artifactId>jersey-container-jetty-http</artifactId>
+                    <version>${project.version}</version>
                     <scope>provided</scope>
                     <exclusions>
                         <exclusion>
                             <groupId>org.eclipse.jetty</groupId>
                             <artifactId>jetty-server</artifactId>
                         </exclusion>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
                     </exclusions>
                 </dependency>
-                <dependency>
-                    <groupId>org.glassfish.jersey.containers</groupId>
-                    <artifactId>jersey-container-jetty-http</artifactId>
-                    <version>${project.version}</version>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.eclipse.jetty</groupId>
-                            <artifactId>jetty-server</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-            </dependencies>
-            <build>
-                <directory>${java8.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java8.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <configuration>
-                            <testExcludes>
-                                <testExclude>org/glassfish/jersey/jetty/*.java</testExclude>
-                            </testExcludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>Jetty11</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-webapp</artifactId>
-                    <exclusions>
-                        <exclusion>
-                            <groupId>org.slf4j</groupId>
-                            <artifactId>slf4j-api</artifactId>
-                        </exclusion>
-                    </exclusions>
-                </dependency>
-                <dependency>
-                    <groupId>org.glassfish.jersey.containers</groupId>
-                    <artifactId>jersey-container-jetty-http</artifactId>
-                    <version>${project.version}</version>
-                </dependency>
             </dependencies>
             <build>
                 <directory>${java11.build.outputDirectory}</directory>
@@ -203,13 +170,41 @@
             </build>
         </profile>
         <profile>
-            <id>copyJDK11FilesToMultiReleaseJar</id>
+            <id>JettyInclude</id>
+            <activation>
+                <jdk>[17,)</jdk>
+            </activation>
+            <build>
+                <directory>${java17.build.outputDirectory}</directory>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>add-source</goal>
+                                </goals>
+                                <configuration>
+                                    <sources>
+                                        <source>${java17.sourceDirectory}</source>
+                                    </sources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>copyJDK17FilesToMultiReleaseJar</id>
             <activation>
                 <file>
-                    <!-- ${java11.build.outputDirectory} does not work here -->
-                    <exists>target11/classes/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.class</exists>
+                    <!-- ${java17.build.outputDirectory} does not work here -->
+                    <exists>target17/classes/org/glassfish/jersey/jetty/JettyWebContainerFactory.class</exists>
                 </file>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <build>
                 <plugins>
@@ -230,16 +225,16 @@
                         <inherited>true</inherited>
                         <executions>
                             <execution>
-                                <id>copy-jdk11-classes</id>
+                                <id>copy-jdk17-classes</id>
                                 <phase>prepare-package</phase>
                                 <goals>
                                     <goal>copy-resources</goal>
                                 </goals>
                                 <configuration>
-                                    <outputDirectory>${java8.build.outputDirectory}/classes/META-INF/versions/11</outputDirectory>
+                                    <outputDirectory>${java11.build.outputDirectory}/classes/META-INF/versions/17</outputDirectory>
                                     <resources>
                                         <resource>
-                                            <directory>${java11.build.outputDirectory}/classes</directory>
+                                            <directory>${java17.build.outputDirectory}/classes</directory>
                                         </resource>
                                     </resources>
                                 </configuration>
@@ -251,14 +246,14 @@
                         <artifactId>maven-antrun-plugin</artifactId>
                         <executions>
                             <execution>
-                                <id>copy-jdk11-sources</id>
+                                <id>copy-jdk17-sources</id>
                                 <phase>package</phase>
                                 <configuration>
                                     <target>
-                                        <property name="sources-jar" value="${java8.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+                                        <property name="sources-jar" value="${java11.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
                                         <echo>sources-jar: ${sources-jar}</echo>
                                         <zip destfile="${sources-jar}" update="true">
-                                            <zipfileset dir="${java11.sourceDirectory}" prefix="META-INF/versions/11"/>
+                                            <zipfileset dir="${java17.sourceDirectory}" prefix="META-INF/versions/17"/>
                                         </zip>
                                     </target>
                                 </configuration>
@@ -272,4 +267,5 @@
             </build>
         </profile>
     </profiles>
+
 </project>
diff --git a/containers/jetty-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java b/containers/jetty-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
index 7f46e7b..afbec62 100644
--- a/containers/jetty-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
+++ b/containers/jetty-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,21 +16,15 @@
 
 package org.glassfish.jersey.jetty.servlet;
 
+import jakarta.servlet.Servlet;
+import jakarta.ws.rs.ProcessingException;
+import org.eclipse.jetty.server.Server;
+import org.glassfish.jersey.jetty.internal.LocalizationMessages;
+import org.glassfish.jersey.servlet.ServletContainer;
+
 import java.net.URI;
 import java.util.Map;
 
-import jakarta.servlet.Servlet;
-
-import org.glassfish.jersey.jetty.JettyHttpContainerFactory;
-import org.glassfish.jersey.servlet.ServletContainer;
-import org.glassfish.jersey.uri.UriComponent;
-
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.webapp.Configuration;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.webapp.WebXmlConfiguration;
-
 /**
  * Factory for creating and starting Jetty {@link Server} instances
  * for deploying a Servlet.
@@ -216,46 +210,7 @@
     private static Server create(URI u, Class<? extends Servlet> c, Servlet servlet,
                                  Map<String, String> initParams, Map<String, String> contextInitParams)
             throws Exception {
-        if (u == null) {
-            throw new IllegalArgumentException("The URI must not be null");
-        }
-
-        String path = u.getPath();
-        if (path == null) {
-            throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be non-null");
-        } else if (path.isEmpty()) {
-            throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be present");
-        } else if (path.charAt(0) != '/') {
-            throw new IllegalArgumentException("The URI path, of the URI " + u + ". must start with a '/'");
-        }
-
-        path = String.format("/%s", UriComponent.decodePath(u.getPath(), true).get(1).toString());
-        WebAppContext context = new WebAppContext();
-        context.setDisplayName("JettyContext");
-        context.setContextPath(path);
-        context.setConfigurations(new Configuration[]{new WebXmlConfiguration()});
-        ServletHolder holder;
-        if (c != null) {
-            holder = context.addServlet(c, "/*");
-        } else {
-            holder = new ServletHolder(servlet);
-            context.addServlet(holder, "/*");
-        }
-
-        if (contextInitParams != null) {
-            for (Map.Entry<String, String> e : contextInitParams.entrySet()) {
-                context.setInitParameter(e.getKey(), e.getValue());
-            }
-        }
-
-        if (initParams != null) {
-            holder.setInitParameters(initParams);
-        }
-
-        Server server = JettyHttpContainerFactory.createServer(u, false);
-        server.setHandler(context);
-        server.start();
-        return server;
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 
     /**
@@ -281,4 +236,4 @@
         }
         return create(u, null, servlet, initParams, contextInitParams);
     }
-}
+}
\ No newline at end of file
diff --git a/containers/jetty-servlet/src/main/java17/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java b/containers/jetty-servlet/src/main/java17/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
new file mode 100644
index 0000000..5ada3ed
--- /dev/null
+++ b/containers/jetty-servlet/src/main/java17/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty.servlet;
+
+import java.net.URI;
+import java.util.Map;
+
+import jakarta.servlet.Servlet;
+
+import org.glassfish.jersey.jetty.JettyHttpContainerFactory;
+import org.glassfish.jersey.servlet.ServletContainer;
+import org.glassfish.jersey.uri.UriComponent;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.ee10.servlet.ServletHolder;
+import org.eclipse.jetty.ee10.webapp.Configuration;
+import org.eclipse.jetty.ee10.webapp.WebAppContext;
+import org.eclipse.jetty.ee10.webapp.WebXmlConfiguration;
+
+/**
+ * Factory for creating and starting Jetty {@link Server} instances
+ * for deploying a Servlet.
+ * <p/>
+ * The default deployed server is an instance of {@link ServletContainer}.
+ * <p/>
+ * If no initialization parameters are declared (or is null) then root
+ * resource and provider classes will be found by searching the classes
+ * referenced in the java classpath.
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public final class JettyWebContainerFactory {
+
+    private JettyWebContainerFactory() {
+    }
+
+    /**
+     * Create a {@link Server} that registers the {@link ServletContainer}.
+     *
+     * @param u the URI to create the http server. The URI scheme must be
+     *          equal to "http". The URI user information and host
+     *          are ignored If the URI port is not present then port 80 will be
+     *          used. The URI query and fragment components are ignored. Only first path segment will be used
+     *          as context path, the rest will be ignored.
+     * @return the http server, with the endpoint started.
+     * @throws Exception                if an error occurs creating the container.
+     * @throws IllegalArgumentException if HTTP server URI is {@code null}.
+     */
+    public static Server create(String u)
+            throws Exception {
+        if (u == null) {
+            throw new IllegalArgumentException("The URI must not be null");
+        }
+
+        return create(URI.create(u));
+    }
+
+    /**
+     * Create a {@link Server} that registers the {@link ServletContainer}.
+     *
+     * @param u          the URI to create the http server. The URI scheme must be
+     *                   equal to "http". The URI user information and host
+     *                   are ignored If the URI port is not present then port 80 will be
+     *                   used. The URI query and fragment components are ignored. Only first path segment will be used
+     *                   as context path, the rest will be ignored.
+     * @param initParams the servlet initialization parameters.
+     * @return the http server, with the endpoint started.
+     * @throws Exception                if an error occurs creating the container.
+     * @throws IllegalArgumentException if HTTP server URI is {@code null}.
+     */
+    public static Server create(String u, Map<String, String> initParams)
+            throws Exception {
+        if (u == null) {
+            throw new IllegalArgumentException("The URI must not be null");
+        }
+
+        return create(URI.create(u), initParams);
+    }
+
+    /**
+     * Create a {@link Server} that registers the {@link ServletContainer}.
+     *
+     * @param u the URI to create the http server. The URI scheme must be
+     *          equal to "http". The URI user information and host
+     *          are ignored If the URI port is not present then port 80 will be
+     *          used. The URI query and fragment components are ignored. Only first path segment will be used
+     *          as context path, the rest will be ignored.
+     * @return the http server, with the endpoint started.
+     * @throws Exception                if an error occurs creating the container.
+     * @throws IllegalArgumentException if HTTP server URI is {@code null}.
+     */
+    public static Server create(URI u)
+            throws Exception {
+        return create(u, ServletContainer.class);
+    }
+
+    /**
+     * Create a {@link Server} that registers the {@link ServletContainer}.
+     *
+     * @param u          the URI to create the http server. The URI scheme must be
+     *                   equal to "http". The URI user information and host
+     *                   are ignored If the URI port is not present then port 80 will be
+     *                   used. The URI query and fragment components are ignored. Only first path segment will be used
+     *                   as context path, the rest will be ignored.
+     * @param initParams the servlet initialization parameters.
+     * @return the http server, with the endpoint started.
+     * @throws Exception                if an error occurs creating the container.
+     * @throws IllegalArgumentException if HTTP server URI is {@code null}.
+     */
+    public static Server create(URI u, Map<String, String> initParams)
+            throws Exception {
+        return create(u, ServletContainer.class, initParams);
+    }
+
+    /**
+     * Create a {@link Server} that registers the declared
+     * servlet class.
+     *
+     * @param u the URI to create the http server. The URI scheme must be
+     *          equal to "http". The URI user information and host
+     *          are ignored If the URI port is not present then port 80 will be
+     *          used. The URI query and fragment components are ignored. Only first path segment will be used
+     *          as context path, the rest will be ignored.
+     * @param c the servlet class.
+     * @return the http server, with the endpoint started.
+     * @throws Exception                if an error occurs creating the container.
+     * @throws IllegalArgumentException if HTTP server URI is {@code null}.
+     */
+    public static Server create(String u, Class<? extends Servlet> c)
+            throws Exception {
+        if (u == null) {
+            throw new IllegalArgumentException("The URI must not be null");
+        }
+
+        return create(URI.create(u), c);
+    }
+
+    /**
+     * Create a {@link Server} that registers the declared
+     * servlet class.
+     *
+     * @param u          the URI to create the http server. The URI scheme must be
+     *                   equal to "http". The URI user information and host
+     *                   are ignored If the URI port is not present then port 80 will be
+     *                   used. The URI query and fragment components are ignored. Only first path segment will be used
+     *                   as context path, the rest will be ignored.
+     * @param c          the servlet class.
+     * @param initParams the servlet initialization parameters.
+     * @return the http server, with the endpoint started.
+     * @throws Exception                if an error occurs creating the container.
+     * @throws IllegalArgumentException if HTTP server URI is {@code null}.
+     */
+    public static Server create(String u, Class<? extends Servlet> c,
+                                Map<String, String> initParams)
+            throws Exception {
+        if (u == null) {
+            throw new IllegalArgumentException("The URI must not be null");
+        }
+
+        return create(URI.create(u), c, initParams);
+    }
+
+    /**
+     * Create a {@link Server} that registers the declared
+     * servlet class.
+     *
+     * @param u the URI to create the http server. The URI scheme must be
+     *          equal to "http". The URI user information and host
+     *          are ignored If the URI port is not present then port 80 will be
+     *          used. The URI query and fragment components are ignored. Only first path segment will be used
+     *          as context path, the rest will be ignored.
+     * @param c the servlet class.
+     * @return the http server, with the endpoint started.
+     * @throws Exception                if an error occurs creating the container.
+     * @throws IllegalArgumentException if HTTP server URI is {@code null}.
+     */
+    public static Server create(URI u, Class<? extends Servlet> c)
+            throws Exception {
+        return create(u, c, null);
+    }
+
+    /**
+     * Create a {@link Server} that registers the declared
+     * servlet class.
+     *
+     * @param u          the URI to create the http server. The URI scheme must be
+     *                   equal to "http". The URI user information and host
+     *                   are ignored If the URI port is not present then port 80 will be
+     *                   used. The URI query and fragment components are ignored. Only first path segment will be used
+     *                   as context path, the rest will be ignored.
+     * @param c          the servlet class.
+     * @param initParams the servlet initialization parameters.
+     * @return the http server, with the endpoint started.
+     * @throws Exception                if an error occurs creating the container.
+     * @throws IllegalArgumentException if HTTP server URI is {@code null}.
+     */
+    public static Server create(URI u, Class<? extends Servlet> c, Map<String, String> initParams)
+            throws Exception {
+        return create(u, c, null, initParams, null);
+    }
+
+    private static Server create(URI u, Class<? extends Servlet> c, Servlet servlet,
+                                 Map<String, String> initParams, Map<String, String> contextInitParams)
+            throws Exception {
+        if (u == null) {
+            throw new IllegalArgumentException("The URI must not be null");
+        }
+
+        String path = u.getPath();
+        if (path == null) {
+            throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be non-null");
+        } else if (path.isEmpty()) {
+            throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be present");
+        } else if (path.charAt(0) != '/') {
+            throw new IllegalArgumentException("The URI path, of the URI " + u + ". must start with a '/'");
+        }
+
+        path = String.format("/%s", UriComponent.decodePath(u.getPath(), true).get(1).toString());
+        WebAppContext context = new WebAppContext();
+        context.setDisplayName("JettyContext");
+        context.setContextPath(path);
+        context.setConfigurations(new Configuration[]{new WebXmlConfiguration()});
+        ServletHolder holder;
+        if (c != null) {
+            holder = context.addServlet(c, "/*");
+        } else {
+            holder = new ServletHolder(servlet);
+            context.addServlet(holder, "/*");
+        }
+
+        if (contextInitParams != null) {
+            for (Map.Entry<String, String> e : contextInitParams.entrySet()) {
+                context.setInitParameter(e.getKey(), e.getValue());
+            }
+        }
+
+        if (initParams != null) {
+            holder.setInitParameters(initParams);
+        }
+
+        Server server = JettyHttpContainerFactory.createServer(u, false);
+        server.setHandler(context);
+        server.start();
+        return server;
+    }
+
+    /**
+     * Create a {@link Server} that registers the declared
+     * servlet instance.
+     *
+     * @param u                 the URI to create the HTTP server. The URI scheme must be
+     *                          equal to "http". The URI user information and host
+     *                          are ignored If the URI port is not present then port 80 will be
+     *                          used. The URI query and fragment components are ignored. Only first path segment will be used
+     *                          as context path, the rest will be ignored.
+     * @param servlet           the servlet instance.
+     * @param initParams        the servlet initialization parameters.
+     * @param contextInitParams the servlet context initialization parameters.
+     * @return the http server, with the endpoint started.
+     * @throws Exception                if an error occurs creating the container.
+     * @throws IllegalArgumentException if HTTP server URI is {@code null}.
+     */
+    public static Server create(URI u, Servlet servlet, Map<String, String> initParams, Map<String, String> contextInitParams)
+            throws Exception {
+        if (servlet == null) {
+            throw new IllegalArgumentException("The servlet must not be null");
+        }
+        return create(u, null, servlet, initParams, contextInitParams);
+    }
+}
\ No newline at end of file
diff --git a/containers/jetty-servlet/src/main/java8/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java b/containers/jetty-servlet/src/main/java8/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
deleted file mode 100644
index 3d87ae8..0000000
--- a/containers/jetty-servlet/src/main/java8/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.jetty.servlet;
-
-import java.net.URI;
-import java.util.Map;
-
-import jakarta.servlet.Servlet;
-
-import jakarta.ws.rs.ProcessingException;
-import org.eclipse.jetty.server.Server;
-import org.glassfish.jersey.jetty.internal.LocalizationMessages;
-
-/**
- * Jersey {@code Server} stub based on Jetty {@link org.eclipse.jetty.server.Server}.
- * <p>
- * For JDK 1.8 only since Jetty 11 does not support JDKs below 11
- */
-public final class JettyWebContainerFactory {
-
-    private JettyWebContainerFactory() {
-    }
-
-
-    public static Server create(String u)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    public static Server create(String u, Map<String, String> initParams)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    public static Server create(URI u)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    public static Server create(URI u, Map<String, String> initParams)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    public static Server create(String u, Class<? extends Servlet> c)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    public static Server create(String u, Class<? extends Servlet> c,
-                                Map<String, String> initParams)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    public static Server create(URI u, Class<? extends Servlet> c)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    public static Server create(URI u, Class<? extends Servlet> c, Map<String, String> initParams)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    private static Server create(URI u, Class<? extends Servlet> c, Servlet servlet,
-                                 Map<String, String> initParams, Map<String, String> contextInitParams)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-
-    public static Server create(URI u, Servlet servlet, Map<String, String> initParams, Map<String, String> contextInitParams)
-            throws Exception {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-}
\ No newline at end of file
diff --git a/containers/jetty-servlet/src/main/resources/org/glassfish/jersey/jetty/servlet/internal/localization.properties b/containers/jetty-servlet/src/main/resources/org/glassfish/jersey/jetty/servlet/internal/localization.properties
index c362bf0..6504f0e 100644
--- a/containers/jetty-servlet/src/main/resources/org/glassfish/jersey/jetty/servlet/internal/localization.properties
+++ b/containers/jetty-servlet/src/main/resources/org/glassfish/jersey/jetty/servlet/internal/localization.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2020, 2023 Oracle and/or its affiliates. All rights reserved.
 #
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,4 +15,4 @@
 #
 
 # {0} - status code; {1} - status reason message
-not.supported=Jetty container is not supported on JDK version less than 11.
+not.supported=Jetty container is not supported on JDK version less than 17.
diff --git a/containers/jetty11-http/pom.xml b/containers/jetty11-http/pom.xml
new file mode 100644
index 0000000..c9f3bcf
--- /dev/null
+++ b/containers/jetty11-http/pom.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>project</artifactId>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <version>3.1.99-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>jersey-container-jetty11-http</artifactId>
+    <packaging>jar</packaging>
+    <name>jersey-container-jetty11-http</name>
+
+    <description>Jetty 11 Http Container</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>jakarta.inject</groupId>
+            <artifactId>jakarta.inject-api</artifactId>
+        </dependency>
+         <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${jetty11.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.eclipse.jetty.toolchain</groupId>
+                    <artifactId>jetty-jakarta-servlet-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>jetty-util</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>${slf4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>${jetty11.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.sun.istack</groupId>
+                <artifactId>istack-commons-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <inherited>true</inherited>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            ${jetty.osgi.version},
+                            *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+
+        <resources>
+            <resource>
+                <directory>${basedir}/src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
+
+</project>
diff --git a/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpContainer.java b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpContainer.java
new file mode 100644
index 0000000..6bddebc
--- /dev/null
+++ b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpContainer.java
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import jakarta.servlet.AsyncContext;
+import jakarta.servlet.AsyncEvent;
+import jakarta.servlet.AsyncListener;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.SecurityContext;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Provider;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+import org.glassfish.jersey.internal.MapPropertiesDelegate;
+import org.glassfish.jersey.internal.inject.AbstractBinder;
+import org.glassfish.jersey.internal.inject.ReferencingFactory;
+import org.glassfish.jersey.internal.util.ExtendedLogger;
+import org.glassfish.jersey.internal.util.collection.Ref;
+import org.glassfish.jersey.jetty11.internal.LocalizationMessages;
+import org.glassfish.jersey.process.internal.RequestScoped;
+import org.glassfish.jersey.server.ApplicationHandler;
+import org.glassfish.jersey.server.ContainerException;
+import org.glassfish.jersey.server.ContainerRequest;
+import org.glassfish.jersey.server.ContainerResponse;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.internal.ContainerUtils;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.ContainerResponseWriter;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Response;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+
+/**
+ * Jersey {@code Container} implementation based on Jetty {@link org.eclipse.jetty.server.Handler}.
+ *
+ * @author Arul Dhesiaseelan (aruld@acm.org)
+ * @author Libor Kramolis
+ * @author Marek Potociar
+ */
+public final class Jetty11HttpContainer extends AbstractHandler implements Container {
+
+    private static final ExtendedLogger LOGGER =
+            new ExtendedLogger(Logger.getLogger(Jetty11HttpContainer.class.getName()), Level.FINEST);
+
+    private static final Type REQUEST_TYPE = (new GenericType<Ref<Request>>() {}).getType();
+    private static final Type RESPONSE_TYPE = (new GenericType<Ref<Response>>() {}).getType();
+
+    private static final int INTERNAL_SERVER_ERROR = jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
+    private static final jakarta.ws.rs.core.Response.Status BAD_REQUEST_STATUS = jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
+
+    /**
+     * Cached value of configuration property
+     * {@link org.glassfish.jersey.server.ServerProperties#RESPONSE_SET_STATUS_OVER_SEND_ERROR}.
+     * If {@code true} method {@link HttpServletResponse#setStatus} is used over {@link HttpServletResponse#sendError}.
+     */
+    private boolean configSetStatusOverSendError;
+
+    /**
+     * Referencing factory for Jetty request.
+     */
+    private static class JettyRequestReferencingFactory extends ReferencingFactory<Request> {
+        @Inject
+        public JettyRequestReferencingFactory(final Provider<Ref<Request>> referenceFactory) {
+            super(referenceFactory);
+        }
+    }
+
+    /**
+     * Referencing factory for Jetty response.
+     */
+    private static class JettyResponseReferencingFactory extends ReferencingFactory<Response> {
+        @Inject
+        public JettyResponseReferencingFactory(final Provider<Ref<Response>> referenceFactory) {
+            super(referenceFactory);
+        }
+    }
+
+    /**
+     * An internal binder to enable Jetty HTTP container specific types injection.
+     * This binder allows to inject underlying Jetty HTTP request and response instances.
+     * Note that since Jetty {@code Request} class is not proxiable as it does not expose an empty constructor,
+     * the injection of Jetty request instance into singleton JAX-RS and Jersey providers is only supported via
+     * {@link jakarta.inject.Provider injection provider}.
+     */
+    private static class JettyBinder extends AbstractBinder {
+
+        @Override
+        protected void configure() {
+            bindFactory(JettyRequestReferencingFactory.class).to(Request.class)
+                    .proxy(false).in(RequestScoped.class);
+            bindFactory(ReferencingFactory.<Request>referenceFactory()).to(new GenericType<Ref<Request>>() {})
+                    .in(RequestScoped.class);
+
+            bindFactory(JettyResponseReferencingFactory.class).to(Response.class)
+                    .proxy(false).in(RequestScoped.class);
+            bindFactory(ReferencingFactory.<Response>referenceFactory()).to(new GenericType<Ref<Response>>() {})
+                    .in(RequestScoped.class);
+        }
+    }
+
+    private volatile ApplicationHandler appHandler;
+
+    @Override
+    public void handle(final String target, final Request request, final HttpServletRequest httpServletRequest,
+                       final HttpServletResponse httpServletResponse) throws IOException, ServletException {
+
+        if (request.isHandled()) {
+            return;
+        }
+
+        final Response response = request.getResponse();
+        final ResponseWriter responseWriter = new ResponseWriter(request, response, configSetStatusOverSendError);
+        try {
+            final URI baseUri = getBaseUri(request);
+            final URI requestUri = getRequestUri(request, baseUri);
+            final ContainerRequest requestContext = new ContainerRequest(
+                    baseUri,
+                    requestUri,
+                    request.getMethod(),
+                    getSecurityContext(request),
+                    new MapPropertiesDelegate(),
+                    appHandler.getConfiguration());
+            requestContext.setEntityStream(request.getInputStream());
+            final Enumeration<String> headerNames = request.getHeaderNames();
+            while (headerNames.hasMoreElements()) {
+                final String headerName = headerNames.nextElement();
+                String headerValue = request.getHeader(headerName);
+                requestContext.headers(headerName, headerValue == null ? "" : headerValue);
+            }
+            requestContext.setWriter(responseWriter);
+            requestContext.setRequestScopedInitializer(injectionManager -> {
+                injectionManager.<Ref<Request>>getInstance(REQUEST_TYPE).set(request);
+                injectionManager.<Ref<Response>>getInstance(RESPONSE_TYPE).set(response);
+            });
+
+            // Mark the request as handled before generating the body of the response
+            request.setHandled(true);
+            appHandler.handle(requestContext);
+        } catch (URISyntaxException e) {
+            setResponseForInvalidUri(response, e);
+        } catch (final Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private URI getRequestUri(final Request request, final URI baseUri) throws URISyntaxException {
+        final String serverAddress = getServerAddress(baseUri);
+        String uri = request.getRequestURI();
+
+        final String queryString = request.getQueryString();
+        if (queryString != null) {
+            uri = uri + "?" + ContainerUtils.encodeUnsafeCharacters(queryString);
+        }
+
+        return new URI(serverAddress + uri);
+    }
+
+    private void setResponseForInvalidUri(final HttpServletResponse response, final Throwable throwable) throws IOException {
+        LOGGER.log(Level.FINER, "Error while processing request.", throwable);
+
+        if (configSetStatusOverSendError) {
+            response.reset();
+            //noinspection deprecation
+            response.setStatus(BAD_REQUEST_STATUS.getStatusCode());
+        } else {
+            response.sendError(BAD_REQUEST_STATUS.getStatusCode(), BAD_REQUEST_STATUS.getReasonPhrase());
+        }
+    }
+
+    private String getServerAddress(URI baseUri) {
+        String serverAddress = baseUri.toString();
+        if (serverAddress.charAt(serverAddress.length() - 1) == '/') {
+            return serverAddress.substring(0, serverAddress.length() - 1);
+        }
+        return serverAddress;
+    }
+
+    private SecurityContext getSecurityContext(final Request request) {
+        return new SecurityContext() {
+
+            @Override
+            public boolean isUserInRole(final String role) {
+                return request.isUserInRole(role);
+            }
+
+            @Override
+            public boolean isSecure() {
+                return request.isSecure();
+            }
+
+            @Override
+            public Principal getUserPrincipal() {
+                return request.getUserPrincipal();
+            }
+
+            @Override
+            public String getAuthenticationScheme() {
+                return request.getAuthType();
+            }
+        };
+    }
+
+
+    private URI getBaseUri(final Request request) throws URISyntaxException {
+        return new URI(request.getScheme(), null, request.getServerName(),
+                request.getServerPort(), getBasePath(request), null, null);
+    }
+
+    private String getBasePath(final Request request) {
+        final String contextPath = request.getContextPath();
+
+        if (contextPath == null || contextPath.isEmpty()) {
+            return "/";
+        } else if (contextPath.charAt(contextPath.length() - 1) != '/') {
+            return contextPath + "/";
+        } else {
+            return contextPath;
+        }
+    }
+
+    private static final class ResponseWriter implements ContainerResponseWriter {
+
+        private final Response response;
+        private final AsyncContext context;
+        private final boolean configSetStatusOverSendError;
+
+        ResponseWriter(final Request request, final Response response, final boolean configSetStatusOverSendError) {
+            this.response = response;
+            this.context = request.startAsync();
+            this.configSetStatusOverSendError = configSetStatusOverSendError;
+        }
+
+        @Override
+        public OutputStream writeResponseStatusAndHeaders(final long contentLength, final ContainerResponse context)
+                throws ContainerException {
+
+            final jakarta.ws.rs.core.Response.StatusType statusInfo = context.getStatusInfo();
+
+            final int code = statusInfo.getStatusCode();
+            final String reason = statusInfo.getReasonPhrase() == null
+                    ? HttpStatus.getMessage(code) : statusInfo.getReasonPhrase();
+
+            response.setStatusWithReason(code, reason);
+
+            if (contentLength != -1 && contentLength < Integer.MAX_VALUE) {
+                response.setContentLength((int) contentLength);
+            }
+            for (final Map.Entry<String, List<String>> e : context.getStringHeaders().entrySet()) {
+                for (final String value : e.getValue()) {
+                    response.addHeader(e.getKey(), value);
+                }
+            }
+
+            try {
+                return response.getOutputStream();
+            } catch (final IOException ioe) {
+                throw new ContainerException("Error during writing out the response headers.", ioe);
+            }
+        }
+
+        @Override
+        public boolean suspend(final long timeOut, final TimeUnit timeUnit, final TimeoutHandler timeoutHandler) {
+            try {
+                if (timeOut > 0) {
+                    final long timeoutMillis = TimeUnit.MILLISECONDS.convert(timeOut, timeUnit);
+                    context.setTimeout(timeoutMillis);
+                }
+                context.addListener(new AsyncListener() {
+                    @Override
+                    public void onComplete(AsyncEvent asyncEvent) throws IOException {
+
+                    }
+
+                    @Override
+                    public void onTimeout(AsyncEvent asyncEvent) throws IOException {
+                        if (timeoutHandler != null) {
+                            timeoutHandler.onTimeout(ResponseWriter.this);
+                        }
+                    }
+
+                    @Override
+                    public void onError(AsyncEvent asyncEvent) throws IOException {
+
+                    }
+
+                    @Override
+                    public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
+
+                    }
+                });
+                return true;
+            } catch (final Exception ex) {
+                return false;
+            }
+        }
+
+        @Override
+        public void setSuspendTimeout(final long timeOut, final TimeUnit timeUnit) throws IllegalStateException {
+            if (timeOut > 0) {
+                final long timeoutMillis = TimeUnit.MILLISECONDS.convert(timeOut, timeUnit);
+                context.setTimeout(timeoutMillis);
+            }
+        }
+
+        @Override
+        public void commit() {
+            try {
+                closeOutput(response);
+            } catch (final IOException e) {
+                LOGGER.log(Level.WARNING, LocalizationMessages.UNABLE_TO_CLOSE_RESPONSE(), e);
+            } finally {
+                if (context.getRequest().isAsyncStarted()) {
+                    context.complete();
+                }
+                LOGGER.log(Level.FINEST, "commit() called");
+            }
+        }
+
+        private void closeOutput(Response response) throws IOException {
+            try {
+                response.completeOutput();
+            } catch (final IOException e) {
+                throw e;
+            } catch (NoSuchMethodError e) {
+                // try older Jetty Response#closeOutput
+                try {
+                    Method method = response.getClass().getMethod("closeOutput");
+                    method.invoke(response);
+                } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
+                    throw new IOException(ex);
+                }
+            }
+        }
+
+        @Override
+        public void failure(final Throwable error) {
+            try {
+                if (!response.isCommitted()) {
+                    try {
+                        if (configSetStatusOverSendError) {
+                            response.reset();
+                            //noinspection deprecation
+                            response.setStatus(INTERNAL_SERVER_ERROR, "Request failed.");
+                        } else {
+                            response.sendError(INTERNAL_SERVER_ERROR, "Request failed.");
+                        }
+                    } catch (final IllegalStateException ex) {
+                        // a race condition externally committing the response can still occur...
+                        LOGGER.log(Level.FINER, "Unable to reset failed response.", ex);
+                    } catch (final IOException ex) {
+                        throw new ContainerException(LocalizationMessages.EXCEPTION_SENDING_ERROR_RESPONSE(INTERNAL_SERVER_ERROR,
+                                "Request failed."), ex);
+                    }
+                }
+            } finally {
+                LOGGER.log(Level.FINEST, "failure(...) called");
+                commit();
+                rethrow(error);
+            }
+        }
+
+        @Override
+        public boolean enableResponseBuffering() {
+            return false;
+        }
+
+        /**
+         * Rethrow the original exception as required by JAX-RS, 3.3.4.
+         *
+         * @param error throwable to be re-thrown
+         */
+        private void rethrow(final Throwable error) {
+            if (error instanceof RuntimeException) {
+                throw (RuntimeException) error;
+            } else {
+                throw new ContainerException(error);
+            }
+        }
+
+    }
+
+    @Override
+    public ResourceConfig getConfiguration() {
+        return appHandler.getConfiguration();
+    }
+
+    @Override
+    public void reload() {
+        reload(new ResourceConfig(getConfiguration()));
+    }
+
+    @Override
+    public void reload(final ResourceConfig configuration) {
+        appHandler.onShutdown(this);
+
+        appHandler = new ApplicationHandler(configuration.register(new JettyBinder()));
+        appHandler.onReload(this);
+        appHandler.onStartup(this);
+        cacheConfigSetStatusOverSendError();
+    }
+
+    @Override
+    public ApplicationHandler getApplicationHandler() {
+        return appHandler;
+    }
+
+    /**
+     * Inform this container that the server has been started.
+     * This method must be implicitly called after the server containing this container is started.
+     *
+     * @throws java.lang.Exception if a problem occurred during server startup.
+     */
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        appHandler.onStartup(this);
+    }
+
+    /**
+     * Inform this container that the server is being stopped.
+     * This method must be implicitly called before the server containing this container is stopped.
+     *
+     * @throws java.lang.Exception if a problem occurred during server shutdown.
+     */
+    @Override
+    public void doStop() throws Exception {
+        super.doStop();
+        appHandler.onShutdown(this);
+        appHandler = null;
+    }
+
+    /**
+     * Create a new Jetty HTTP container.
+     *
+     * @param application   JAX-RS / Jersey application to be deployed on Jetty HTTP container.
+     * @param parentContext DI provider specific context with application's registered bindings.
+     */
+    Jetty11HttpContainer(final Application application, final Object parentContext) {
+        this.appHandler = new ApplicationHandler(application, new JettyBinder(), parentContext);
+    }
+
+    /**
+     * Create a new Jetty HTTP container.
+     *
+     * @param application JAX-RS / Jersey application to be deployed on Jetty HTTP container.
+     */
+    Jetty11HttpContainer(final Application application) {
+        this.appHandler = new ApplicationHandler(application, new JettyBinder());
+
+        cacheConfigSetStatusOverSendError();
+    }
+
+    /**
+     * Create a new Jetty HTTP container.
+     *
+     * @param applicationClass JAX-RS / Jersey class of application to be deployed on Jetty HTTP container.
+     */
+    Jetty11HttpContainer(final Class<? extends Application> applicationClass) {
+        this.appHandler = new ApplicationHandler(applicationClass, new JettyBinder());
+
+        cacheConfigSetStatusOverSendError();
+    }
+
+    /**
+     * The method reads and caches value of configuration property
+     * {@link ServerProperties#RESPONSE_SET_STATUS_OVER_SEND_ERROR} for future purposes.
+     */
+    private void cacheConfigSetStatusOverSendError() {
+        this.configSetStatusOverSendError = ServerProperties.getValue(getConfiguration().getProperties(),
+                ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, false, Boolean.class);
+    }
+
+}
diff --git a/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpContainerFactory.java b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpContainerFactory.java
new file mode 100644
index 0000000..4eb813a
--- /dev/null
+++ b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpContainerFactory.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11;
+
+import java.net.URI;
+import java.util.concurrent.ThreadFactory;
+
+import jakarta.ws.rs.ProcessingException;
+
+import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
+import org.glassfish.jersey.jetty11.internal.LocalizationMessages;
+import org.glassfish.jersey.process.JerseyProcessingUncaughtExceptionHandler;
+import org.glassfish.jersey.server.ContainerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.spi.Container;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+
+/**
+ * Factory for creating and starting Jetty server handlers. This returns
+ * a handle to the started server as {@link Server} instances, which allows
+ * the server to be stopped by invoking the {@link org.eclipse.jetty.server.Server#stop()} method.
+ * <p/>
+ * To start the server in HTTPS mode an {@link SslContextFactory} can be provided.
+ * This will be used to decrypt and encrypt information sent over the
+ * connected TCP socket channel.
+ *
+ * @author Arul Dhesiaseelan (aruld@acm.org)
+ * @author Marek Potociar
+ */
+public final class Jetty11HttpContainerFactory {
+
+    private Jetty11HttpContainerFactory() {
+    }
+
+    /**
+     * Creates a {@link Server} instance that registers an {@link org.eclipse.jetty.server.Handler}.
+     *
+     * @param uri uri on which the {@link org.glassfish.jersey.server.ApplicationHandler} will be deployed. Only first path
+     *            segment will be used as context path, the rest will be ignored.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri) throws ProcessingException {
+        return createServer(uri, null, null, true);
+    }
+
+    /**
+     * Creates a {@link Server} instance that registers an {@link org.eclipse.jetty.server.Handler}.
+     *
+     * @param uri   uri on which the {@link org.glassfish.jersey.server.ApplicationHandler} will be deployed. Only first path
+     *              segment will be used as context path, the rest will be ignored.
+     * @param start if set to false, server will not get started, which allows to configure the underlying transport
+     *              layer, see above for details.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri, final boolean start) throws ProcessingException {
+        return createServer(uri, null, null, start);
+    }
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     * <p/>
+     * This implementation defers to the
+     * {@link org.glassfish.jersey.server.ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+     * for creating an Container that manages the root resources.
+     *
+     * @param uri    the URI to create the http server. The URI scheme must be
+     *               equal to "http". The URI user information and host
+     *               are ignored If the URI port is not present then port 80 will be
+     *               used. The URI path, query and fragment components are ignored.
+     * @param config the resource configuration.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri, final ResourceConfig config)
+            throws ProcessingException {
+
+        final Jetty11HttpContainer container = ContainerFactory.createContainer(Jetty11HttpContainer.class, config);
+        return createServer(uri, null, container, true);
+    }
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     * <p/>
+     * This implementation defers to the
+     * {@link org.glassfish.jersey.server.ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+     * for creating an Container that manages the root resources.
+     *
+     * @param uri           URI on which the Jersey web application will be deployed. Only first path segment will be
+     *                      used as context path, the rest will be ignored.
+     * @param configuration web application configuration.
+     * @param start         if set to false, server will not get started, which allows to configure the underlying
+     *                      transport layer, see above for details.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri, final ResourceConfig configuration, final boolean start)
+            throws ProcessingException {
+        return createServer(uri, null, ContainerFactory.createContainer(Jetty11HttpContainer.class, configuration), start);
+    }
+
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     *
+     * @param uri           the URI to create the http server. The URI scheme must be
+     *                      equal to "https". The URI user information and host
+     *                      are ignored If the URI port is not present then port 143 will be
+     *                      used. The URI path, query and fragment components are ignored.
+     * @param config        the resource configuration.
+     * @param parentContext DI provider specific context with application's registered bindings.
+     * @param start         if set to false, server will not get started, this allows end users to set
+     *                      additional properties on the underlying listener.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     * @see Jetty11HttpContainer
+     * @since 2.12
+     */
+    public static Server createServer(final URI uri, final ResourceConfig config, final boolean start,
+                                      final Object parentContext) {
+        return createServer(uri, null, new Jetty11HttpContainer(config, parentContext), start);
+    }
+
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     *
+     * @param uri           the URI to create the http server. The URI scheme must be
+     *                      equal to "https". The URI user information and host
+     *                      are ignored If the URI port is not present then port 143 will be
+     *                      used. The URI path, query and fragment components are ignored.
+     * @param config        the resource configuration.
+     * @param parentContext DI provider specific context with application's registered bindings.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     * @see Jetty11HttpContainer
+     * @since 2.12
+     */
+    public static Server createServer(final URI uri, final ResourceConfig config, final Object parentContext) {
+        return createServer(uri, null, new Jetty11HttpContainer(config, parentContext), true);
+    }
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes declared by the
+     * resource configuration.
+     * <p/>
+     * This implementation defers to the
+     * {@link ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+     * for creating an Container that manages the root resources.
+     *
+     * @param uri               the URI to create the http server. The URI scheme must be
+     *                          equal to {@code https}. The URI user information and host
+     *                          are ignored. If the URI port is not present then port
+     *                          {@value org.glassfish.jersey.server.spi.Container#DEFAULT_HTTPS_PORT} will be
+     *                          used. The URI path, query and fragment components are ignored.
+     * @param sslContextFactory this is the SSL context factory used to configure SSL connector
+     * @param config            the resource configuration.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     */
+    public static Server createServer(final URI uri, final SslContextFactory.Server sslContextFactory,
+                                      final ResourceConfig config)
+            throws ProcessingException {
+        final Jetty11HttpContainer container = ContainerFactory.createContainer(Jetty11HttpContainer.class, config);
+        return createServer(uri, sslContextFactory, container, true);
+    }
+
+    /**
+     * Create a {@link Server} that registers an {@link org.eclipse.jetty.server.Handler} that
+     * in turn manages all root resource and provider classes found by searching the
+     * classes referenced in the java classpath.
+     *
+     * @param uri               the URI to create the http server. The URI scheme must be
+     *                          equal to {@code https}. The URI user information and host
+     *                          are ignored. If the URI port is not present then port
+     *                          {@value org.glassfish.jersey.server.spi.Container#DEFAULT_HTTPS_PORT} will be
+     *                          used. The URI path, query and fragment components are ignored.
+     * @param sslContextFactory this is the SSL context factory used to configure SSL connector
+     * @param handler           the container that handles all HTTP requests
+     * @param start             if set to false, server will not get started, this allows end users to set
+     *                          additional properties on the underlying listener.
+     * @return newly created {@link Server}.
+     *
+     * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
+     * @throws IllegalArgumentException if {@code uri} is {@code null}.
+     * @see Jetty11HttpContainer
+     */
+    public static Server createServer(final URI uri,
+                                      final SslContextFactory.Server sslContextFactory,
+                                      final Jetty11HttpContainer handler,
+                                      final boolean start) {
+        if (uri == null) {
+            throw new IllegalArgumentException(LocalizationMessages.URI_CANNOT_BE_NULL());
+        }
+        final String scheme = uri.getScheme();
+        int defaultPort = Container.DEFAULT_HTTP_PORT;
+
+        if (sslContextFactory == null) {
+            if (!"http".equalsIgnoreCase(scheme)) {
+                throw new IllegalArgumentException(LocalizationMessages.WRONG_SCHEME_WHEN_USING_HTTP());
+            }
+        } else {
+            if (!"https".equalsIgnoreCase(scheme)) {
+                throw new IllegalArgumentException(LocalizationMessages.WRONG_SCHEME_WHEN_USING_HTTPS());
+            }
+            defaultPort = Container.DEFAULT_HTTPS_PORT;
+        }
+        final int port = (uri.getPort() == -1) ? defaultPort : uri.getPort();
+
+        final Server server = new Server(new JettyConnectorThreadPool());
+        final HttpConfiguration config = new HttpConfiguration();
+        if (sslContextFactory != null) {
+            config.setSecureScheme("https");
+            config.setSecurePort(port);
+            config.addCustomizer(new SecureRequestCustomizer());
+
+            final ServerConnector https = new ServerConnector(server,
+                    new SslConnectionFactory(sslContextFactory, "http/1.1"),
+                    new HttpConnectionFactory(config));
+            https.setPort(port);
+            server.setConnectors(new Connector[]{https});
+
+        } else {
+            final ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(config));
+            http.setPort(port);
+            server.setConnectors(new Connector[]{http});
+        }
+        if (handler != null) {
+            server.setHandler(handler);
+        }
+
+        if (start) {
+            try {
+                // Start the server.
+                server.start();
+            } catch (final Exception e) {
+                throw new ProcessingException(LocalizationMessages.ERROR_WHEN_CREATING_SERVER(), e);
+            }
+        }
+        return server;
+    }
+
+    // TODO: Use https://www.eclipse.org/jetty/javadoc/current/org/eclipse/jetty/util/thread/QueuedThreadPool.html
+    //  #%3Cinit%3E(int,int,int,int,java.util.concurrent.BlockingQueue,java.lang.ThreadGroup,java.util.concurrent.ThreadFactory)
+    //
+    //  Keeping this for backwards compatibility for the time being
+    private static final class JettyConnectorThreadPool extends QueuedThreadPool {
+        private final ThreadFactory threadFactory = new ThreadFactoryBuilder()
+                .setNameFormat("jetty-http-server-%d")
+                .setUncaughtExceptionHandler(new JerseyProcessingUncaughtExceptionHandler())
+                .build();
+
+        @Override
+        public Thread newThread(Runnable runnable) {
+            return threadFactory.newThread(runnable);
+        }
+    }
+}
diff --git a/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpContainerProvider.java b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpContainerProvider.java
new file mode 100644
index 0000000..e741ab3
--- /dev/null
+++ b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpContainerProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.internal.util.JdkVersion;
+import org.glassfish.jersey.jetty11.internal.LocalizationMessages;
+import org.glassfish.jersey.server.spi.ContainerProvider;
+
+/**
+ * Container provider for containers based on Jetty Server {@link org.eclipse.jetty.server.Handler}.
+ *
+ * @author Arul Dhesiaseelan (aruld@acm.org)
+ * @author Marek Potociar
+ */
+public final class Jetty11HttpContainerProvider implements ContainerProvider {
+
+    public static final String HANDLER_NAME = "org.eclipse.jetty.server.Handler";
+    @Override
+    public <T> T createContainer(final Class<T> type, final Application application) throws ProcessingException {
+        if (JdkVersion.getJdkVersion().getMajor() < 11) {
+            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+        }
+        if (type != null && (HANDLER_NAME.equalsIgnoreCase(type.getCanonicalName()) || Jetty11HttpContainer.class == type)) {
+            return type.cast(new Jetty11HttpContainer(application));
+        }
+        return null;
+    }
+
+    public <T> T createContainer(final Class<T> type, final Application application,
+                                 Object parentContext) throws ProcessingException {
+        if (JdkVersion.getJdkVersion().getMajor() < 11) {
+            throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+        }
+        if (type != null && (HANDLER_NAME.equalsIgnoreCase(type.getCanonicalName()) || Jetty11HttpContainer.class == type)) {
+            return type.cast(new Jetty11HttpContainer(application, parentContext));
+        }
+        return null;
+    }
+
+}
diff --git a/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpServer.java b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpServer.java
new file mode 100644
index 0000000..617776e
--- /dev/null
+++ b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpServer.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11;
+
+import static jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication.MANDATORY;
+import static jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication.OPTIONAL;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.glassfish.jersey.server.ContainerFactory;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+
+/**
+ * Jersey {@code Server} implementation based on Jetty
+ * {@link org.eclipse.jetty.server.Server Server}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+final class Jetty11HttpServer implements WebServer {
+
+    private final Jetty11HttpContainer container;
+
+    private final org.eclipse.jetty.server.Server httpServer;
+
+    Jetty11HttpServer(final Application application, final JerseySeBootstrapConfiguration configuration) {
+        this(ContainerFactory.createContainer(Jetty11HttpContainer.class, application), configuration);
+    }
+
+    Jetty11HttpServer(final Class<? extends Application> applicationClass,
+                      final JerseySeBootstrapConfiguration configuration) {
+        this(new Jetty11HttpContainer(applicationClass), configuration);
+    }
+
+    Jetty11HttpServer(final Jetty11HttpContainer container, final JerseySeBootstrapConfiguration configuration) {
+        final SeBootstrap.Configuration.SSLClientAuthentication sslClientAuthentication = configuration
+                .sslClientAuthentication();
+        final SslContextFactory.Server sslContextFactory;
+        if (configuration.isHttps()) {
+            sslContextFactory = new SslContextFactory.Server();
+            sslContextFactory.setSslContext(configuration.sslContext());
+            sslContextFactory.setWantClientAuth(sslClientAuthentication == OPTIONAL);
+            sslContextFactory.setNeedClientAuth(sslClientAuthentication == MANDATORY);
+        } else {
+            sslContextFactory = null;
+        }
+        this.container = container;
+        this.httpServer = Jetty11HttpContainerFactory.createServer(
+                configuration.uri(true),
+                sslContextFactory,
+                this.container,
+                configuration.autoStart());
+    }
+
+    @Override
+    public final Jetty11HttpContainer container() {
+        return this.container;
+    }
+
+    @Override
+    public final int port() {
+        final ServerConnector serverConnector = (ServerConnector) this.httpServer.getConnectors()[0];
+        final int configuredPort = serverConnector.getPort();
+        final int localPort = serverConnector.getLocalPort();
+        return localPort < 0 ? configuredPort : localPort;
+    }
+
+    @Override
+    public final CompletableFuture<Void> start() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                this.httpServer.start();
+            } catch (final Exception e) {
+                throw new CompletionException(e);
+            }
+        });
+    }
+
+    @Override
+    public final CompletableFuture<Void> stop() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                this.httpServer.stop();
+            } catch (final Exception e) {
+                throw new CompletionException(e);
+            }
+        });
+    }
+
+    @Override
+    public final <T> T unwrap(final Class<T> nativeClass) {
+        return nativeClass.cast(this.httpServer);
+    }
+
+}
diff --git a/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpServerProvider.java b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpServerProvider.java
new file mode 100644
index 0000000..533e1ca
--- /dev/null
+++ b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/Jetty11HttpServerProvider.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+
+/**
+ * Server provider for servers based on Jetty
+ * {@link org.eclipse.jetty.server.Server Server}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class Jetty11HttpServerProvider implements WebServerProvider {
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Application application,
+                                                      final SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(Jetty11HttpServer.class, type, configuration)
+                ? type.cast(new Jetty11HttpServer(application, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Class<? extends Application> applicationClass,
+                                                final SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(Jetty11HttpServer.class, type, configuration)
+                ? type.cast(new Jetty11HttpServer(applicationClass, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+}
diff --git a/containers/jetty-http2/src/main/java/org/glassfish/jersey/jetty/http2/package-info.java b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/package-info.java
similarity index 80%
copy from containers/jetty-http2/src/main/java/org/glassfish/jersey/jetty/http2/package-info.java
copy to containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/package-info.java
index a402b27..b3d9f85 100644
--- a/containers/jetty-http2/src/main/java/org/glassfish/jersey/jetty/http2/package-info.java
+++ b/containers/jetty11-http/src/main/java/org/glassfish/jersey/jetty11/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,6 +15,6 @@
  */
 
 /**
- * Jersey Jetty HTTP2 container classes.
+ * Jersey Jetty container classes.
  */
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11;
diff --git a/containers/jetty11-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ContainerProvider b/containers/jetty11-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ContainerProvider
new file mode 100644
index 0000000..634f74f
--- /dev/null
+++ b/containers/jetty11-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ContainerProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.jetty11.Jetty11HttpContainerProvider
diff --git a/containers/jetty11-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider b/containers/jetty11-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
new file mode 100644
index 0000000..341f882
--- /dev/null
+++ b/containers/jetty11-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.jetty11.Jetty11HttpServerProvider
diff --git a/containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties b/containers/jetty11-http/src/main/resources/org/glassfish/jersey/jetty11/internal/localization.properties
similarity index 64%
copy from containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties
copy to containers/jetty11-http/src/main/resources/org/glassfish/jersey/jetty11/internal/localization.properties
index 9807184..6d0d06c 100644
--- a/containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties
+++ b/containers/jetty11-http/src/main/resources/org/glassfish/jersey/jetty11/internal/localization.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
 #
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,5 +15,10 @@
 #
 
 # {0} - status code; {1} - status reason message
+exception.sending.error.response=I/O exception occurred while sending "{0}/{1}" error response.
 error.when.creating.server=Exception thrown when trying to create jetty server.
-not.supported=Jetty container is not supported on JDK version less than 11.
\ No newline at end of file
+unable.to.close.response=Unable to close response output.
+uri.cannot.be.null=The URI must not be null.
+wrong.scheme.when.using.http=The URI scheme should be 'http' when not using SSL.
+wrong.scheme.when.using.https=The URI scheme should be 'https' when using SSL.
+not.supported=Jetty container is not supported on JDK version less than 11.
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AbstractJettyServerTester.java b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/AbstractJetty11ServerTester.java
similarity index 80%
copy from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AbstractJettyServerTester.java
copy to containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/AbstractJetty11ServerTester.java
index 6134d03..14b3b6c 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AbstractJettyServerTester.java
+++ b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/AbstractJetty11ServerTester.java
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +15,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11;
 
 import java.net.URI;
 import java.security.AccessController;
@@ -29,6 +30,7 @@
 import org.glassfish.jersey.server.ResourceConfig;
 
 import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
 import org.junit.jupiter.api.AfterEach;
 
 /**
@@ -38,9 +40,9 @@
  * @author Arul Dhesiaseelan (aruld at acm.org)
  * @author Miroslav Fuksa
  */
-public abstract class AbstractJettyServerTester {
+public abstract class AbstractJetty11ServerTester {
 
-    private static final Logger LOGGER = Logger.getLogger(AbstractJettyServerTester.class.getName());
+    private static final Logger LOGGER = Logger.getLogger(AbstractJetty11ServerTester.class.getName());
 
     public static final String CONTEXT = "";
     private static final int DEFAULT_PORT = 0; // rather Jetty choose than 9998
@@ -51,20 +53,24 @@
      * @return The HTTP port of the URI
      */
     protected final int getPort() {
+        if (server != null) {
+            return ((ServerConnector) server.getConnectors()[0]).getLocalPort();
+        }
+
         final String value = AccessController
                 .doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
         if (value != null) {
 
             try {
                 final int i = Integer.parseInt(value);
-                if (i <= 0) {
-                    throw new NumberFormatException("Value not positive.");
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
                 }
                 return i;
             } catch (NumberFormatException e) {
                 LOGGER.log(Level.CONFIG,
                         "Value of 'jersey.config.test.container.port'"
-                                + " property is not a valid positive integer [" + value + "]."
+                                + " property is not a valid non-negative integer [" + value + "]."
                                 + " Reverting to default [" + DEFAULT_PORT + "].",
                         e);
             }
@@ -89,18 +95,16 @@
         return UriBuilder.fromUri("http://localhost").port(getPort(RuntimeType.CLIENT)).path(CONTEXT);
     }
 
-    public void startServer(Class... resources) {
+    public void startServer(Class<?>... resources) {
         ResourceConfig config = new ResourceConfig(resources);
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
-        final URI baseUri = getBaseUri();
-        server = JettyHttp2ContainerFactory.createHttp2Server(baseUri, config, true);
-        LOGGER.log(Level.INFO, "Jetty-http server started on base uri: " + server.getURI());
+        startServer(config);
     }
 
     public void startServer(ResourceConfig config) {
         final URI baseUri = getBaseUri();
-        server = JettyHttp2ContainerFactory.createHttp2Server(baseUri, config, true);
-        LOGGER.log(Level.INFO, "Jetty-http server started on base uri: " + server.getURI());
+        server = Jetty11HttpContainerFactory.createServer(baseUri, config);
+        LOGGER.log(Level.INFO, "Jetty-http server started on base uri: " + getBaseUri());
     }
 
     public URI getBaseUri() {
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AsyncTest.java b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/AsyncTest.java
similarity index 96%
copy from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AsyncTest.java
copy to containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/AsyncTest.java
index ac1ebb5..a766150 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AsyncTest.java
+++ b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/AsyncTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11;
 
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -42,7 +42,7 @@
  * @author Arul Dhesiaseelan (aruld at acm.org)
  * @author Michal Gajdos
  */
-public class AsyncTest extends AbstractJettyServerTester {
+public class AsyncTest extends AbstractJetty11ServerTester {
 
     @Path("/async")
     @SuppressWarnings("VoidMethodAnnotatedWithGET")
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/ExceptionTest.java b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/ExceptionTest.java
similarity index 94%
copy from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/ExceptionTest.java
copy to containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/ExceptionTest.java
index 60e086b..4cf0abd 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/ExceptionTest.java
+++ b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/ExceptionTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11;
 
 import org.apache.http.HttpHost;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -40,7 +40,7 @@
 /**
  * @author Paul Sandoz
  */
-public class ExceptionTest extends AbstractJettyServerTester {
+public class ExceptionTest extends AbstractJetty11ServerTester {
     @Path("{status}")
     public static class ExceptionResource {
         @GET
diff --git a/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/Jetty11HttpServerProviderTest.java b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/Jetty11HttpServerProviderTest.java
new file mode 100644
index 0000000..7fd2e29
--- /dev/null
+++ b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/Jetty11HttpServerProviderTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11;
+
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+
+import java.security.AccessController;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLContext;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+/**
+ * Unit tests for {@link Jetty11HttpServerProvider}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class Jetty11HttpServerProviderTest {
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServer() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        shouldProvideServer(ShouldProvideServerApplication.class, resource);
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServerWithClass() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        final Application application = new ShouldProvideServerApplication();
+        shouldProvideServer(application.getClass(), resource);
+    }
+
+    private void shouldProvideServer(final Object application, final Resource resource)
+            throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new Jetty11HttpServerProvider();
+        final SeBootstrap.Configuration configuration = configuration(getPort(), FALSE);
+
+        // when
+        final WebServer webServer = Application.class.isInstance(application)
+                ? webServerProvider.createServer(WebServer.class, (Application) application, configuration)
+                : webServerProvider.createServer(WebServer.class, (Class<Application>) application, configuration);
+        final Object nativeHandle = webServer.unwrap(Object.class);
+        final CompletionStage<?> start = webServer.start();
+        final Object startResult = start.toCompletableFuture().get();
+        final Container container = webServer.container();
+        final int port = webServer.port();
+        final String entity = ClientBuilder.newClient()
+                .target(UriBuilder.newInstance().scheme("http").host("localhost").port(port).build()).request()
+                .get(String.class);
+        final CompletionStage<?> stop = webServer.stop();
+        final Object stopResult = stop.toCompletableFuture().get();
+
+        // then
+        assertThat(webServer, is(instanceOf(Jetty11HttpServer.class)));
+        assertThat(nativeHandle, is(instanceOf(org.eclipse.jetty.server.Server.class)));
+        assertThat(startResult, is(nullValue()));
+        assertThat(container, is(instanceOf(Jetty11HttpContainer.class)));
+        assertThat(port, is(greaterThan(0)));
+        assertThat(entity, is(resource.toString()));
+        assertThat(stopResult, is(nullValue()));
+    }
+
+    @Path("/")
+    protected static final class Resource {
+        @GET
+        @Override
+        public String toString() {
+            return Resource.class.getName();
+        }
+    }
+
+    protected static class ShouldProvideServerApplication extends Application {
+        @Override
+        public Set<Object> getSingletons() {
+            return Collections.singleton(new Resource());
+        }
+    }
+
+    private static final Logger LOGGER = Logger.getLogger(Jetty11HttpServerProviderTest.class.getName());
+
+    private static final int DEFAULT_PORT = 0;
+
+    private static final int getPort() {
+        final String value = AccessController
+                .doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
+        if (value != null) {
+            try {
+                final int i = Integer.parseInt(value);
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
+                }
+                return i;
+            } catch (final NumberFormatException e) {
+                LOGGER.log(Level.CONFIG,
+                        "Value of 'jersey.config.test.container.port'"
+                                + " property is not a valid non-negative integer [" + value + "]."
+                                + " Reverting to default [" + DEFAULT_PORT + "].",
+                        e);
+            }
+        }
+
+        return DEFAULT_PORT;
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public final void shouldScanFreePort() throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new Jetty11HttpServerProvider();
+        final Application application = new Application();
+        final SeBootstrap.Configuration configuration = configuration(SeBootstrap.Configuration.FREE_PORT, TRUE);
+
+        // when
+        final WebServer webServer = webServerProvider.createServer(WebServer.class, application, configuration);
+
+        // then
+        assertThat(webServer.port(), is(greaterThan(0)));
+    }
+
+    private SeBootstrap.Configuration configuration(int port, boolean autoStart) {
+        return (SeBootstrap.Configuration) name -> {
+            switch (name) {
+                case SeBootstrap.Configuration.PROTOCOL:
+                    return "HTTP";
+                case SeBootstrap.Configuration.HOST:
+                    return "localhost";
+                case SeBootstrap.Configuration.PORT:
+                    return port;
+                case SeBootstrap.Configuration.ROOT_PATH:
+                    return "/";
+                case SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION:
+                    return SSLClientAuthentication.NONE;
+                case SeBootstrap.Configuration.SSL_CONTEXT:
+                    try {
+                        return SSLContext.getDefault();
+                    } catch (final NoSuchAlgorithmException e) {
+                        throw new RuntimeException(e);
+                    }
+                case ServerProperties.WEBSERVER_AUTO_START:
+                    return autoStart;
+                default:
+                    return null;
+            }
+        };
+    }
+
+}
\ No newline at end of file
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/LifecycleListenerTest.java b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/LifecycleListenerTest.java
similarity index 94%
copy from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/LifecycleListenerTest.java
copy to containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/LifecycleListenerTest.java
index 93ae01f..6270306 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/LifecycleListenerTest.java
+++ b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/LifecycleListenerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11;
 
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.server.spi.AbstractContainerLifecycleListener;
@@ -40,7 +40,7 @@
  * @author Paul Sandoz
  * @author Marek Potociar
  */
-public class LifecycleListenerTest extends AbstractJettyServerTester {
+public class LifecycleListenerTest extends AbstractJetty11ServerTester {
 
     @Path("/one")
     public static class One {
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/OptionsTest.java b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/OptionsTest.java
similarity index 91%
copy from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/OptionsTest.java
copy to containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/OptionsTest.java
index 3e7a8ac..8ba1b4b 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/OptionsTest.java
+++ b/containers/jetty11-http/src/test/java/org/glassfish/jersey/jetty11/OptionsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11;
 
 import org.junit.jupiter.api.Test;
 
@@ -28,7 +28,7 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-public class OptionsTest extends AbstractJettyServerTester {
+public class OptionsTest extends AbstractJetty11ServerTester {
 
     @Path("helloworld")
     public static class HelloWorldResource {
diff --git a/containers/jetty11-http2/pom.xml b/containers/jetty11-http2/pom.xml
new file mode 100644
index 0000000..15a7d78
--- /dev/null
+++ b/containers/jetty11-http2/pom.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>project</artifactId>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <version>3.1.99-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>jersey-container-jetty11-http2</artifactId>
+    <packaging>jar</packaging>
+    <name>jersey-container-jetty11-http2</name>
+
+    <description>Jetty 11 Http2 Container</description>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-util</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty.http2</groupId>
+                <artifactId>http2-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-alpn-conscrypt-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-jetty11-http</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>jetty-server</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>jetty-util</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.inject</groupId>
+            <artifactId>jakarta.inject-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${jetty11.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>${jetty11.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty.http2</groupId>
+            <artifactId>http2-server</artifactId>
+            <version>${jetty11.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>jetty-server</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-alpn-conscrypt-server</artifactId>
+            <version>${jetty11.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.sun.istack</groupId>
+                <artifactId>istack-commons-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <inherited>true</inherited>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            ${jetty.osgi.version},
+                            *
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+
+        <resources>
+            <resource>
+                <directory>${basedir}/src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
+
+</project>
diff --git a/containers/jetty-http2/src/main/java11/org/glassfish/jersey/jetty/http2/JettyHttp2ContainerFactory.java b/containers/jetty11-http2/src/main/java/org/glassfish/jersey/jetty11/http2/Jetty11Http2ContainerFactory.java
similarity index 92%
rename from containers/jetty-http2/src/main/java11/org/glassfish/jersey/jetty/http2/JettyHttp2ContainerFactory.java
rename to containers/jetty11-http2/src/main/java/org/glassfish/jersey/jetty11/http2/Jetty11Http2ContainerFactory.java
index b03f409..b2248bf 100644
--- a/containers/jetty-http2/src/main/java11/org/glassfish/jersey/jetty/http2/JettyHttp2ContainerFactory.java
+++ b/containers/jetty11-http2/src/main/java/org/glassfish/jersey/jetty11/http2/Jetty11Http2ContainerFactory.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11.http2;
 
 import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
 import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
@@ -27,9 +27,9 @@
 import org.eclipse.jetty.server.ServerConnector;
 import org.eclipse.jetty.server.SslConnectionFactory;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.glassfish.jersey.jetty.JettyHttpContainer;
-import org.glassfish.jersey.jetty.JettyHttpContainerFactory;
-import org.glassfish.jersey.jetty.JettyHttpContainerProvider;
+import org.glassfish.jersey.jetty11.Jetty11HttpContainer;
+import org.glassfish.jersey.jetty11.Jetty11HttpContainerFactory;
+import org.glassfish.jersey.jetty11.Jetty11HttpContainerProvider;
 import org.glassfish.jersey.server.ContainerFactory;
 import org.glassfish.jersey.server.ResourceConfig;
 
@@ -38,9 +38,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-public final class JettyHttp2ContainerFactory {
+public final class Jetty11Http2ContainerFactory {
 
-    private JettyHttp2ContainerFactory() {
+    private Jetty11Http2ContainerFactory() {
 
     }
 
@@ -80,7 +80,7 @@
     public static Server createHttp2Server(final URI uri, final ResourceConfig configuration, final boolean start)
             throws ProcessingException {
         return createHttp2Server(uri, null,
-                ContainerFactory.createContainer(JettyHttpContainer.class, configuration), start);
+                ContainerFactory.createContainer(Jetty11HttpContainer.class, configuration), start);
     }
 
     /**
@@ -119,14 +119,14 @@
      *
      * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
      * @throws IllegalArgumentException if {@code uri} is {@code null}.
-     * @see JettyHttpContainer
+     * @see Jetty11HttpContainer
      *
      * @since 2.40
      */
     public static Server createHttp2Server(final URI uri, final ResourceConfig config, final boolean start,
                                            final Object parentContext) {
         return createHttp2Server(uri, null,
-                new JettyHttpContainerProvider().createContainer(JettyHttpContainer.class,
+                new Jetty11HttpContainerProvider().createContainer(Jetty11HttpContainer.class,
                         config, parentContext), start);
     }
 
@@ -148,19 +148,19 @@
      *
      * @throws ProcessingException      in case of any failure when creating a new Jetty {@code Server} instance.
      * @throws IllegalArgumentException if {@code uri} is {@code null}.
-     * @see JettyHttpContainer
+     * @see Jetty11HttpContainer
      *
      * @since 2.40
      */
     public static Server createHttp2Server(final URI uri,
                                            final SslContextFactory.Server sslContextFactory,
-                                           final JettyHttpContainer handler,
+                                           final Jetty11HttpContainer handler,
                                            final boolean start) {
 
         /**
          * Creating basic Jetty HTTP/1.1 container (but always not started)
          */
-        final Server server = JettyHttpContainerFactory.createServer(uri, sslContextFactory, handler, false);
+        final Server server = Jetty11HttpContainerFactory.createServer(uri, sslContextFactory, handler, false);
         /**
          * Obtain configured HTTP connection factory
          */
diff --git a/containers/jetty-http2/src/main/java/org/glassfish/jersey/jetty/http2/JettyHttp2ContainerProvider.java b/containers/jetty11-http2/src/main/java/org/glassfish/jersey/jetty11/http2/Jetty11Http2ContainerProvider.java
similarity index 68%
rename from containers/jetty-http2/src/main/java/org/glassfish/jersey/jetty/http2/JettyHttp2ContainerProvider.java
rename to containers/jetty11-http2/src/main/java/org/glassfish/jersey/jetty11/http2/Jetty11Http2ContainerProvider.java
index 01c61fc..a48c266 100644
--- a/containers/jetty-http2/src/main/java/org/glassfish/jersey/jetty/http2/JettyHttp2ContainerProvider.java
+++ b/containers/jetty11-http2/src/main/java/org/glassfish/jersey/jetty11/http2/Jetty11Http2ContainerProvider.java
@@ -14,28 +14,28 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11.http2;
 
 import org.glassfish.jersey.internal.util.JdkVersion;
-import org.glassfish.jersey.jetty.JettyHttpContainer;
-import org.glassfish.jersey.jetty.JettyHttpContainerProvider;
-import org.glassfish.jersey.jetty.internal.LocalizationMessages;
+import org.glassfish.jersey.jetty11.Jetty11HttpContainer;
+import org.glassfish.jersey.jetty11.Jetty11HttpContainerProvider;
+import org.glassfish.jersey.jetty11.internal.LocalizationMessages;
 import org.glassfish.jersey.server.spi.ContainerProvider;
 
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.core.Application;
 
-import static org.glassfish.jersey.jetty.JettyHttpContainerProvider.HANDLER_NAME;
+import static org.glassfish.jersey.jetty11.Jetty11HttpContainerProvider.HANDLER_NAME;
 
-public final class JettyHttp2ContainerProvider implements ContainerProvider {
+public final class Jetty11Http2ContainerProvider implements ContainerProvider {
 
     @Override
     public <T> T createContainer(final Class<T> type, final Application application) throws ProcessingException {
         if (JdkVersion.getJdkVersion().getMajor() < 11) {
             throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
         }
-        if (type != null && (HANDLER_NAME.equalsIgnoreCase(type.getCanonicalName()) || JettyHttpContainer.class == type)) {
-            return type.cast(new JettyHttpContainerProvider().createContainer(JettyHttpContainer.class, application));
+        if (type != null && (HANDLER_NAME.equalsIgnoreCase(type.getCanonicalName()) || Jetty11HttpContainer.class == type)) {
+            return type.cast(new Jetty11HttpContainerProvider().createContainer(Jetty11HttpContainer.class, application));
         }
         return null;
     }
diff --git a/containers/jetty-http2/src/main/java/org/glassfish/jersey/jetty/http2/package-info.java b/containers/jetty11-http2/src/main/java/org/glassfish/jersey/jetty11/http2/package-info.java
similarity index 94%
rename from containers/jetty-http2/src/main/java/org/glassfish/jersey/jetty/http2/package-info.java
rename to containers/jetty11-http2/src/main/java/org/glassfish/jersey/jetty11/http2/package-info.java
index a402b27..6f005f1 100644
--- a/containers/jetty-http2/src/main/java/org/glassfish/jersey/jetty/http2/package-info.java
+++ b/containers/jetty11-http2/src/main/java/org/glassfish/jersey/jetty11/http2/package-info.java
@@ -17,4 +17,4 @@
 /**
  * Jersey Jetty HTTP2 container classes.
  */
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11.http2;
diff --git a/containers/jetty11-http2/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ContainerProvider b/containers/jetty11-http2/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ContainerProvider
new file mode 100644
index 0000000..ba63b3d
--- /dev/null
+++ b/containers/jetty11-http2/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ContainerProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.jetty11.http2.Jetty11Http2ContainerProvider
diff --git a/containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties b/containers/jetty11-http2/src/main/resources/org/glassfish/jersey/jetty11/http2/localization.properties
similarity index 98%
rename from containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties
rename to containers/jetty11-http2/src/main/resources/org/glassfish/jersey/jetty11/http2/localization.properties
index 9807184..ba290bd 100644
--- a/containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties
+++ b/containers/jetty11-http2/src/main/resources/org/glassfish/jersey/jetty11/http2/localization.properties
@@ -16,4 +16,4 @@
 
 # {0} - status code; {1} - status reason message
 error.when.creating.server=Exception thrown when trying to create jetty server.
-not.supported=Jetty container is not supported on JDK version less than 11.
\ No newline at end of file
+not.supported=Jetty container is not supported on JDK version less than 17.
\ No newline at end of file
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AbstractJettyServerTester.java b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/AbstractJetty11ServerTester.java
similarity index 92%
rename from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AbstractJettyServerTester.java
rename to containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/AbstractJetty11ServerTester.java
index 6134d03..037503e 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AbstractJettyServerTester.java
+++ b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/AbstractJetty11ServerTester.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11.http2;
 
 import java.net.URI;
 import java.security.AccessController;
@@ -38,9 +38,9 @@
  * @author Arul Dhesiaseelan (aruld at acm.org)
  * @author Miroslav Fuksa
  */
-public abstract class AbstractJettyServerTester {
+public abstract class AbstractJetty11ServerTester {
 
-    private static final Logger LOGGER = Logger.getLogger(AbstractJettyServerTester.class.getName());
+    private static final Logger LOGGER = Logger.getLogger(AbstractJetty11ServerTester.class.getName());
 
     public static final String CONTEXT = "";
     private static final int DEFAULT_PORT = 0; // rather Jetty choose than 9998
@@ -93,13 +93,13 @@
         ResourceConfig config = new ResourceConfig(resources);
         config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
         final URI baseUri = getBaseUri();
-        server = JettyHttp2ContainerFactory.createHttp2Server(baseUri, config, true);
+        server = Jetty11Http2ContainerFactory.createHttp2Server(baseUri, config, true);
         LOGGER.log(Level.INFO, "Jetty-http server started on base uri: " + server.getURI());
     }
 
     public void startServer(ResourceConfig config) {
         final URI baseUri = getBaseUri();
-        server = JettyHttp2ContainerFactory.createHttp2Server(baseUri, config, true);
+        server = Jetty11Http2ContainerFactory.createHttp2Server(baseUri, config, true);
         LOGGER.log(Level.INFO, "Jetty-http server started on base uri: " + server.getURI());
     }
 
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AsyncTest.java b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/AsyncTest.java
similarity index 97%
rename from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AsyncTest.java
rename to containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/AsyncTest.java
index ac1ebb5..e2dada8 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/AsyncTest.java
+++ b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/AsyncTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11.http2;
 
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -42,7 +42,7 @@
  * @author Arul Dhesiaseelan (aruld at acm.org)
  * @author Michal Gajdos
  */
-public class AsyncTest extends AbstractJettyServerTester {
+public class AsyncTest extends AbstractJetty11ServerTester {
 
     @Path("/async")
     @SuppressWarnings("VoidMethodAnnotatedWithGET")
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/ExceptionTest.java b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/ExceptionTest.java
similarity index 96%
rename from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/ExceptionTest.java
rename to containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/ExceptionTest.java
index 60e086b..ce441bf 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/ExceptionTest.java
+++ b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/ExceptionTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11.http2;
 
 import org.apache.http.HttpHost;
 import org.apache.http.client.methods.CloseableHttpResponse;
@@ -40,7 +40,7 @@
 /**
  * @author Paul Sandoz
  */
-public class ExceptionTest extends AbstractJettyServerTester {
+public class ExceptionTest extends AbstractJetty11ServerTester {
     @Path("{status}")
     public static class ExceptionResource {
         @GET
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/LifecycleListenerTest.java b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/LifecycleListenerTest.java
similarity index 96%
rename from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/LifecycleListenerTest.java
rename to containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/LifecycleListenerTest.java
index 93ae01f..2236d25 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/LifecycleListenerTest.java
+++ b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/LifecycleListenerTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11.http2;
 
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.server.spi.AbstractContainerLifecycleListener;
@@ -40,7 +40,7 @@
  * @author Paul Sandoz
  * @author Marek Potociar
  */
-public class LifecycleListenerTest extends AbstractJettyServerTester {
+public class LifecycleListenerTest extends AbstractJetty11ServerTester {
 
     @Path("/one")
     public static class One {
diff --git a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/OptionsTest.java b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/OptionsTest.java
similarity index 94%
rename from containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/OptionsTest.java
rename to containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/OptionsTest.java
index 3e7a8ac..c5e07cf 100644
--- a/containers/jetty-http2/src/test/java/org/glassfish/jersey/jetty/http2/OptionsTest.java
+++ b/containers/jetty11-http2/src/test/java/org/glassfish/jersey/jetty11/http2/OptionsTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.jetty.http2;
+package org.glassfish.jersey.jetty11.http2;
 
 import org.junit.jupiter.api.Test;
 
@@ -28,7 +28,7 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-public class OptionsTest extends AbstractJettyServerTester {
+public class OptionsTest extends AbstractJetty11ServerTester {
 
     @Path("helloworld")
     public static class HelloWorldResource {
diff --git a/containers/netty-http/pom.xml b/containers/netty-http/pom.xml
index 40e4424..7f0329e 100644
--- a/containers/netty-http/pom.xml
+++ b/containers/netty-http/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-container-netty-http</artifactId>
@@ -42,6 +42,11 @@
             <artifactId>jersey-netty-connector</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyHttp2ServerHandler.java b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyHttp2ServerHandler.java
index 924fb9a..3212cd7 100644
--- a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyHttp2ServerHandler.java
+++ b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyHttp2ServerHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -135,6 +135,11 @@
                     private final Map<String, Object> properties = new HashMap<>();
 
                     @Override
+                    public boolean hasProperty(final String name) {
+                        return properties.containsKey(name);
+                    }
+
+                    @Override
                     public Object getProperty(String name) {
                         return properties.get(name);
                     }
diff --git a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyServerHandler.java b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyServerHandler.java
index 0b43e1e..69105a1 100644
--- a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyServerHandler.java
+++ b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyServerHandler.java
@@ -166,6 +166,11 @@
                     private final Map<String, Object> properties = new HashMap<>();
 
                     @Override
+                    public boolean hasProperty(final String name) {
+                        return properties.containsKey(name);
+                    }
+
+                    @Override
                     public Object getProperty(String name) {
                         return properties.get(name);
                     }
diff --git a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpContainer.java b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpContainer.java
index cbd7fe4..d6e8508 100644
--- a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpContainer.java
+++ b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpContainer.java
@@ -41,6 +41,11 @@
         this.appHandler.onStartup(this);
     }
 
+    NettyHttpContainer(Class<? extends Application> applicationClass) {
+        this.appHandler = new ApplicationHandler(applicationClass);
+        this.appHandler.onStartup(this);
+    }
+
     @Override
     public ResourceConfig getConfiguration() {
         return appHandler.getConfiguration();
diff --git a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpContainerProvider.java b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpContainerProvider.java
index 6f926c0..3d78837 100644
--- a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpContainerProvider.java
+++ b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpContainerProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -58,7 +58,7 @@
      * Create and start Netty server.
      *
      * @param baseUri       base uri.
-     * @param configuration Jersey configuration.
+     * @param container     Jersey container.
      * @param sslContext    Netty SSL context (can be null).
      * @param block         when {@code true}, this method will block until the server is stopped. When {@code false}, the
      *                      execution will
@@ -66,25 +66,64 @@
      * @return Netty channel instance.
      * @throws ProcessingException when there is an issue with creating new container.
      */
-    public static Channel createServer(final URI baseUri, final ResourceConfig configuration, SslContext sslContext,
+    public static Channel createServer(final URI baseUri, final NettyHttpContainer container, SslContext sslContext,
                                        final boolean block)
             throws ProcessingException {
 
+        final ServerBootstrap serverBootstrap = createServerBootstrap(baseUri, container, sslContext);
+        return startServer(getPort(baseUri), container, serverBootstrap, block);
+    }
+
+    /**
+     * Create but not start Netty server.
+     *
+     * @param baseUri       base uri.
+     * @param container     Jersey container.
+     * @param sslContext    Netty SSL context (can be null).
+     * @return Netty bootstrap instance.
+     * @throws ProcessingException when there is an issue with creating new container.
+     */
+    static ServerBootstrap createServerBootstrap(final URI baseUri, final NettyHttpContainer container, SslContext sslContext) {
+        final JerseyServerInitializer jerseyServerInitializer =
+                new JerseyServerInitializer(baseUri, sslContext, container, container.getConfiguration());
+        return createServerBootstrap(jerseyServerInitializer);
+    }
+
+    private static ServerBootstrap createServerBootstrap(final JerseyServerInitializer jerseyServerInitializer) {
         // Configure the server.
         final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
         final EventLoopGroup workerGroup = new NioEventLoopGroup();
-        final NettyHttpContainer container = new NettyHttpContainer(configuration);
+
+        ServerBootstrap b = new ServerBootstrap();
+        b.option(ChannelOption.SO_BACKLOG, 1024);
+        b.group(bossGroup, workerGroup)
+                .channel(NioServerSocketChannel.class)
+                .childHandler(jerseyServerInitializer);
+
+        return b;
+    }
+
+    /**
+     * Start Netty server.
+     *
+     * @param port          IP port to listen.
+     * @param container     Jersey container.
+     * @param serverBootstrap Netty server bootstrap (i. e. prepared but unstarted server instance)
+     * @param block         when {@code true}, this method will block until the server is stopped. When {@code false}, the
+     *                      execution will
+     *                      end immediately after the server is started.
+     * @return Netty channel instance.
+     * @throws ProcessingException when there is an issue with creating new container.
+     */
+    static Channel startServer(final int port, final NettyHttpContainer container, final ServerBootstrap serverBootstrap,
+                                       final boolean block)
+            throws ProcessingException {
 
         try {
-            ServerBootstrap b = new ServerBootstrap();
-            b.option(ChannelOption.SO_BACKLOG, 1024);
-            b.group(bossGroup, workerGroup)
-             .channel(NioServerSocketChannel.class)
-             .childHandler(new JerseyServerInitializer(baseUri, sslContext, container, configuration));
+            final EventLoopGroup bossGroup = serverBootstrap.config().group();
+            final EventLoopGroup workerGroup = serverBootstrap.config().childGroup();
 
-            int port = getPort(baseUri);
-
-            Channel ch = b.bind(port).sync().channel();
+            Channel ch = serverBootstrap.bind(port).sync().channel();
 
             ch.closeFuture().addListener(new GenericFutureListener<Future<? super Void>>() {
                 @Override
@@ -112,6 +151,24 @@
      *
      * @param baseUri       base uri.
      * @param configuration Jersey configuration.
+     * @param sslContext    Netty SSL context (can be null).
+     * @param block         when {@code true}, this method will block until the server is stopped. When {@code false}, the
+     *                      execution will
+     *                      end immediately after the server is started.
+     * @return Netty channel instance.
+     * @throws ProcessingException when there is an issue with creating new container.
+     */
+    public static Channel createServer(final URI baseUri, final ResourceConfig configuration, SslContext sslContext,
+                                       final boolean block)
+            throws ProcessingException {
+        return createServer(baseUri, new NettyHttpContainer(configuration), sslContext, block);
+    }
+
+    /**
+     * Create and start Netty server.
+     *
+     * @param baseUri       base uri.
+     * @param configuration Jersey configuration.
      * @param block         when {@code true}, this method will block until the server is stopped. When {@code false}, the
      *                      execution will
      *                      end immediately after the server is started.
@@ -140,39 +197,18 @@
     public static Channel createHttp2Server(final URI baseUri, final ResourceConfig configuration, SslContext sslContext) throws
             ProcessingException {
 
-        final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
-        final EventLoopGroup workerGroup = new NioEventLoopGroup();
         final NettyHttpContainer container = new NettyHttpContainer(configuration);
 
-        try {
-            ServerBootstrap b = new ServerBootstrap();
-            b.option(ChannelOption.SO_BACKLOG, 1024);
-            b.group(bossGroup, workerGroup)
-             .channel(NioServerSocketChannel.class)
-             .childHandler(new JerseyServerInitializer(baseUri, sslContext, container, configuration, true));
+        final JerseyServerInitializer jerseyServerInitializer =
+                new JerseyServerInitializer(baseUri, sslContext, container, configuration, true);
+        ServerBootstrap serverBootstrap = createServerBootstrap(jerseyServerInitializer);
 
-            int port = getPort(baseUri);
+        int port = getPort(baseUri);
 
-            Channel ch = b.bind(port).sync().channel();
-
-            ch.closeFuture().addListener(new GenericFutureListener<Future<? super Void>>() {
-                @Override
-                public void operationComplete(Future<? super Void> future) throws Exception {
-                    container.getApplicationHandler().onShutdown(container);
-
-                    bossGroup.shutdownGracefully();
-                    workerGroup.shutdownGracefully();
-                }
-            });
-
-            return ch;
-
-        } catch (InterruptedException e) {
-            throw new ProcessingException(e);
-        }
+        return startServer(port, container, serverBootstrap, false);
     }
 
-    private static int getPort(URI uri) {
+    static int getPort(URI uri) {
         if (uri.getPort() == -1) {
             if ("http".equalsIgnoreCase(uri.getScheme())) {
                 return 80;
diff --git a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpServer.java b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpServer.java
new file mode 100644
index 0000000..7b28779
--- /dev/null
+++ b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpServer.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.netty.httpserver;
+
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.Channel;
+import io.netty.handler.ssl.ClientAuth;
+import io.netty.handler.ssl.JdkSslContext;
+
+/**
+ * Jersey {@code Server} implementation based on Netty {@link Channel}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+final class NettyHttpServer implements WebServer {
+
+    private final NettyHttpContainer container;
+
+    private final ServerBootstrap serverBootstrap;
+
+    private volatile Channel channel;
+
+    private final int port;
+
+    NettyHttpServer(final Application application, final JerseySeBootstrapConfiguration configuration) {
+        this(new NettyHttpContainer(application), configuration);
+    }
+
+    NettyHttpServer(final Class<? extends Application> applicationClass,
+                    final JerseySeBootstrapConfiguration configuration) {
+        this(new NettyHttpContainer(applicationClass), configuration);
+    }
+
+    NettyHttpServer(final NettyHttpContainer container, final JerseySeBootstrapConfiguration configuration) {
+        final SSLContext sslContext = configuration.sslContext();
+        final SeBootstrap.Configuration.SSLClientAuthentication sslClientAuthentication = configuration
+                .sslClientAuthentication();
+
+        final URI uri = configuration.uri(true);
+        this.port = NettyHttpContainerProvider.getPort(uri);
+
+        this.container = container;
+        this.serverBootstrap = NettyHttpContainerProvider.createServerBootstrap(
+                uri,
+                this.container,
+                configuration.isHttps()
+                        ? new JdkSslContext(sslContext, false, nettyClientAuth(sslClientAuthentication))
+                        : null
+        );
+
+        if (configuration.autoStart()) {
+            this.channel = NettyHttpContainerProvider.startServer(this.port, this.container, this.serverBootstrap, false);
+        }
+    }
+
+    private static final ClientAuth nettyClientAuth(
+            final SeBootstrap.Configuration.SSLClientAuthentication sslClientAuthentication) {
+        switch (sslClientAuthentication) {
+        case MANDATORY:
+            return ClientAuth.REQUIRE;
+        case OPTIONAL:
+            return ClientAuth.OPTIONAL;
+        default:
+            return ClientAuth.NONE;
+        }
+    }
+
+    @Override
+    public final NettyHttpContainer container() {
+        return this.container;
+    }
+
+    @Override
+    public final int port() {
+        return this.channel == null ? this.port : ((InetSocketAddress) this.channel.localAddress()).getPort();
+    }
+
+    @Override
+    public final CompletableFuture<Object> start() {
+        return this.channel != null ? CompletableFuture.completedFuture(this.channel)
+                : CompletableFuture.supplyAsync(() -> {
+                    try {
+                        this.channel = NettyHttpContainerProvider.startServer(this.port, this.container,
+                                this.serverBootstrap, false);
+                        return this.channel;
+                    } catch (final Exception e) {
+                        throw new CompletionException(e);
+                    }
+                });
+    }
+
+    @Override
+    public final CompletableFuture<Void> stop() {
+        return this.channel == null ? CompletableFuture.completedFuture(null) : CompletableFuture.supplyAsync(() -> {
+            try {
+                return this.channel.close().get();
+            } catch (final Exception e) {
+                throw new CompletionException(e);
+            }
+        });
+    }
+
+    @Override
+    public final <T> T unwrap(final Class<T> nativeClass) {
+        return nativeClass.cast(this.channel == null ? this.serverBootstrap : this.channel);
+    }
+
+}
diff --git a/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpServerProvider.java b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpServerProvider.java
new file mode 100644
index 0000000..0749369
--- /dev/null
+++ b/containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/NettyHttpServerProvider.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.netty.httpserver;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+
+import io.netty.channel.Channel;
+
+/**
+ * Server provider for servers based on Netty {@link Channel}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class NettyHttpServerProvider implements WebServerProvider {
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Application application,
+                                                final SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(NettyHttpServer.class, type, configuration)
+                ? type.cast(new NettyHttpServer(application, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Class<? extends Application> applicationClass,
+                                                final SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(NettyHttpServer.class, type, configuration)
+                ? type.cast(new NettyHttpServer(applicationClass, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+}
diff --git a/containers/netty-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider b/containers/netty-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
new file mode 100644
index 0000000..61e6e1b
--- /dev/null
+++ b/containers/netty-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.netty.httpserver.NettyHttpServerProvider
\ No newline at end of file
diff --git a/containers/netty-http/src/test/java/org/glassfish/jersey/netty/httpserver/NettyHttpServerProviderTest.java b/containers/netty-http/src/test/java/org/glassfish/jersey/netty/httpserver/NettyHttpServerProviderTest.java
new file mode 100644
index 0000000..8ea7dd5
--- /dev/null
+++ b/containers/netty-http/src/test/java/org/glassfish/jersey/netty/httpserver/NettyHttpServerProviderTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.netty.httpserver;
+
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+
+import java.security.AccessController;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.Channel;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+/**
+ * Unit tests for {@link NettyHttpServerProvider}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class NettyHttpServerProviderTest {
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServer2() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        shouldProvideServer(ShouldProvideServerApplication.class, resource);
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServerWithClass() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        final Application application = new ShouldProvideServerApplication();
+        shouldProvideServer(application.getClass(), resource);
+    }
+
+    private void shouldProvideServer(final Object application, final Resource resource)
+            throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new NettyHttpServerProvider();
+        final SeBootstrap.Configuration configuration = configuration(getPort(), FALSE);
+
+        // when
+        final WebServer webServer = Application.class.isInstance(application)
+                ? webServerProvider.createServer(WebServer.class, (Application) application, configuration)
+                : webServerProvider.createServer(WebServer.class, (Class<Application>) application, configuration);
+        final Object nativeHandle = webServer.unwrap(Object.class);
+        final CompletionStage<?> start = webServer.start();
+        final Object startResult = start.toCompletableFuture().get();
+        final Container container = webServer.container();
+        final int port = webServer.port();
+        final String entity = ClientBuilder.newClient()
+                .target(UriBuilder.newInstance().scheme("http").host("localhost").port(port).build()).request()
+                .get(String.class);
+        final CompletionStage<?> stop = webServer.stop();
+        final Object stopResult = stop.toCompletableFuture().get();
+
+        // then
+        assertThat(webServer, is(instanceOf(NettyHttpServer.class)));
+        assertThat(nativeHandle, is(instanceOf(ServerBootstrap.class)));
+        assertThat(startResult, is(instanceOf(Channel.class)));
+        assertThat(container, is(instanceOf(NettyHttpContainer.class)));
+        assertThat(port, is(greaterThan(0)));
+        assertThat(entity, is(resource.toString()));
+        assertThat(stopResult, is(nullValue()));
+    }
+
+
+    @Path("/")
+    protected static final class Resource {
+        @GET
+        @Override
+        public String toString() {
+            return Resource.class.getName();
+        }
+    }
+
+    protected static class ShouldProvideServerApplication extends Application {
+        @Override
+        public Set<Object> getSingletons() {
+            return Collections.singleton(new Resource());
+        }
+    }
+
+    private static final Logger LOGGER = Logger.getLogger(NettyHttpServerProviderTest.class.getName());
+
+    private static final int DEFAULT_PORT = 0;
+
+    private static final int getPort() {
+        final String value = AccessController
+                .doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
+        if (value != null) {
+            try {
+                final int i = Integer.parseInt(value);
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
+                }
+                return i;
+            } catch (final NumberFormatException e) {
+                LOGGER.log(Level.CONFIG,
+                        "Value of 'jersey.config.test.container.port'"
+                                + " property is not a valid non-negative integer [" + value + "]."
+                                + " Reverting to default [" + DEFAULT_PORT + "].",
+                        e);
+            }
+        }
+
+        return DEFAULT_PORT;
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public final void shouldScanFreePort() throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new NettyHttpServerProvider();
+        final Application application = new Application();
+        final SeBootstrap.Configuration configuration = configuration(SeBootstrap.Configuration.FREE_PORT, TRUE);
+
+        // when
+        final WebServer webServer = webServerProvider.createServer(WebServer.class, application, configuration);
+
+        // then
+        assertThat(webServer.port(), is(greaterThan(0)));
+    }
+
+    private SeBootstrap.Configuration configuration(int port, boolean autoStart) {
+        return (SeBootstrap.Configuration) name -> {
+            switch (name) {
+                case SeBootstrap.Configuration.PROTOCOL:
+                    return "HTTP";
+                case SeBootstrap.Configuration.HOST:
+                    return "localhost";
+                case SeBootstrap.Configuration.PORT:
+                    return port;
+                case SeBootstrap.Configuration.ROOT_PATH:
+                    return "/";
+                case SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION:
+                    return SSLClientAuthentication.NONE;
+                case SeBootstrap.Configuration.SSL_CONTEXT:
+                    try {
+                        return SSLContext.getDefault();
+                    } catch (final NoSuchAlgorithmException e) {
+                        throw new RuntimeException(e);
+                    }
+                case ServerProperties.WEBSERVER_AUTO_START:
+                    return autoStart;
+                default:
+                    return null;
+            }
+        };
+    }
+
+}
\ No newline at end of file
diff --git a/containers/pom.xml b/containers/pom.xml
index f64b698..2196acb 100644
--- a/containers/pom.xml
+++ b/containers/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.containers</groupId>
@@ -40,8 +40,9 @@
         <module>jdk-http</module>
         <module>jersey-servlet-core</module>
         <module>jersey-servlet</module>
+        <module>jetty11-http</module>
         <module>jetty-http</module>
-        <module>jetty-http2</module>
+        <module>jetty11-http2</module>
         <module>jetty-servlet</module>
         <module>netty-http</module>
         <module>simple-http</module>
diff --git a/containers/simple-http/pom.xml b/containers/simple-http/pom.xml
index bad8eb1..6f94d79 100644
--- a/containers/simple-http/pom.xml
+++ b/containers/simple-http/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.containers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-container-simple-http</artifactId>
diff --git a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java
index afd86b5..6298cf3 100644
--- a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java
+++ b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java
@@ -465,4 +465,15 @@
         this.appHandler = new ApplicationHandler(application, new SimpleBinder());
         this.scheduler = new ScheduledThreadPoolExecutor(2, new DaemonFactory(TimeoutDispatcher.class));
     }
+
+    /**
+     * Create a new Simple framework HTTP container.
+     *
+     * @param applicationClass JAX-RS / Jersey application class to be deployed on Simple framework HTTP
+     *                    container.
+     */
+    SimpleContainer(final Class<? extends Application> applicationClass) {
+        this.appHandler = new ApplicationHandler(applicationClass, new SimpleBinder());
+        this.scheduler = new ScheduledThreadPoolExecutor(2, new DaemonFactory(TimeoutDispatcher.class));
+    }
 }
diff --git a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java
index 6740c6b..519fe7d 100644
--- a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java
+++ b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,19 +19,19 @@
 import java.io.Closeable;
 import java.io.IOException;
 import java.net.InetSocketAddress;
-import java.net.SocketAddress;
 import java.net.URI;
 
-import jakarta.ws.rs.ProcessingException;
-
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication;
+import jakarta.ws.rs.ProcessingException;
 
 import org.glassfish.jersey.internal.util.collection.UnsafeValue;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.simple.internal.LocalizationMessages;
-
 import org.simpleframework.http.core.Container;
 import org.simpleframework.http.core.ContainerSocketProcessor;
+import org.simpleframework.transport.Socket;
 import org.simpleframework.transport.SocketProcessor;
 import org.simpleframework.transport.connect.Connection;
 import org.simpleframework.transport.connect.SocketConnection;
@@ -149,7 +149,55 @@
             public SocketProcessor get() throws IOException {
                 return new ContainerSocketProcessor(container);
             }
-        });
+        }, true);
+    }
+
+    /**
+     * Create a {@link Closeable} that registers an {@link Container} that in turn manages all root
+     * resource and provider classes found by searching the classes referenced in the java classpath.
+     *
+     * @param address   the URI to create the http server. The URI scheme must be equal to {@code https}
+     *                  . The URI user information and host are ignored. If the URI port is not present then
+     *                  port {@value org.glassfish.jersey.server.spi.Container#DEFAULT_HTTPS_PORT} will be used.
+     *                  The URI path, query and fragment components are ignored.
+     * @param context   this is the SSL context used for SSL connections.
+     * @param container the Simple container with ResourceConfig.
+     * @param sslClientAuthentication Secure socket client authentication policy.
+     * @param start whether the server shall listen to connections immediately
+     * @return the closeable connection, with the endpoint started.
+     * @throws ProcessingException      thrown when problems during server creation.
+     * @throws IllegalArgumentException if {@code address} is {@code null}.
+     */
+    public static SimpleServer create(final URI address, final SSLContext context,
+            final SSLClientAuthentication sslClientAuthentication, final SimpleContainer container, final boolean start) {
+        return _create(address, context, container, new UnsafeValue<SocketProcessor, IOException>() {
+            @Override
+            public SocketProcessor get() throws IOException {
+                return new ContainerSocketProcessor(container) {
+                    @Override
+                    public final void process(final Socket socket) throws IOException {
+                        final SSLEngine sslEngine = socket.getEngine();
+                        if (sslEngine != null) {
+                            switch (sslClientAuthentication) {
+                            case MANDATORY: {
+                                sslEngine.setNeedClientAuth(true);
+                                break;
+                            }
+                            case OPTIONAL: {
+                                sslEngine.setWantClientAuth(true);
+                                break;
+                            }
+                            default: {
+                                sslEngine.setNeedClientAuth(false);
+                                break;
+                            }
+                            }
+                        }
+                        super.process(socket);
+                    }
+                };
+            }
+        }, start);
     }
 
     /**
@@ -201,12 +249,13 @@
             public SocketProcessor get() throws IOException {
                 return new ContainerSocketProcessor(container, count, select);
             }
-        });
+        }, true);
     }
 
     private static SimpleServer _create(final URI address, final SSLContext context,
                                         final SimpleContainer container,
-                                        final UnsafeValue<SocketProcessor, IOException> serverProvider)
+                                        final UnsafeValue<SocketProcessor, IOException> serverProvider,
+                                        final boolean start)
             throws ProcessingException {
         if (address == null) {
             throw new IllegalArgumentException(LocalizationMessages.URI_CANNOT_BE_NULL());
@@ -236,22 +285,26 @@
             final SocketProcessor server = serverProvider.get();
             connection = new SocketConnection(server, analyzer);
 
+            final SimpleServer simpleServer = new SimpleServer() {
+                private InetSocketAddress socketAddr = listen;
 
-            final SocketAddress socketAddr = connection.connect(listen, context);
-            container.onServerStart();
-
-            return new SimpleServer() {
+                @Override
+                public final void start() throws IOException {
+                    this.socketAddr = (InetSocketAddress) connection.connect(listen, context);
+                    container.onServerStart();
+                }
 
                 @Override
                 public void close() throws IOException {
                     container.onServerStop();
                     analyzer.stop();
                     connection.close();
+                    this.socketAddr = listen;
                 }
 
                 @Override
                 public int getPort() {
-                    return ((InetSocketAddress) socketAddr).getPort();
+                    return this.socketAddr.getPort();
                 }
 
                 @Override
@@ -268,6 +321,12 @@
                     }
                 }
             };
+
+            if (start) {
+                simpleServer.start();
+            }
+
+            return simpleServer;
         } catch (final IOException ex) {
             throw new ProcessingException(LocalizationMessages.ERROR_WHEN_CREATING_SERVER(), ex);
         }
diff --git a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleHttpServer.java b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleHttpServer.java
new file mode 100644
index 0000000..1b9ac18
--- /dev/null
+++ b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleHttpServer.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.simple;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+
+/**
+ * Jersey {@code Server} implementation based on Simple framework
+ * {@link SimpleServer}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+final class SimpleHttpServer implements WebServer {
+
+    private final SimpleContainer container;
+
+    private final SimpleServer simpleServer;
+
+    SimpleHttpServer(final Application application, final JerseySeBootstrapConfiguration configuration) {
+        this(new SimpleContainer(application), configuration);
+    }
+
+    SimpleHttpServer(final Class<?extends Application> applicationClass,
+                     final JerseySeBootstrapConfiguration configuration) {
+        this(new SimpleContainer(applicationClass), configuration);
+    }
+
+    SimpleHttpServer(final SimpleContainer container, final JerseySeBootstrapConfiguration configuration) {
+        this.container = container;
+        this.simpleServer = SimpleContainerFactory.create(
+                configuration.uri(true),
+                configuration.sslContext(),
+                configuration.sslClientAuthentication(),
+                this.container,
+                configuration.autoStart());
+    }
+
+    @Override
+    public final SimpleContainer container() {
+        return this.container;
+    }
+
+    @Override
+    public final int port() {
+        return this.simpleServer.getPort();
+    }
+
+    @Override
+    public final CompletableFuture<Void> start() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                this.simpleServer.start();
+            } catch (final Exception e) {
+                throw new CompletionException(e);
+            }
+        });
+    }
+
+    @Override
+    public final CompletableFuture<Void> stop() {
+        return CompletableFuture.runAsync(() -> {
+            try {
+                this.simpleServer.close();
+            } catch (final Exception e) {
+                throw new CompletionException(e);
+            }
+        });
+    }
+
+    @Override
+    public final <T> T unwrap(final Class<T> nativeClass) {
+        return nativeClass.cast(this.simpleServer);
+    }
+
+}
diff --git a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleHttpServerProvider.java b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleHttpServerProvider.java
new file mode 100644
index 0000000..33bd6a7
--- /dev/null
+++ b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleHttpServerProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.simple;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+
+/**
+ * Server provider for servers based on Simple framework {@link SimpleServer}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class SimpleHttpServerProvider implements WebServerProvider {
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Application application,
+                                                      final SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(SimpleHttpServer.class, type, configuration)
+                ? type.cast(new SimpleHttpServer(application, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+
+    @Override
+    public <T extends WebServer> T createServer(final Class<T> type, final Class<? extends Application> applicationClass,
+                                                final SeBootstrap.Configuration configuration) {
+        return WebServerProvider.isSupportedWebServer(SimpleHttpServer.class, type, configuration)
+                ? type.cast(new SimpleHttpServer(applicationClass, JerseySeBootstrapConfiguration.from(configuration)))
+                : null;
+    }
+}
diff --git a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleServer.java b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleServer.java
index 02aec75..7560c52 100644
--- a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleServer.java
+++ b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,6 +17,7 @@
 package org.glassfish.jersey.simple;
 
 import java.io.Closeable;
+import java.io.IOException;
 
 /**
  * Simple server facade providing convenient methods to obtain info about the server (i.e. port).
@@ -26,6 +27,8 @@
  */
 public interface SimpleServer extends Closeable {
 
+    public void start() throws IOException;
+
     /**
      * The port the server is listening to for incomming HTTP connections. If the port is not
      * specified the {@link org.glassfish.jersey.server.spi.Container.DEFAULT_PORT} is used.
diff --git a/containers/simple-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider b/containers/simple-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
new file mode 100644
index 0000000..54d8c53
--- /dev/null
+++ b/containers/simple-http/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.WebServerProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.simple.SimpleHttpServerProvider
\ No newline at end of file
diff --git a/containers/simple-http/src/test/java/org/glassfish/jersey/simple/AbstractSimpleServerTester.java b/containers/simple-http/src/test/java/org/glassfish/jersey/simple/AbstractSimpleServerTester.java
index 3543e50..81c8601 100644
--- a/containers/simple-http/src/test/java/org/glassfish/jersey/simple/AbstractSimpleServerTester.java
+++ b/containers/simple-http/src/test/java/org/glassfish/jersey/simple/AbstractSimpleServerTester.java
@@ -50,21 +50,25 @@
      * @return The HTTP port of the URI
      */
     protected final int getPort() {
+        if (server != null) {
+            return server.getPort();
+        }
+
         final String value = AccessController
                 .doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
         if (value != null) {
 
             try {
                 final int i = Integer.parseInt(value);
-                if (i <= 0) {
-                    throw new NumberFormatException("Value not positive.");
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
                 }
                 return i;
             } catch (NumberFormatException e) {
                 LOGGER.log(
                         Level.CONFIG,
                         "Value of 'jersey.config.test.container.port'"
-                        + " property is not a valid positive integer [" + value + "]."
+                        + " property is not a valid non-negative integer [" + value + "]."
                         + " Reverting to default [" + DEFAULT_PORT + "].",
                         e);
             }
@@ -94,28 +98,28 @@
         config.register(LoggingFeature.class);
         final URI baseUri = getBaseUri();
         server = SimpleContainerFactory.create(baseUri, config);
-        LOGGER.log(Level.INFO, "Simple-http server started on base uri: " + baseUri.getHost() + ":" + server.getPort());
+        LOGGER.log(Level.INFO, "Simple-http server started on base uri: " + getBaseUri());
     }
 
     public void startServerNoLoggingFilter(Class... resources) {
         ResourceConfig config = new ResourceConfig(resources);
         final URI baseUri = getBaseUri();
         server = SimpleContainerFactory.create(baseUri, config);
-        LOGGER.log(Level.INFO, "Simple-http server started on base uri: " + baseUri.getHost() + ":" + server.getPort());
+        LOGGER.log(Level.INFO, "Simple-http server started on base uri: " + getBaseUri());
     }
 
     public void startServer(ResourceConfig config) {
         final URI baseUri = getBaseUri();
         config.register(LoggingFeature.class);
         server = SimpleContainerFactory.create(baseUri, config);
-        LOGGER.log(Level.INFO, "Simple-http server started on base uri: " + baseUri.getHost() + ":" + server.getPort());
+        LOGGER.log(Level.INFO, "Simple-http server started on base uri: " + getBaseUri());
     }
 
     public void startServer(ResourceConfig config, int count, int select) {
         final URI baseUri = getBaseUri();
         config.register(LoggingFeature.class);
         server = SimpleContainerFactory.create(baseUri, config, count, select);
-        LOGGER.log(Level.INFO, "Simple-http server started on base uri: " + baseUri);
+        LOGGER.log(Level.INFO, "Simple-http server started on base uri: " + getBaseUri());
     }
 
     public URI getBaseUri() {
diff --git a/containers/simple-http/src/test/java/org/glassfish/jersey/simple/SimpleHttpServerProviderTest.java b/containers/simple-http/src/test/java/org/glassfish/jersey/simple/SimpleHttpServerProviderTest.java
new file mode 100644
index 0000000..7c6f01b
--- /dev/null
+++ b/containers/simple-http/src/test/java/org/glassfish/jersey/simple/SimpleHttpServerProviderTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.simple;
+
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.instanceOf;
+
+import java.security.AccessController;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.SeBootstrap.Configuration.SSLClientAuthentication;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+/**
+ * Unit tests for {@link SimpleHttpServerProvider}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class SimpleHttpServerProviderTest {
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServer2() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        shouldProvideServer(ShouldProvideServerApplication.class, resource);
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public void shouldProvideServerWithClass() throws InterruptedException, ExecutionException {
+        // given
+        final Resource resource = new Resource();
+        final Application application = new ShouldProvideServerApplication();
+        shouldProvideServer(application.getClass(), resource);
+    }
+
+    private void shouldProvideServer(final Object application, final Resource resource)
+            throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new SimpleHttpServerProvider();
+        final SeBootstrap.Configuration configuration = configuration(getPort(), FALSE);
+
+        // when
+        final WebServer webServer = Application.class.isInstance(application)
+                ? webServerProvider.createServer(WebServer.class, (Application) application, configuration)
+                : webServerProvider.createServer(WebServer.class, (Class<Application>) application, configuration);
+        final Object nativeHandle = webServer.unwrap(Object.class);
+        final CompletionStage<?> start = webServer.start();
+        final Object startResult = start.toCompletableFuture().get();
+        final Container container = webServer.container();
+        final int port = webServer.port();
+        final String entity = ClientBuilder.newClient()
+                .target(UriBuilder.newInstance().scheme("http").host("localhost").port(port).build()).request()
+                .get(String.class);
+        final CompletionStage<?> stop = webServer.stop();
+        final Object stopResult = stop.toCompletableFuture().get();
+
+        // then
+        assertThat(webServer, is(instanceOf(SimpleHttpServer.class)));
+        assertThat(nativeHandle, is(instanceOf(SimpleServer.class)));
+        assertThat(startResult, is(nullValue()));
+        assertThat(container, is(instanceOf(SimpleContainer.class)));
+        assertThat(port, is(greaterThan(0)));
+        assertThat(entity, is(resource.toString()));
+        assertThat(stopResult, is(nullValue()));
+    }
+
+    @Path("/")
+    protected static final class Resource {
+        @GET
+        @Override
+        public String toString() {
+            return Resource.class.getName();
+        }
+    }
+
+    protected static class ShouldProvideServerApplication extends Application {
+        @Override
+        public Set<Object> getSingletons() {
+            return Collections.singleton(new Resource());
+        }
+    }
+
+    private static final Logger LOGGER = Logger.getLogger(SimpleHttpServerProviderTest.class.getName());
+
+    private static final int DEFAULT_PORT = 0;
+
+    private static final int getPort() {
+        final String value = AccessController
+                .doPrivileged(PropertiesHelper.getSystemProperty("jersey.config.test.container.port"));
+        if (value != null) {
+            try {
+                final int i = Integer.parseInt(value);
+                if (i < 0) {
+                    throw new NumberFormatException("Value is negative.");
+                }
+                return i;
+            } catch (final NumberFormatException e) {
+                LOGGER.log(Level.CONFIG,
+                        "Value of 'jersey.config.test.container.port'"
+                                + " property is not a valid non-negative integer [" + value + "]."
+                                + " Reverting to default [" + DEFAULT_PORT + "].",
+                        e);
+            }
+        }
+
+        return DEFAULT_PORT;
+    }
+
+    @Test
+    @Timeout(value = 15000L, unit = TimeUnit.MILLISECONDS)
+    public final void shouldScanFreePort() throws InterruptedException, ExecutionException {
+        // given
+        final WebServerProvider webServerProvider = new SimpleHttpServerProvider();
+        final Application application = new Application();
+        final SeBootstrap.Configuration configuration = configuration(SeBootstrap.Configuration.FREE_PORT, TRUE);
+
+        // when
+        final WebServer webServer = webServerProvider.createServer(WebServer.class, application, configuration);
+
+        // then
+        assertThat(webServer.port(), is(greaterThan(0)));
+    }
+
+    private SeBootstrap.Configuration configuration(int port, boolean autoStart) {
+        return (SeBootstrap.Configuration) name -> {
+            switch (name) {
+                case SeBootstrap.Configuration.PROTOCOL:
+                    return "HTTP";
+                case SeBootstrap.Configuration.HOST:
+                    return "localhost";
+                case SeBootstrap.Configuration.PORT:
+                    return port;
+                case SeBootstrap.Configuration.ROOT_PATH:
+                    return "/";
+                case SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION:
+                    return SSLClientAuthentication.NONE;
+                case SeBootstrap.Configuration.SSL_CONTEXT:
+                    try {
+                        return SSLContext.getDefault();
+                    } catch (final NoSuchAlgorithmException e) {
+                        throw new RuntimeException(e);
+                    }
+                case ServerProperties.WEBSERVER_AUTO_START:
+                    return autoStart;
+                default:
+                    return null;
+            }
+        };
+    }
+
+}
diff --git a/core-client/pom.xml b/core-client/pom.xml
index 10cb8b7..fcd0987 100644
--- a/core-client/pom.xml
+++ b/core-client/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.core</groupId>
@@ -120,8 +120,8 @@
 
         <dependency>
             <!-- not to warn about missing activation -->
-            <groupId>com.sun.activation</groupId>
-            <artifactId>jakarta.activation</artifactId>
+            <groupId>org.eclipse.angus</groupId>
+            <artifactId>angus-activation</artifactId>
             <scope>test</scope>
         </dependency>
 
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java
index 4dca460..b072c1d 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientConfig.java
@@ -331,6 +331,11 @@
         }
 
         @Override
+        public boolean hasProperty(final String name) {
+            return commonConfig.getConfiguration().hasProperty(name);
+        }
+
+        @Override
         public Object getProperty(final String name) {
             return commonConfig.getConfiguration().getProperty(name);
         }
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java
index 64963c6..aa0676b 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java
@@ -467,6 +467,24 @@
     public static final String QUERY_PARAM_STYLE = "jersey.config.client.uri.query.param.style";
 
     /**
+     * <p>
+     *     Most connectors support HOST header value to be used as an SNIHostName. However, the HOST header is restricted in JDK.
+     *     {@code HttpUrlConnector} and {@code JavaNetHttpConnector} need
+     *     to have an extra System Property set to allow HOST header.
+     *     As an option to HOST header, this property allows the HOST name to be pre-set on a Client and does not need to
+     *     be set on each request.
+     * </p>
+     * <p>
+     *     The value MUST be an instance of {@link java.lang.String}.
+     * </p>
+     * <p>
+     *     The name of the configuration property is <tt>{@value}</tt>.
+     * </p>
+     * @since 3.1.2
+     */
+    public static final String SNI_HOST_NAME = "jersey.config.client.sniHostName";
+
+    /**
      * Sets the {@link org.glassfish.jersey.client.spi.ConnectorProvider} class. Overrides the value from META-INF/services.
      *
      * <p>
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientRequest.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientRequest.java
index 992311e..9b0e9c1 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientRequest.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientRequest.java
@@ -139,6 +139,11 @@
     }
 
     @Override
+    public boolean hasProperty(final String name) {
+        return propertiesDelegate.hasProperty(name);
+    }
+
+    @Override
     public Object getProperty(final String name) {
         return propertiesDelegate.getProperty(name);
     }
@@ -229,9 +234,19 @@
         return clientConfig;
     }
 
+    /**
+     * Get the values of an HTTP request header if the header exists on the current request. The returned value will be
+     * a read-only List if the specified header exists or {@code null} if it does not. This is a shortcut for
+     * {@code getRequestHeaders().get(name)}.
+     *
+     * @param name the header name, case insensitive.
+     * @return a read-only list of header values if the specified header exists, otherwise {@code null}.
+     * @throws java.lang.IllegalStateException if called outside the scope of a request.
+     */
     @Override
     public List<String> getRequestHeader(String name) {
-        return HeaderUtils.asStringList(getHeaders().get(name), clientConfig.getConfiguration());
+        final List<Object> values = getHeaders().get(name);
+        return values == null ? null : HeaderUtils.asStringList(values, clientConfig.getConfiguration());
     }
 
     @Override
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/innate/Expect100ContinueUsage.java b/core-client/src/main/java/org/glassfish/jersey/client/innate/Expect100ContinueUsage.java
new file mode 100644
index 0000000..7c45854
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/innate/Expect100ContinueUsage.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.innate;
+
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientRequest;
+import org.glassfish.jersey.client.RequestEntityProcessing;
+
+/**
+ * Utility class to check whether it's possible to send the Expect header within request.
+ */
+public final class Expect100ContinueUsage {
+
+    private Expect100ContinueUsage() {
+        //do not instantiate
+    }
+
+    /**
+     * Checks if usage of the Expect header with 100-Continue value is allowed
+     *
+     * @param request client's request
+     * @param requestMethod method of the request (GET, POST, PUT etc).
+     * @return true if the Expect header is allowed.
+     */
+    public static boolean isAllowed(ClientRequest request, String requestMethod) {
+
+        long requestLength = request.getLengthLong();
+
+        final RequestEntityProcessing entityProcessing = request.resolveProperty(
+                ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.class);
+
+        final Boolean expectContinueActivated = request.resolveProperty(
+                ClientProperties.EXPECT_100_CONTINUE, Boolean.class);
+        final Long expectContinueSizeThreshold = request.resolveProperty(
+                ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE,
+                ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE);
+
+        final boolean allowStreaming = requestLength > expectContinueSizeThreshold
+                || entityProcessing == RequestEntityProcessing.CHUNKED;
+
+        return !(!Boolean.TRUE.equals(expectContinueActivated)
+                || !("POST".equals(requestMethod) || "PUT".equals(requestMethod))
+                || !allowStreaming
+        );
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SSLParamConfigurator.java b/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SSLParamConfigurator.java
index 33ef0b6..cb32a5c 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SSLParamConfigurator.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SSLParamConfigurator.java
@@ -16,18 +16,25 @@
 
 package org.glassfish.jersey.client.innate.http;
 
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.HttpHeaders;
+import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.ClientRequest;
 
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLSocket;
 import jakarta.ws.rs.core.UriBuilder;
+import org.glassfish.jersey.internal.PropertiesResolver;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+
 import java.net.InetAddress;
 import java.net.URI;
 import java.net.UnknownHostException;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Properties;
 
 /**
  * A unified routines to configure {@link SSLParameters}.
@@ -35,27 +42,36 @@
  */
 public final class SSLParamConfigurator {
     private final URI uri;
-    private final Map<String, List<Object>> httpHeaders;
     private final Optional<SniConfigurator> sniConfigurator;
 
     /**
      * Builder of the {@link SSLParamConfigurator} instance.
      */
     public static final class Builder {
-        private ClientRequest clientRequest;
-        private URI uri;
-        private Map<String, List<Object>> httpHeaders;
+        private URI uri = null;
+        private String sniHostNameHeader = null;
+        private String sniHostNameProperty = null;
         private boolean setAlways = false;
 
         /**
-         * Sets the {@link ClientRequest} instance.
+         * Sets the SNIHostName and {@link URI} from the {@link ClientRequest} instance.
          * @param clientRequest the {@link ClientRequest}
          * @return the builder instance
          */
         public Builder request(ClientRequest clientRequest) {
-            this.clientRequest = clientRequest;
-            this.httpHeaders = null;
-            this.uri = null;
+            this.sniHostNameHeader = getSniHostNameHeader(clientRequest.getHeaders());
+            this.sniHostNameProperty = clientRequest.resolveProperty(ClientProperties.SNI_HOST_NAME, String.class);
+            this.uri = clientRequest.getUri();
+            return this;
+        }
+
+        /**
+         * Sets the SNIHostName from the {@link Configuration} instance.
+         * @param configuration the {@link Configuration}
+         * @return the builder instance
+         */
+        public Builder configuration(Configuration configuration) {
+            this.sniHostNameProperty = (String) configuration.getProperty(ClientProperties.SNI_HOST_NAME);
             return this;
         }
 
@@ -65,7 +81,6 @@
          * @return the builder instance
          */
         public Builder uri(URI uri) {
-            this.clientRequest = null;
             this.uri = uri;
             return this;
         }
@@ -76,8 +91,7 @@
          * @return the builder instance
          */
         public Builder headers(Map<String, List<Object>> httpHeaders) {
-            this.clientRequest = null;
-            this.httpHeaders = httpHeaders;
+            this.sniHostNameHeader = getSniHostNameHeader(httpHeaders);
             return this;
         }
 
@@ -99,12 +113,31 @@
         public SSLParamConfigurator build() {
             return new SSLParamConfigurator(this);
         }
+
+        private static String getSniHostNameHeader(Map<String, List<Object>> httpHeaders) {
+            List<Object> hostHeaders = httpHeaders.get(HttpHeaders.HOST);
+            if (hostHeaders == null || hostHeaders.get(0) == null) {
+                return null;
+            }
+
+            final String hostHeader = hostHeaders.get(0).toString();
+            final String trimmedHeader;
+            if (hostHeader != null) {
+                int index = hostHeader.indexOf(':'); // RFC 7230  Host = uri-host [ ":" port ] ;
+                final String trimmedHeader0 = index != -1 ? hostHeader.substring(0, index).trim() : hostHeader.trim();
+                trimmedHeader = trimmedHeader0.isEmpty() ? hostHeader : trimmedHeader0;
+            } else {
+                trimmedHeader = null;
+            }
+
+            return trimmedHeader;
+        }
     }
 
     private SSLParamConfigurator(SSLParamConfigurator.Builder builder) {
-        this.uri = builder.clientRequest != null ? builder.clientRequest.getUri() : builder.uri;
-        this.httpHeaders = builder.clientRequest != null ? builder.clientRequest.getHeaders() : builder.httpHeaders;
-        sniConfigurator = SniConfigurator.createWhenHostHeader(uri, httpHeaders, builder.setAlways);
+        String sniHostName = builder.sniHostNameHeader == null ? builder.sniHostNameProperty : builder.sniHostNameHeader;
+        uri = builder.uri;
+        sniConfigurator = SniConfigurator.createWhenHostHeader(uri, sniHostName, builder.setAlways);
     }
 
     /**
@@ -178,6 +211,15 @@
     }
 
     /**
+     * Set {@link javax.net.ssl.SNIServerName} for the {@link SSLParameters} when SNI should be used
+     * (i.e. {@link jakarta.ws.rs.core.HttpHeaders#HOST} differs from HTTP request host name)
+     * @param parameters the {@link SSLParameters} to be set
+     */
+    public void setSNIServerName(SSLParameters parameters) {
+        sniConfigurator.ifPresent(sni -> sni.updateSSLParameters(parameters));
+    }
+
+    /**
      * Set setEndpointIdentificationAlgorithm to HTTPS. This is to prevent man-in-the-middle attacks.
      * @param sslEngine the {@link SSLEngine} the algorithm is set for.
      * @see SSLParameters#setEndpointIdentificationAlgorithm(String)
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SniConfigurator.java b/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SniConfigurator.java
index 596c587..9e766f5 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SniConfigurator.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SniConfigurator.java
@@ -27,7 +27,6 @@
 import java.net.URI;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 import java.util.logging.Logger;
 
@@ -53,32 +52,24 @@
     /**
      * Create ClientSNI when {@link HttpHeaders#HOST} is set different from the request URI host (or {@code whenDiffer}.is false).
      * @param hostUri the Uri of the HTTP request
-     * @param headers the HttpHeaders
+     * @param sniHostName the SniHostName either from HttpHeaders or the
+     *      {@link org.glassfish.jersey.client.ClientProperties#SNI_HOST_NAME} property from Configuration object.
      * @param whenDiffer create {@SniConfigurator only when different from the request URI host}
      * @return ClientSNI or empty when {@link HttpHeaders#HOST}
      */
-    static Optional<SniConfigurator> createWhenHostHeader(URI hostUri, Map<String, List<Object>> headers, boolean whenDiffer) {
-        List<Object> hostHeaders = headers.get(HttpHeaders.HOST);
-        if (hostHeaders == null || hostHeaders.get(0) == null) {
+    static Optional<SniConfigurator> createWhenHostHeader(URI hostUri, String sniHostName, boolean whenDiffer) {
+        if (sniHostName == null) {
             return Optional.empty();
         }
 
-        final String hostHeader = hostHeaders.get(0).toString();
-        final String trimmedHeader;
-        if (hostHeader != null) {
-            int index = hostHeader.indexOf(':'); // RFC 7230  Host = uri-host [ ":" port ] ;
-            final String trimmedHeader0 = index != -1 ? hostHeader.substring(0, index).trim() : hostHeader.trim();
-            trimmedHeader = trimmedHeader0.isEmpty() ? hostHeader : trimmedHeader0;
-        } else {
-            return Optional.empty();
+        if (hostUri != null) {
+            final String hostUriString = hostUri.getHost();
+            if (!whenDiffer && hostUriString.equals(sniHostName)) {
+                return Optional.empty();
+            }
         }
 
-        final String hostUriString = hostUri.getHost();
-        if (!whenDiffer && hostUriString.equals(trimmedHeader)) {
-            return Optional.empty();
-        }
-
-        return Optional.of(new SniConfigurator(trimmedHeader));
+        return Optional.of(new SniConfigurator(sniHostName));
     }
 
     /**
@@ -103,7 +94,7 @@
         LOGGER.fine(LocalizationMessages.SNI_ON_SSLSOCKET());
     }
 
-    private SSLParameters updateSSLParameters(SSLParameters sslParameters) {
+    SSLParameters updateSSLParameters(SSLParameters sslParameters) {
         SNIHostName serverName = new SNIHostName(hostName);
         List<SNIServerName> serverNames = new LinkedList<>();
         serverNames.add(serverName);
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlExpect100ContinueConnectorExtension.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlExpect100ContinueConnectorExtension.java
index 2e727eb..ad13830 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlExpect100ContinueConnectorExtension.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlExpect100ContinueConnectorExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,7 +18,7 @@
 
 import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.ClientRequest;
-import org.glassfish.jersey.client.RequestEntityProcessing;
+import org.glassfish.jersey.client.innate.Expect100ContinueUsage;
 
 import java.io.IOException;
 import java.net.HttpURLConnection;
@@ -32,26 +32,9 @@
     @Override
     public  void invoke(ClientRequest request, HttpURLConnection uc) {
 
-        final long length = request.getLengthLong();
-        final RequestEntityProcessing entityProcessing = request.resolveProperty(
-                ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.class);
-
-        final Boolean expectContinueActivated = request.resolveProperty(
-                ClientProperties.EXPECT_100_CONTINUE, Boolean.class);
-        final Long expectContinueSizeThreshold = request.resolveProperty(
-                ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE,
-                ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE);
-
-        final boolean allowStreaming = length > expectContinueSizeThreshold
-                || entityProcessing == RequestEntityProcessing.CHUNKED;
-
-        if (!Boolean.TRUE.equals(expectContinueActivated)
-                || !("POST".equals(uc.getRequestMethod()) || "PUT".equals(uc.getRequestMethod()))
-                || !allowStreaming
-        ) {
-            return;
+        if (Expect100ContinueUsage.isAllowed(request, uc.getRequestMethod())) {
+            uc.setRequestProperty("Expect", "100-Continue");
         }
-        uc.setRequestProperty("Expect", "100-Continue");
     }
 
     @Override
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/ClientConfigTest.java b/core-client/src/test/java/org/glassfish/jersey/client/ClientConfigTest.java
index aaa88c9..d2ede28 100644
--- a/core-client/src/test/java/org/glassfish/jersey/client/ClientConfigTest.java
+++ b/core-client/src/test/java/org/glassfish/jersey/client/ClientConfigTest.java
@@ -105,6 +105,13 @@
     }
 
     @Test
+    public void testHasProperty() {
+        ClientConfig instance = new ClientConfig().property("name", "value");
+        assertTrue(instance.hasProperty("name"));
+        assertFalse(instance.hasProperty("other"));
+    }
+
+    @Test
     public void testGetProperty() {
         ClientConfig instance = new ClientConfig().property("name", "value");
         assertEquals("value", instance.getProperty("name"));
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/ClientRequestTest.java b/core-client/src/test/java/org/glassfish/jersey/client/ClientRequestTest.java
index a877f69..1f7de34 100644
--- a/core-client/src/test/java/org/glassfish/jersey/client/ClientRequestTest.java
+++ b/core-client/src/test/java/org/glassfish/jersey/client/ClientRequestTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -93,6 +93,9 @@
         assertFalse(request.getConfiguration().getPropertyNames().contains("name"));
         assertFalse(request.getPropertyNames().contains("name"));
 
+        assertFalse(request.getConfiguration().hasProperty("name"));
+        assertFalse(request.hasProperty("name"));
+
         assertNull(request.getConfiguration().getProperty("name"));
         assertNull(request.getProperty("name"));
 
@@ -110,6 +113,9 @@
         assertTrue(request.getConfiguration().getPropertyNames().contains("name"));
         assertFalse(request.getPropertyNames().contains("name"));
 
+        assertTrue(request.getConfiguration().hasProperty("name"));
+        assertFalse(request.hasProperty("name"));
+
         assertEquals("value-global", request.getConfiguration().getProperty("name"));
         assertNull(request.getProperty("name"));
 
@@ -128,6 +134,9 @@
         assertFalse(request.getConfiguration().getPropertyNames().contains("name"));
         assertTrue(request.getPropertyNames().contains("name"));
 
+        assertFalse(request.getConfiguration().hasProperty("name"));
+        assertTrue(request.hasProperty("name"));
+
         assertNull(request.getConfiguration().getProperty("name"));
         assertEquals("value-request", request.getProperty("name"));
 
@@ -146,6 +155,9 @@
         assertTrue(request.getConfiguration().getPropertyNames().contains("name"));
         assertTrue(request.getPropertyNames().contains("name"));
 
+        assertTrue(request.getConfiguration().hasProperty("name"));
+        assertTrue(request.hasProperty("name"));
+
         assertEquals("value-global", request.getConfiguration().getProperty("name"));
         assertEquals("value-request", request.getProperty("name"));
 
diff --git a/core-common/pom.xml b/core-common/pom.xml
index 58799ec..3e5eae4 100644
--- a/core-common/pom.xml
+++ b/core-common/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.core</groupId>
@@ -216,8 +216,8 @@
             <artifactId>jakarta.annotation-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.sun.activation</groupId>
-            <artifactId>jakarta.activation</artifactId>
+            <groupId>org.eclipse.angus</groupId>
+            <artifactId>angus-activation</artifactId>
             <scope>provided</scope>
             <optional>true</optional>
         </dependency>
@@ -254,446 +254,6 @@
 
     <profiles>
         <profile>
-            <id>jdk8</id>
-            <activation>
-                <jdk>1.8</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>src/main/jsr166</source>
-                                        <source>src/main/java8</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <artifactId>maven-antrun-plugin</artifactId>
-                        <dependencies>
-                            <dependency>
-                                <groupId>com.sun</groupId>
-                                <artifactId>tools</artifactId>
-                                <version>1.8.0</version>
-                                <scope>system</scope>
-                                <systemPath>${java.home}/../lib/tools.jar</systemPath>
-                            </dependency>
-                        </dependencies>
-                        <executions>
-                            <execution>
-                                <phase>validate</phase>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                                <configuration>
-                                    <target>
-                                        <echo>Building for JDK8</echo>
-                                    </target>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <!-- need to compile this to be able to compile-2-java8 -->
-                                <id>compile-1-jsr166</id>
-                                <phase>process-resources</phase>
-                                <configuration>
-                                    <target>
-                                        <javac srcdir="${jsr166.sourceDirectory}" destdir="${project.build.outputDirectory}"
-                                               classpath="${project.build.outputDirectory}" includeantruntime="false" />
-                                    </target>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                            </execution>
-                            <execution>
-                                <!-- Compile these files with jdk 8 and put them aside to be included in multirelase jar -->
-                                <!-- Multi-release jar is built by jdk 11+, but these classes are buildable by jdk 8 only -->
-                                <id>compile-2-java8</id>
-                                <phase>process-resources</phase>
-                                <configuration>
-                                    <target>
-                                        <mkdir dir="${java8.build.outputDirectory}" />
-                                        <javac srcdir="${java8.sourceDirectory}" destdir="${java8.build.outputDirectory}"
-                                               classpath="${project.build.outputDirectory}" includeantruntime="false" />
-                                    </target>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-
-        <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-antrun-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>validate</phase>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                                <configuration>
-                                    <target>
-                                        <echo>Building for JDK 11+</echo>
-                                    </target>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>compile-1-jsr166</id>
-                                <phase>process-resources</phase>
-                                <configuration>
-                                    <target>
-                                        <javac srcdir="${jsr166.sourceDirectory}" destdir="${project.build.outputDirectory}"
-                                               classpath="${project.build.outputDirectory}" includeantruntime="false" />
-                                    </target>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                            </execution>
-                            <execution>
-                                <!-- build these java 11 specific classes to be put to META-INF/versions/11 later -->
-                                <id>compile-2-java11</id>
-                                <phase>process-resources</phase>
-                                <configuration>
-                                    <target>
-                                        <mkdir dir="${java11.build.outputDirectory}" />
-                                        <javac srcdir="${java11.sourceDirectory}" destdir="${java11.build.outputDirectory}"
-                                               classpath="${project.build.outputDirectory}" includeantruntime="false" release="11" />
-                                    </target>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <id>compile-0-addsources</id>
-                                <phase>process-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>src/main/jsr166</source>
-                                        <source>src/main/java11</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <id>default-compile</id>
-                                <configuration>
-                                    <!-- compile everything to ensure module-info contains right entries -->
-                                    <release>11</release>
-                                </configuration>
-                            </execution>
-                       </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>copyJDK11FilesToMultiReleaseJar</id>
-            <activation>
-                <file>
-                    <!-- ${java11.build.outputDirectory} does not work here -->
-                    <exists>target/classes-java11/org/glassfish/jersey/internal/jsr166/SubmissionPublisher.class</exists>
-                </file>
-                <jdk>1.8</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.felix</groupId>
-                        <artifactId>maven-bundle-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <extensions>true</extensions>
-                        <configuration>
-                            <instructions>
-                                <Multi-Release>true</Multi-Release>
-                            </instructions>
-                        </configuration>
-                    </plugin>
-                    <plugin>
-                        <artifactId>maven-clean-plugin</artifactId>
-                        <!-- only one file set per execution works -->
-                        <executions>
-                            <execution>
-                                <id>remove-jdk11-generated-sources</id>
-                                <phase>initialize</phase>
-                                <goals>
-                                    <goal>clean</goal>
-                                </goals>
-                                <configuration>
-                                    <excludeDefaultDirectories>true</excludeDefaultDirectories>
-                                    <filesets>
-                                        <fileset>
-                                            <directory>${project.build.directory}/generated-sources</directory>
-                                        </fileset>
-                                    </filesets>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>remove-jdk11-classes</id>
-                                <phase>initialize</phase>
-                                <goals>
-                                    <goal>clean</goal>
-                                </goals>
-                                <configuration>
-                                    <excludeDefaultDirectories>true</excludeDefaultDirectories>
-                                    <filesets>
-                                        <fileset>
-                                            <directory>${project.build.directory}/classes</directory>
-                                        </fileset>
-                                    </filesets>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-resources-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <executions>
-                            <execution>
-                                <id>copy-jdk11-sources</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${project.build.directory}/generated-sources/rsrc-gen/META-INF/versions/11/org/glassfish/jersey/internal/jsr166</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>${java11.sourceDirectory}/org/glassfish/jersey/internal/jsr166</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>copy-jdk11-classes-to-meta-inf</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${project.build.outputDirectory}/META-INF/versions/11</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>${java11.build.outputDirectory}</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>copyJDK8FilesToMultiReleaseJar</id>
-            <activation>
-                <file>
-                    <!-- ${java8.build.outputDirectory} does not work here -->
-                    <exists>target/classes-java8/org/glassfish/jersey/internal/jsr166/UnsafeAccessor.class</exists>
-                </file>
-                <jdk>[11,)</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.felix</groupId>
-                        <artifactId>maven-bundle-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <extensions>true</extensions>
-                        <configuration>
-                            <instructions>
-                                <Multi-Release>true</Multi-Release>
-                            </instructions>
-                        </configuration>
-                    </plugin>
-                    <plugin>
-                        <artifactId>maven-clean-plugin</artifactId>
-                        <!-- only one file set per execution works -->
-                        <executions>
-                            <execution>
-                                <id>remove-jdk11-jsr166-sources</id>
-                                <phase>initialize</phase>
-                                <goals>
-                                    <goal>clean</goal>
-                                </goals>
-                                <configuration>
-                                    <excludeDefaultDirectories>true</excludeDefaultDirectories>
-                                    <filesets>
-                                        <fileset>
-                                            <directory>${project.build.directory}/generated-sources/rsrc-gen/org/glassfish/jersey/internal/jsr166</directory>
-                                        </fileset>
-                                    </filesets>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>remove-jdk11-jsr166-META-INF-sources</id>
-                                <phase>initialize</phase>
-                                <goals>
-                                    <goal>clean</goal>
-                                </goals>
-                                <configuration>
-                                    <excludeDefaultDirectories>true</excludeDefaultDirectories>
-                                    <filesets>
-                                        <fileset>
-                                            <directory>${project.build.directory}/generated-sources/rsrc-gen/META-INF</directory>
-                                        </fileset>
-                                    </filesets>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>remove-jdk11-jsr166-classes</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>clean</goal>
-                                </goals>
-                                <configuration>
-                                    <excludeDefaultDirectories>true</excludeDefaultDirectories>
-                                    <filesets>
-                                        <fileset>
-                                            <directory>${project.build.outputDirectory}/org/glassfish/jersey/internal/jsr166</directory>
-                                            <includes>
-                                                <include>*.class</include>
-                                            </includes>
-                                            <excludes>
-                                                <exclude>Flow*.class</exclude>
-                                                <exclude>SubmittableFlowPublisher.class</exclude>
-                                                <exclude>package-info.class</exclude>
-                                            </excludes>
-                                        </fileset>
-                                    </filesets>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-resources-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <executions>
-                            <execution>
-                                <id>copy-jdk8-classes-ouputDirectory</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${project.build.outputDirectory}</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>${java8.build.outputDirectory}</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>copy-jdk8-sources</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${project.build.directory}/generated-sources/rsrc-gen/org/glassfish/jersey/internal/jsr166</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>${java8.sourceDirectory}/org/glassfish/jersey/internal/jsr166</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>copy-jdk11-sources</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${project.build.directory}/generated-sources/rsrc-gen/META-INF/versions/11/org/glassfish/jersey/internal/jsr166</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>${java11.sourceDirectory}/org/glassfish/jersey/internal/jsr166</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                            <execution>
-                                <id>copy-jdk11-classes-to-meta-inf</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${project.build.outputDirectory}/META-INF/versions/11</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>${java11.build.outputDirectory}</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-source-plugin</artifactId>
-                        <version>3.0.1</version>
-                        <executions>
-                            <execution>
-                                <id>attach-sources</id>
-                                <phase>package</phase>
-                                <goals>
-                                    <goal>jar-no-fork</goal>
-                                </goals>
-                                <configuration>
-                                    <excludes>
-                                        <exclude>org/glassfish/jersey/internal/jsr166/Jdk9SubmissionPublisher.java</exclude>
-                                    </excludes>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-
-        <profile>
             <id>securityOff</id>
             <properties>
                <surefire.security.argline />
@@ -733,11 +293,6 @@
 
     <properties>
         <surefire.security.argline>-Djava.security.manager -Djava.security.policy=${project.build.directory}/test-classes/surefire.policy</surefire.security.argline>
-        <jsr166.sourceDirectory>${project.basedir}/src/main/jsr166</jsr166.sourceDirectory>
-        <java8.build.outputDirectory>${project.build.directory}/classes-java8</java8.build.outputDirectory>
-        <java8.sourceDirectory>${project.basedir}/src/main/java8</java8.sourceDirectory>
-        <java11.build.outputDirectory>${project.build.directory}/classes-java11</java11.build.outputDirectory>
-        <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
     </properties>
 
 </project>
diff --git a/test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java b/core-common/src/main/java/org/glassfish/jersey/innate/package-info.java
similarity index 76%
copy from test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java
copy to core-common/src/main/java/org/glassfish/jersey/innate/package-info.java
index cd4980f..b0648e7 100644
--- a/test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java
+++ b/core-common/src/main/java/org/glassfish/jersey/innate/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,6 +15,6 @@
  */
 
 /**
- * Jersey test framework for Jetty HTTP/2 Container.
+ * Jersey innate packages. The innate packages will not be opened by JPMS outside of Jersey.
  */
-package org.glassfish.jersey.test.jetty.http2;
+package org.glassfish.jersey.innate;
diff --git a/core-common/src/main/java/org/glassfish/jersey/innate/spi/EntityPartBuilderProvider.java b/core-common/src/main/java/org/glassfish/jersey/innate/spi/EntityPartBuilderProvider.java
new file mode 100644
index 0000000..606e212
--- /dev/null
+++ b/core-common/src/main/java/org/glassfish/jersey/innate/spi/EntityPartBuilderProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.innate.spi;
+
+import jakarta.ws.rs.core.EntityPart;
+
+/**
+ * Jersey extension of provider of EntityPart.Builder.
+ * A service meant to be implemented solely by Jersey.
+ *
+ * @since 3.1.0
+ */
+public interface EntityPartBuilderProvider {
+
+    /**
+     * @param partName name of the part to create within the multipart entity.
+     * @return {@link EntityPart.Builder} for building new {@link EntityPart} instances.
+     */
+    public EntityPart.Builder withName(String partName);
+}
diff --git a/test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java b/core-common/src/main/java/org/glassfish/jersey/innate/spi/package-info.java
similarity index 77%
copy from test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java
copy to core-common/src/main/java/org/glassfish/jersey/innate/spi/package-info.java
index cd4980f..3d70312 100644
--- a/test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java
+++ b/core-common/src/main/java/org/glassfish/jersey/innate/spi/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,6 +15,6 @@
  */
 
 /**
- * Jersey test framework for Jetty HTTP/2 Container.
+ * Common Jersey innate SPI classes. The innate package will not be opened by JPMS.
  */
-package org.glassfish.jersey.test.jetty.http2;
+package org.glassfish.jersey.innate.spi;
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/AbstractRuntimeDelegate.java b/core-common/src/main/java/org/glassfish/jersey/internal/AbstractRuntimeDelegate.java
index aa439db..39940fb 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/AbstractRuntimeDelegate.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/AbstractRuntimeDelegate.java
@@ -25,14 +25,20 @@
 import jakarta.ws.rs.core.CacheControl;
 import jakarta.ws.rs.core.Configuration;
 import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.EntityPart;
 import jakarta.ws.rs.core.EntityTag;
 import jakarta.ws.rs.core.Link;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.NewCookie;
 import jakarta.ws.rs.core.Response.ResponseBuilder;
 import jakarta.ws.rs.core.UriBuilder;
+import jakarta.ws.rs.ext.ParamConverter;
 import jakarta.ws.rs.ext.RuntimeDelegate;
 
+import org.glassfish.jersey.innate.spi.EntityPartBuilderProvider;
+import org.glassfish.jersey.internal.util.collection.LazyValue;
+import org.glassfish.jersey.internal.util.collection.Value;
+import org.glassfish.jersey.internal.util.collection.Values;
 import org.glassfish.jersey.message.internal.JerseyLink;
 import org.glassfish.jersey.message.internal.OutboundJaxrsResponse;
 import org.glassfish.jersey.message.internal.OutboundMessageContext;
@@ -50,6 +56,8 @@
 
     private final Set<HeaderDelegateProvider> hps;
     private final Map<Class<?>, HeaderDelegate<?>> map;
+    private LazyValue<EntityPartBuilderProvider> entityPartBuilderProvider = Values.lazy(
+            (Value<EntityPartBuilderProvider>) () -> findEntityPartBuilderProvider());
 
     /**
      * Initialization constructor. The injection manager will be shut down.
@@ -117,4 +125,24 @@
 
         return null;
     }
+
+    @Override
+    public EntityPart.Builder createEntityPartBuilder(String partName) throws IllegalArgumentException {
+        return entityPartBuilderProvider.get().withName(partName);
+    }
+
+    /**
+     * Obtain a {@code RuntimeDelegate} instance using the method described in {@link #getInstance}.
+     *
+     * @return an instance of {@code RuntimeDelegate}.
+     */
+    private static EntityPartBuilderProvider findEntityPartBuilderProvider() {
+        for (final EntityPartBuilderProvider entityPartBuilder : ServiceFinder.find(EntityPartBuilderProvider.class)) {
+            if (entityPartBuilder != null) {
+                return entityPartBuilder;
+            }
+        }
+
+        throw new IllegalArgumentException(LocalizationMessages.NO_ENTITYPART_BUILDER_FOUND());
+    }
 }
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/DynamicFeatureConfigurator.java b/core-common/src/main/java/org/glassfish/jersey/internal/DynamicFeatureConfigurator.java
index 65ac48b..12eb78b 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/DynamicFeatureConfigurator.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/DynamicFeatureConfigurator.java
@@ -23,7 +23,6 @@
 import jakarta.ws.rs.RuntimeType;
 import jakarta.ws.rs.container.DynamicFeature;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/ExceptionMapperFactory.java b/core-common/src/main/java/org/glassfish/jersey/internal/ExceptionMapperFactory.java
index 4af235b..7c51af4 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/ExceptionMapperFactory.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/ExceptionMapperFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -180,6 +180,11 @@
             for (ServiceHolder<ExceptionMapper> mapperHandle: mapperHandles) {
                 ExceptionMapper mapper = mapperHandle.getInstance();
 
+                // the default exception mapper is processed by the ServerRuntime
+                if ("org.glassfish.jersey.server.DefaultExceptionMapper".equals(mapper.getClass().getName())) {
+                    continue;
+                }
+
                 if (Proxy.isProxyClass(mapper.getClass())) {
                     SortedSet<Class<? extends ExceptionMapper>> mapperTypes =
                             new TreeSet<>((o1, o2) -> o1.isAssignableFrom(o2) ? -1 : 1);
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/MapPropertiesDelegate.java b/core-common/src/main/java/org/glassfish/jersey/internal/MapPropertiesDelegate.java
index aed1cfe..3cce5bd 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/MapPropertiesDelegate.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/MapPropertiesDelegate.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -64,6 +64,11 @@
     }
 
     @Override
+    public boolean hasProperty(final String name) {
+        return store.containsKey(name);
+    }
+
+    @Override
     public Object getProperty(String name) {
         return store.get(name);
     }
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/PropertiesDelegate.java b/core-common/src/main/java/org/glassfish/jersey/internal/PropertiesDelegate.java
index 70833b9..3413de0 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/PropertiesDelegate.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/PropertiesDelegate.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -43,6 +43,22 @@
      */
     public Object getProperty(String name);
 
+    /**
+     * Returns {@code true} if the property with the given name registered in the current request/response
+     * exchange context, or {@code false} if there is no property by that name.
+     * <p>
+     * Use the {@link #getProperty} method with a property name to get the value of
+     * a property.
+     * </p>
+     *
+     * @return {@code true} if a property matching the given name exists, or
+     *         {@code false} otherwise.
+     * @see #getProperty
+     * @since 3.1.0
+     */
+    public default boolean hasProperty(String name) {
+        return getProperty(name) != null;
+    }
 
     /**
      * Returns an immutable {@link java.util.Collection collection} containing the property
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateDecorator.java b/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateDecorator.java
index 5f954ba..b21616d 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateDecorator.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateDecorator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,16 +19,20 @@
 import org.glassfish.jersey.internal.util.PropertiesHelper;
 import org.glassfish.jersey.spi.HeaderDelegateProvider;
 
+import jakarta.ws.rs.SeBootstrap;
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.EntityPart;
 import jakarta.ws.rs.core.Link;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.UriBuilder;
 import jakarta.ws.rs.core.Variant;
 import jakarta.ws.rs.ext.RuntimeDelegate;
+
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.CompletionStage;
 
 /**
  * RuntimeDelegate Decorator that changes behaviour due to provided runtime information.
@@ -102,6 +106,27 @@
             return runtimeDelegate.createLinkBuilder();
         }
 
+        @Override
+        public SeBootstrap.Configuration.Builder createConfigurationBuilder() {
+            return runtimeDelegate.createConfigurationBuilder();
+        }
+
+        @Override
+        public CompletionStage<SeBootstrap.Instance> bootstrap(Application application, SeBootstrap.Configuration configuration) {
+            return runtimeDelegate.bootstrap(application, configuration);
+        }
+
+        @Override
+        public CompletionStage<SeBootstrap.Instance> bootstrap(Class<? extends Application> applicationClass,
+                                                               SeBootstrap.Configuration configuration) {
+            return runtimeDelegate.bootstrap(applicationClass, configuration);
+        }
+
+        @Override
+        public EntityPart.Builder createEntityPartBuilder(String partName) throws IllegalArgumentException {
+            return runtimeDelegate.createEntityPartBuilder(partName);
+        }
+
         private <T> HeaderDelegate<T> _createHeaderDelegate(final Class<T> type) {
             for (final HeaderDelegateProvider hp : headerDelegateProviders) {
                 if (hp.supports(type)) {
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateImpl.java b/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateImpl.java
index 80dac78..89e7089 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateImpl.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/RuntimeDelegateImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,11 +16,16 @@
 
 package org.glassfish.jersey.internal;
 
+import jakarta.ws.rs.SeBootstrap;
 import jakarta.ws.rs.core.Application;
 
+import jakarta.ws.rs.core.EntityPart;
 import jakarta.ws.rs.ext.RuntimeDelegate;
 import org.glassfish.jersey.message.internal.MessagingBinders;
 
+import java.util.Optional;
+import java.util.concurrent.CompletionStage;
+
 /**
  * Default implementation of JAX-RS {@link jakarta.ws.rs.ext.RuntimeDelegate}.
  * The {@link jakarta.ws.rs.ext.RuntimeDelegate} class looks for the implementations registered
@@ -42,13 +47,49 @@
     public <T> T createEndpoint(Application application, Class<T> endpointType)
             throws IllegalArgumentException, UnsupportedOperationException {
 
-        // TODO : Do we need multiple RuntimeDelegates?
+        final RuntimeDelegate runtimeDelegate = findServerDelegate();
+        if (runtimeDelegate != null) {
+            return runtimeDelegate.createEndpoint(application, endpointType);
+        }
+        throw new UnsupportedOperationException(LocalizationMessages.NO_CONTAINER_AVAILABLE());
+    }
+
+    @Override
+    public SeBootstrap.Configuration.Builder createConfigurationBuilder() {
+        final RuntimeDelegate runtimeDelegate = findServerDelegate();
+        if (runtimeDelegate != null) {
+            return runtimeDelegate.createConfigurationBuilder();
+        }
+        throw new UnsupportedOperationException(LocalizationMessages.NO_CONTAINER_AVAILABLE());
+    }
+
+    @Override
+    public CompletionStage<SeBootstrap.Instance> bootstrap(Application application, SeBootstrap.Configuration configuration) {
+        final RuntimeDelegate runtimeDelegate = findServerDelegate();
+        if (runtimeDelegate != null) {
+            return runtimeDelegate.bootstrap(application, configuration);
+        }
+        throw new UnsupportedOperationException(LocalizationMessages.NO_CONTAINER_AVAILABLE());
+    }
+
+    @Override
+    public CompletionStage<SeBootstrap.Instance> bootstrap(Class<? extends Application> applicationClass,
+                                                           SeBootstrap.Configuration configuration) {
+        final RuntimeDelegate runtimeDelegate = findServerDelegate();
+        if (runtimeDelegate != null) {
+            return runtimeDelegate.bootstrap(applicationClass, configuration);
+        }
+        throw new UnsupportedOperationException(LocalizationMessages.NO_CONTAINER_AVAILABLE());
+    }
+
+    // TODO : Do we need multiple RuntimeDelegates?
+    private RuntimeDelegate findServerDelegate() {
         for (RuntimeDelegate delegate : ServiceFinder.find(RuntimeDelegate.class)) {
             // try to find runtime delegate from core-server
             if (delegate.getClass() != RuntimeDelegateImpl.class) {
-                return delegate.createEndpoint(application, endpointType);
+                return delegate;
             }
         }
-        throw new UnsupportedOperationException(LocalizationMessages.NO_CONTAINER_AVAILABLE());
+        return null;
     }
 }
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java b/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java
index 13a4baf..23b127a 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/config/SystemPropertiesConfigurationModel.java
@@ -86,7 +86,7 @@
     }
     @Override
     public <T> Optional<T> getOptionalProperty(String name, Class<T> clazz) {
-        return Optional.of(as(name, clazz));
+        return Optional.ofNullable(as(name, clazz));
     }
 
     @Override
@@ -230,9 +230,4 @@
     public Set<Object> getInstances() {
         return null;
     }
-
-    // Jersey 2.x
-    private boolean hasProperty(String name) {
-        return getProperty(name) != null;
-    }
 }
\ No newline at end of file
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
index 0a9aaba..5798695 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
@@ -17,11 +17,15 @@
 
 package org.glassfish.jersey.internal.inject;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
 import java.security.AccessController;
 import java.text.ParseException;
 import java.util.Date;
@@ -300,6 +304,39 @@
     }
 
     /**
+     * Provider of {@link ParamConverter param converter} that convert the supplied string into a Java
+     * {@link InputStream} instance.
+     */
+    public static class InputStreamProvider implements ParamConverterProvider {
+
+        @Override
+        public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
+            return rawType != InputStream.class ? null : new ParamConverter<T>() {
+
+                @Override
+                public T fromString(String value) {
+                    if (value == null) {
+                        throw new IllegalArgumentException(LocalizationMessages.METHOD_PARAMETER_CANNOT_BE_NULL("value"));
+                    }
+                    return rawType.cast(new ByteArrayInputStream(value.getBytes(StandardCharsets.UTF_8)));
+                }
+
+                @Override
+                public String toString(T value) {
+                    if (value == null) {
+                        throw new IllegalArgumentException(LocalizationMessages.METHOD_PARAMETER_CANNOT_BE_NULL("value"));
+                    }
+                    try {
+                        return new String(((InputStream) value).readAllBytes());
+                    } catch (IOException ioe) {
+                        throw new ExtractorException(ioe);
+                    }
+                }
+            };
+        }
+    }
+
+    /**
      * Provider of {@link ParamConverter param converter} that produce the Optional instance
      * by invoking {@link ParamConverterProvider}.
      */
@@ -466,6 +503,7 @@
                     new TypeFromStringEnum(canThrowNull),
                     new TypeValueOf(canThrowNull),
                     new CharacterProvider(canThrowNull),
+                    new InputStreamProvider(),
                     new TypeFromString(canThrowNull),
                     new StringConstructor(canThrowNull),
                     new OptionalCustomProvider(manager, canThrowNull),
diff --git a/core-common/src/main/jsr166/org/glassfish/jersey/internal/jsr166/Flow.java b/core-common/src/main/java/org/glassfish/jersey/internal/jsr166/Flow.java
similarity index 100%
rename from core-common/src/main/jsr166/org/glassfish/jersey/internal/jsr166/Flow.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/jsr166/Flow.java
diff --git a/core-common/src/main/java11/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java b/core-common/src/main/java/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
similarity index 100%
rename from core-common/src/main/java11/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
diff --git a/core-common/src/main/java11/org/glassfish/jersey/internal/jsr166/SubmissionPublisher.java b/core-common/src/main/java/org/glassfish/jersey/internal/jsr166/SubmissionPublisher.java
similarity index 100%
rename from core-common/src/main/java11/org/glassfish/jersey/internal/jsr166/SubmissionPublisher.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/jsr166/SubmissionPublisher.java
diff --git a/core-common/src/main/java11/org/glassfish/jersey/internal/jsr166/SubmissionPublisherFactory.java b/core-common/src/main/java/org/glassfish/jersey/internal/jsr166/SubmissionPublisherFactory.java
similarity index 100%
rename from core-common/src/main/java11/org/glassfish/jersey/internal/jsr166/SubmissionPublisherFactory.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/jsr166/SubmissionPublisherFactory.java
diff --git a/core-common/src/main/jsr166/org/glassfish/jersey/internal/jsr166/SubmittableFlowPublisher.java b/core-common/src/main/java/org/glassfish/jersey/internal/jsr166/SubmittableFlowPublisher.java
similarity index 100%
rename from core-common/src/main/jsr166/org/glassfish/jersey/internal/jsr166/SubmittableFlowPublisher.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/jsr166/SubmittableFlowPublisher.java
diff --git a/core-common/src/main/jsr166/org/glassfish/jersey/internal/jsr166/package-info.java b/core-common/src/main/java/org/glassfish/jersey/internal/jsr166/package-info.java
similarity index 100%
rename from core-common/src/main/jsr166/org/glassfish/jersey/internal/jsr166/package-info.java
rename to core-common/src/main/java/org/glassfish/jersey/internal/jsr166/package-info.java
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/CookiesParser.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/CookiesParser.java
index f8bec0a..bcd7e5f 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/CookiesParser.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/CookiesParser.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -120,6 +120,7 @@
         boolean secure = false;
         boolean httpOnly = false;
         Date expiry = null;
+        NewCookie.SameSite sameSite = null;
 
         public MutableNewCookie(String name, String value) {
             this.name = name;
@@ -127,7 +128,7 @@
         }
 
         public NewCookie getImmutableNewCookie() {
-            return new NewCookie(name, value, path, domain, version, comment, maxAge, expiry, secure, httpOnly);
+            return new NewCookie(name, value, path, domain, version, comment, maxAge, expiry, secure, httpOnly, sameSite);
         }
     }
 
@@ -163,6 +164,8 @@
                     cookie.version = Integer.parseInt(value);
                 } else if (param.startsWith("httponly")) {
                     cookie.httpOnly = true;
+                } else if (param.startsWith("samesite")) {
+                    cookie.sameSite = NewCookie.SameSite.valueOf(value.toUpperCase());
                 }  else if (param.startsWith("expires")) {
                     try {
                         cookie.expiry = HttpDateFormat.readDate(value + ", " + bites[++i]);
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/InterceptorExecutor.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/InterceptorExecutor.java
index 3040bf6..9acc012 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/InterceptorExecutor.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/InterceptorExecutor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -89,6 +89,11 @@
     }
 
     @Override
+    public boolean hasProperty(final String name) {
+        return propertiesDelegate.hasProperty(name);
+    }
+
+    @Override
     public Object getProperty(final String name) {
         return propertiesDelegate.getProperty(name);
     }
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/NewCookieProvider.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/NewCookieProvider.java
index 9c53c74..15ab8d0 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/NewCookieProvider.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/NewCookieProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -73,6 +73,10 @@
         if (cookie.isHttpOnly()) {
             b.append(";HttpOnly");
         }
+        if (cookie.getSameSite() != null) {
+            b.append(";SameSite=");
+            b.append(cookie.getSameSite());
+        }
         if (cookie.getExpiry() != null) {
             b.append(";Expires=");
             b.append(HttpDateFormat.getPreferredDateFormat().format(cookie.getExpiry()));
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/TracingAwarePropertiesDelegate.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/TracingAwarePropertiesDelegate.java
index 97afd68..a75e554 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/TracingAwarePropertiesDelegate.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/TracingAwarePropertiesDelegate.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -59,6 +59,14 @@
     }
 
     @Override
+    public boolean hasProperty(final String name) {
+        if (tracingLogger != null && TracingLogger.PROPERTY_NAME.equals(name)) {
+            return true;
+        }
+        return propertiesDelegate.hasProperty(name);
+    }
+
+    @Override
     public Object getProperty(String name) {
         if (tracingLogger != null && TracingLogger.PROPERTY_NAME.equals(name)) {
             return tracingLogger;
diff --git a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/SubmissionPublisher.java b/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/SubmissionPublisher.java
deleted file mode 100644
index 6eb4cb5..0000000
--- a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/SubmissionPublisher.java
+++ /dev/null
@@ -1,1626 +0,0 @@
-/*
- * Written by Doug Lea with assistance from members of JCP JSR-166
- * Expert Group and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-package org.glassfish.jersey.internal.jsr166;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ForkJoinPool;
-import java.util.concurrent.ForkJoinTask;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.LockSupport;
-import java.util.function.BiConsumer;
-import java.util.function.BiPredicate;
-import java.util.function.Consumer;
-
-/**
- * A {@link Flow.Publisher} that asynchronously issues submitted
- * (non-null) items to current subscribers until it is closed.  Each
- * current subscriber receives newly submitted items in the same order
- * unless drops or exceptions are encountered.  Using a
- * SubmissionPublisher allows item generators to act as compliant <a
- * href="http://www.reactive-streams.org/"> reactive-streams</a>
- * Publishers relying on drop handling and/or blocking for flow
- * control.
- * <p>
- * <p>A SubmissionPublisher uses the {@link Executor} supplied in its
- * constructor for delivery to subscribers. The best choice of
- * Executor depends on expected usage. If the generator(s) of
- * submitted items run in separate threads, and the number of
- * subscribers can be estimated, consider using a {@link
- * Executors#newFixedThreadPool}. Otherwise consider using the
- * default, normally the {@link ForkJoinPool#commonPool}.
- * <p>
- * <p>Buffering allows producers and consumers to transiently operate
- * at different rates.  Each subscriber uses an independent buffer.
- * Buffers are created upon first use and expanded as needed up to the
- * given maximum. (The enforced capacity may be rounded up to the
- * nearest power of two and/or bounded by the largest value supported
- * by this implementation.)  Invocations of {@link
- * Flow.Subscription#request(long) request} do not directly result in
- * buffer expansion, but risk saturation if unfilled requests exceed
- * the maximum capacity.  The default value of {@link
- * Flow#defaultBufferSize()} may provide a useful starting point for
- * choosing a capacity based on expected rates, resources, and usages.
- * <p>
- * <p>Publication methods support different policies about what to do
- * when buffers are saturated. Method {@link #submit(Object) submit}
- * blocks until resources are available. This is simplest, but least
- * responsive.  The {@code offer} methods may drop items (either
- * immediately or with bounded timeout), but provide an opportunity to
- * interpose a handler and then retry.
- * <p>
- * <p>If any Subscriber method throws an exception, its subscription
- * is cancelled.  If a handler is supplied as a constructor argument,
- * it is invoked before cancellation upon an exception in method
- * {@link Flow.Subscriber#onNext onNext}, but exceptions in methods
- * {@link Flow.Subscriber#onSubscribe onSubscribe},
- * {@link Flow.Subscriber#onError(Throwable) onError} and
- * {@link Flow.Subscriber#onComplete() onComplete} are not recorded or
- * handled before cancellation.  If the supplied Executor throws
- * {@link RejectedExecutionException} (or any other RuntimeException
- * or Error) when attempting to execute a task, or a drop handler
- * throws an exception when processing a dropped item, then the
- * exception is rethrown. In these cases, not all subscribers will
- * have been issued the published item. It is usually good practice to
- * {@link #closeExceptionally closeExceptionally} in these cases.
- * <p>
- * <p>Method {@link #consume(Consumer)} simplifies support for a
- * common case in which the only action of a subscriber is to request
- * and process all items using a supplied function.
- * <p>
- * <p>This class may also serve as a convenient base for subclasses
- * that generate items, and use the methods in this class to publish
- * them.  For example here is a class that periodically publishes the
- * items generated from a supplier. (In practice you might add methods
- * to independently start and stop generation, to share Executors
- * among publishers, and so on, or use a SubmissionPublisher as a
- * component rather than a superclass.)
- * <p>
- * <pre> {@code
- * class PeriodicPublisher<T> extends SubmissionPublisher<T> {
- *   final ScheduledFuture<?> periodicTask;
- *   final ScheduledExecutorService scheduler;
- *   PeriodicPublisher(Executor executor, int maxBufferCapacity,
- *                     Supplier<? extends T> supplier,
- *                     long period, TimeUnit unit) {
- *     super(executor, maxBufferCapacity);
- *     scheduler = new ScheduledThreadPoolExecutor(1);
- *     periodicTask = scheduler.scheduleAtFixedRate(
- *       () -> submit(supplier.get()), 0, period, unit);
- *   }
- *   public void close() {
- *     periodicTask.cancel(false);
- *     scheduler.shutdown();
- *     super.close();
- *   }
- * }}</pre>
- * <p>
- * <p>Here is an example of a {@link Flow.Processor} implementation.
- * It uses single-step requests to its publisher for simplicity of
- * illustration. A more adaptive version could monitor flow using the
- * lag estimate returned from {@code submit}, along with other utility
- * methods.
- * <p>
- * <pre> {@code
- * class TransformProcessor<S,T> extends SubmissionPublisher<T>
- *   implements Flow.Processor<S,T> {
- *   final Function<? super S, ? extends T> function;
- *   Flow.Subscription subscription;
- *   TransformProcessor(Executor executor, int maxBufferCapacity,
- *                      Function<? super S, ? extends T> function) {
- *     super(executor, maxBufferCapacity);
- *     this.function = function;
- *   }
- *   public void onSubscribe(Flow.Subscription subscription) {
- *     (this.subscription = subscription).request(1);
- *   }
- *   public void onNext(S item) {
- *     subscription.request(1);
- *     submit(function.apply(item));
- *   }
- *   public void onError(Throwable ex) { closeExceptionally(ex); }
- *   public void onComplete() { close(); }
- * }}</pre>
- *
- * @param <T> the published item type
- * @author Doug Lea
- * @since 9
- */
-public class SubmissionPublisher<T> implements Flow.Publisher<T>, SubmittableFlowPublisher<T>,
-        AutoCloseable {
-    /*
-     * Most mechanics are handled by BufferedSubscription. This class
-     * mainly tracks subscribers and ensures sequentiality, by using
-     * built-in synchronization locks across public methods. (Using
-     * built-in locks works well in the most typical case in which
-     * only one thread submits items).
-     */
-
-    /**
-     * The largest possible power of two array size.
-     */
-    static final int BUFFER_CAPACITY_LIMIT = 1 << 30;
-
-    /**
-     * Round capacity to power of 2, at most limit.
-     */
-    static final int roundCapacity(int cap) {
-        int n = cap - 1;
-        n |= n >>> 1;
-        n |= n >>> 2;
-        n |= n >>> 4;
-        n |= n >>> 8;
-        n |= n >>> 16;
-        return (n <= 0) ? 1 : // at least 1
-                (n >= BUFFER_CAPACITY_LIMIT) ? BUFFER_CAPACITY_LIMIT : n + 1;
-    }
-
-    // default Executor setup; nearly the same as CompletableFuture
-
-    /**
-     * Default executor -- ForkJoinPool.commonPool() unless it cannot
-     * support parallelism.
-     */
-    private static final Executor ASYNC_POOL =
-            (ForkJoinPool.getCommonPoolParallelism() > 1) ? ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
-
-    /**
-     * Fallback if ForkJoinPool.commonPool() cannot support parallelism
-     */
-    private static final class ThreadPerTaskExecutor implements Executor {
-        public void execute(Runnable r) {
-            new Thread(r).start();
-        }
-    }
-
-    /**
-     * Clients (BufferedSubscriptions) are maintained in a linked list
-     * (via their "next" fields). This works well for publish loops.
-     * It requires O(n) traversal to check for duplicate subscribers,
-     * but we expect that subscribing is much less common than
-     * publishing. Unsubscribing occurs only during traversal loops,
-     * when BufferedSubscription methods return negative values
-     * signifying that they have been disabled.  To reduce
-     * head-of-line blocking, submit and offer methods first call
-     * BufferedSubscription.offer on each subscriber, and place
-     * saturated ones in retries list (using nextRetry field), and
-     * retry, possibly blocking or dropping.
-     */
-    BufferedSubscription<T> clients;
-
-    /**
-     * Run status, updated only within locks
-     */
-    volatile boolean closed;
-    /**
-     * If non-null, the exception in closeExceptionally
-     */
-    volatile Throwable closedException;
-
-    // Parameters for constructing BufferedSubscriptions
-    final Executor executor;
-    final BiConsumer<? super Flow.Subscriber<? super T>, ? super Throwable> onNextHandler;
-    final int maxBufferCapacity;
-
-    /**
-     * Creates a new SubmissionPublisher using the given Executor for
-     * async delivery to subscribers, with the given maximum buffer size
-     * for each subscriber, and, if non-null, the given handler invoked
-     * when any Subscriber throws an exception in method {@link
-     * Flow.Subscriber#onNext(Object) onNext}.
-     *
-     * @param executor          the executor to use for async delivery,
-     *                          supporting creation of at least one independent thread
-     * @param maxBufferCapacity the maximum capacity for each
-     *                          subscriber's buffer (the enforced capacity may be rounded up to
-     *                          the nearest power of two and/or bounded by the largest value
-     *                          supported by this implementation; method {@link #getMaxBufferCapacity}
-     *                          returns the actual value)
-     * @param handler           if non-null, procedure to invoke upon exception
-     *                          thrown in method {@code onNext}
-     * @throws NullPointerException     if executor is null
-     * @throws IllegalArgumentException if maxBufferCapacity not
-     *                                  positive
-     */
-    public SubmissionPublisher(Executor executor, int maxBufferCapacity,
-                               BiConsumer<? super Flow.Subscriber<? super T>, ? super Throwable> handler) {
-        if (executor == null) {
-            throw new NullPointerException();
-        }
-        if (maxBufferCapacity <= 0) {
-            throw new IllegalArgumentException("capacity must be positive");
-        }
-        this.executor = executor;
-        this.onNextHandler = handler;
-        this.maxBufferCapacity = roundCapacity(maxBufferCapacity);
-    }
-
-    /**
-     * Creates a new SubmissionPublisher using the given Executor for
-     * async delivery to subscribers, with the given maximum buffer size
-     * for each subscriber, and no handler for Subscriber exceptions in
-     * method {@link Flow.Subscriber#onNext(Object) onNext}.
-     *
-     * @param executor          the executor to use for async delivery,
-     *                          supporting creation of at least one independent thread
-     * @param maxBufferCapacity the maximum capacity for each
-     *                          subscriber's buffer (the enforced capacity may be rounded up to
-     *                          the nearest power of two and/or bounded by the largest value
-     *                          supported by this implementation; method {@link #getMaxBufferCapacity}
-     *                          returns the actual value)
-     * @throws NullPointerException     if executor is null
-     * @throws IllegalArgumentException if maxBufferCapacity not
-     *                                  positive
-     */
-    public SubmissionPublisher(Executor executor, int maxBufferCapacity) {
-        this(executor, maxBufferCapacity, null);
-    }
-
-    /**
-     * Creates a new SubmissionPublisher using the {@link
-     * ForkJoinPool#commonPool()} for async delivery to subscribers
-     * (unless it does not support a parallelism level of at least two,
-     * in which case, a new Thread is created to run each task), with
-     * maximum buffer capacity of {@link Flow#defaultBufferSize}, and no
-     * handler for Subscriber exceptions in method {@link
-     * Flow.Subscriber#onNext(Object) onNext}.
-     */
-    public SubmissionPublisher() {
-        this(ASYNC_POOL, Flow.defaultBufferSize(), null);
-    }
-
-    /**
-     * Adds the given Subscriber unless already subscribed.  If already
-     * subscribed, the Subscriber's {@link
-     * Flow.Subscriber#onError(Throwable) onError} method is invoked on
-     * the existing subscription with an {@link IllegalStateException}.
-     * Otherwise, upon success, the Subscriber's {@link
-     * Flow.Subscriber#onSubscribe onSubscribe} method is invoked
-     * asynchronously with a new {@link Flow.Subscription}.  If {@link
-     * Flow.Subscriber#onSubscribe onSubscribe} throws an exception, the
-     * subscription is cancelled. Otherwise, if this SubmissionPublisher
-     * was closed exceptionally, then the subscriber's {@link
-     * Flow.Subscriber#onError onError} method is invoked with the
-     * corresponding exception, or if closed without exception, the
-     * subscriber's {@link Flow.Subscriber#onComplete() onComplete}
-     * method is invoked.  Subscribers may enable receiving items by
-     * invoking the {@link Flow.Subscription#request(long) request}
-     * method of the new Subscription, and may unsubscribe by invoking
-     * its {@link Flow.Subscription#cancel() cancel} method.
-     *
-     * @param subscriber the subscriber
-     * @throws NullPointerException if subscriber is null
-     */
-    public void subscribe(Flow.Subscriber<? super T> subscriber) {
-        if (subscriber == null) {
-            throw new NullPointerException();
-        }
-        BufferedSubscription<T> subscription =
-                new BufferedSubscription<T>(subscriber, executor,
-                        onNextHandler, maxBufferCapacity);
-        synchronized (this) {
-            for (BufferedSubscription<T> b = clients, pred = null;;) {
-                if (b == null) {
-                    Throwable ex;
-                    subscription.onSubscribe();
-                    if ((ex = closedException) != null) {
-                        subscription.onError(ex);
-                    } else if (closed) {
-                        subscription.onComplete();
-                    } else if (pred == null) {
-                        clients = subscription;
-                    } else {
-                        pred.next = subscription;
-                    }
-                    break;
-                }
-                BufferedSubscription<T> next = b.next;
-                if (b.isDisabled()) { // remove
-                    b.next = null;    // detach
-                    if (pred == null) {
-                        clients = next;
-                    } else {
-                        pred.next = next;
-                    }
-                } else if (subscriber.equals(b.subscriber)) {
-                    b.onError(new IllegalStateException("Duplicate subscribe"));
-                    break;
-                } else {
-                    pred = b;
-                }
-                b = next;
-            }
-        }
-    }
-
-    /**
-     * Publishes the given item to each current subscriber by
-     * asynchronously invoking its {@link Flow.Subscriber#onNext(Object)
-     * onNext} method, blocking uninterruptibly while resources for any
-     * subscriber are unavailable. This method returns an estimate of
-     * the maximum lag (number of items submitted but not yet consumed)
-     * among all current subscribers. This value is at least one
-     * (accounting for this submitted item) if there are any
-     * subscribers, else zero.
-     * <p>
-     * <p>If the Executor for this publisher throws a
-     * RejectedExecutionException (or any other RuntimeException or
-     * Error) when attempting to asynchronously notify subscribers,
-     * then this exception is rethrown, in which case not all
-     * subscribers will have been issued this item.
-     *
-     * @param item the (non-null) item to publish
-     * @return the estimated maximum lag among subscribers
-     * @throws IllegalStateException      if closed
-     * @throws NullPointerException       if item is null
-     * @throws RejectedExecutionException if thrown by Executor
-     */
-    public int submit(T item) {
-        if (item == null) {
-            throw new NullPointerException();
-        }
-        int lag = 0;
-        boolean complete;
-        synchronized (this) {
-            complete = closed;
-            BufferedSubscription<T> b = clients;
-            if (!complete) {
-                BufferedSubscription<T> pred = null, r = null, rtail = null;
-                while (b != null) {
-                    BufferedSubscription<T> next = b.next;
-                    int stat = b.offer(item);
-                    if (stat < 0) {           // disabled
-                        b.next = null;
-                        if (pred == null) {
-                            clients = next;
-                        } else {
-                            pred.next = next;
-                        }
-                    } else {
-                        if (stat > lag) {
-                            lag = stat;
-                        } else if (stat == 0) { // place on retry list
-                            b.nextRetry = null;
-                            if (rtail == null) {
-                                r = b;
-                            } else {
-                                rtail.nextRetry = b;
-                            }
-                            rtail = b;
-                        }
-                        pred = b;
-                    }
-                    b = next;
-                }
-                while (r != null) {
-                    BufferedSubscription<T> nextRetry = r.nextRetry;
-                    r.nextRetry = null;
-                    int stat = r.submit(item);
-                    if (stat > lag) {
-                        lag = stat;
-                    } else if (stat < 0 && clients == r) {
-                        clients = r.next; // postpone internal unsubscribes
-                    }
-                    r = nextRetry;
-                }
-            }
-        }
-        if (complete) {
-            throw new IllegalStateException("Closed");
-        } else {
-            return lag;
-        }
-    }
-
-    /**
-     * Publishes the given item, if possible, to each current subscriber
-     * by asynchronously invoking its {@link
-     * Flow.Subscriber#onNext(Object) onNext} method. The item may be
-     * dropped by one or more subscribers if resource limits are
-     * exceeded, in which case the given handler (if non-null) is
-     * invoked, and if it returns true, retried once.  Other calls to
-     * methods in this class by other threads are blocked while the
-     * handler is invoked.  Unless recovery is assured, options are
-     * usually limited to logging the error and/or issuing an {@link
-     * Flow.Subscriber#onError(Throwable) onError} signal to the
-     * subscriber.
-     * <p>
-     * <p>This method returns a status indicator: If negative, it
-     * represents the (negative) number of drops (failed attempts to
-     * issue the item to a subscriber). Otherwise it is an estimate of
-     * the maximum lag (number of items submitted but not yet
-     * consumed) among all current subscribers. This value is at least
-     * one (accounting for this submitted item) if there are any
-     * subscribers, else zero.
-     * <p>
-     * <p>If the Executor for this publisher throws a
-     * RejectedExecutionException (or any other RuntimeException or
-     * Error) when attempting to asynchronously notify subscribers, or
-     * the drop handler throws an exception when processing a dropped
-     * item, then this exception is rethrown.
-     *
-     * @param item   the (non-null) item to publish
-     * @param onDrop if non-null, the handler invoked upon a drop to a
-     *               subscriber, with arguments of the subscriber and item; if it
-     *               returns true, an offer is re-attempted (once)
-     * @return if negative, the (negative) number of drops; otherwise
-     * an estimate of maximum lag
-     * @throws IllegalStateException      if closed
-     * @throws NullPointerException       if item is null
-     * @throws RejectedExecutionException if thrown by Executor
-     */
-    public int offer(T item,
-                     BiPredicate<Flow.Subscriber<? super T>, ? super T> onDrop) {
-        return doOffer(0L, item, onDrop);
-    }
-
-    /**
-     * Publishes the given item, if possible, to each current subscriber
-     * by asynchronously invoking its {@link
-     * Flow.Subscriber#onNext(Object) onNext} method, blocking while
-     * resources for any subscription are unavailable, up to the
-     * specified timeout or until the caller thread is interrupted, at
-     * which point the given handler (if non-null) is invoked, and if it
-     * returns true, retried once. (The drop handler may distinguish
-     * timeouts from interrupts by checking whether the current thread
-     * is interrupted.)  Other calls to methods in this class by other
-     * threads are blocked while the handler is invoked.  Unless
-     * recovery is assured, options are usually limited to logging the
-     * error and/or issuing an {@link Flow.Subscriber#onError(Throwable)
-     * onError} signal to the subscriber.
-     * <p>
-     * <p>This method returns a status indicator: If negative, it
-     * represents the (negative) number of drops (failed attempts to
-     * issue the item to a subscriber). Otherwise it is an estimate of
-     * the maximum lag (number of items submitted but not yet
-     * consumed) among all current subscribers. This value is at least
-     * one (accounting for this submitted item) if there are any
-     * subscribers, else zero.
-     * <p>
-     * <p>If the Executor for this publisher throws a
-     * RejectedExecutionException (or any other RuntimeException or
-     * Error) when attempting to asynchronously notify subscribers, or
-     * the drop handler throws an exception when processing a dropped
-     * item, then this exception is rethrown.
-     *
-     * @param item    the (non-null) item to publish
-     * @param timeout how long to wait for resources for any subscriber
-     *                before giving up, in units of {@code unit}
-     * @param unit    a {@code TimeUnit} determining how to interpret the
-     *                {@code timeout} parameter
-     * @param onDrop  if non-null, the handler invoked upon a drop to a
-     *                subscriber, with arguments of the subscriber and item; if it
-     *                returns true, an offer is re-attempted (once)
-     * @return if negative, the (negative) number of drops; otherwise
-     * an estimate of maximum lag
-     * @throws IllegalStateException      if closed
-     * @throws NullPointerException       if item is null
-     * @throws RejectedExecutionException if thrown by Executor
-     */
-    public int offer(T item, long timeout, TimeUnit unit,
-                     BiPredicate<Flow.Subscriber<? super T>, ? super T> onDrop) {
-        return doOffer(unit.toNanos(timeout), item, onDrop);
-    }
-
-    /**
-     * Common implementation for both forms of offer
-     */
-    final int doOffer(long nanos, T item,
-                      BiPredicate<Flow.Subscriber<? super T>, ? super T> onDrop) {
-        if (item == null) {
-            throw new NullPointerException();
-        }
-        int lag = 0, drops = 0;
-        boolean complete;
-        synchronized (this) {
-            complete = closed;
-            BufferedSubscription<T> b = clients;
-            if (!complete) {
-                BufferedSubscription<T> pred = null, r = null, rtail = null;
-                while (b != null) {
-                    BufferedSubscription<T> next = b.next;
-                    int stat = b.offer(item);
-                    if (stat < 0) {
-                        b.next = null;
-                        if (pred == null) {
-                            clients = next;
-                        } else {
-                            pred.next = next;
-                        }
-                    } else {
-                        if (stat > lag) {
-                            lag = stat;
-                        } else if (stat == 0) {
-                            b.nextRetry = null;
-                            if (rtail == null) {
-                                r = b;
-                            } else {
-                                rtail.nextRetry = b;
-                            }
-                            rtail = b;
-                        } else if (stat > lag) {
-                            lag = stat;
-                        }
-                        pred = b;
-                    }
-                    b = next;
-                }
-                while (r != null) {
-                    BufferedSubscription<T> nextRetry = r.nextRetry;
-                    r.nextRetry = null;
-                    int stat = (nanos > 0L)
-                            ? r.timedOffer(item, nanos)
-                            : r.offer(item);
-                    if (stat == 0 && onDrop != null && onDrop.test(r.subscriber, item)) {
-                        stat = r.offer(item);
-                    }
-                    if (stat == 0) {
-                        ++drops;
-                    } else if (stat > lag) {
-                        lag = stat;
-                    } else if (stat < 0 && clients == r) {
-                        clients = r.next;
-                    }
-                    r = nextRetry;
-                }
-            }
-        }
-        if (complete) {
-            throw new IllegalStateException("Closed");
-        } else {
-            return (drops > 0) ? -drops : lag;
-        }
-    }
-
-    /**
-     * Unless already closed, issues {@link
-     * Flow.Subscriber#onComplete() onComplete} signals to current
-     * subscribers, and disallows subsequent attempts to publish.
-     * Upon return, this method does <em>NOT</em> guarantee that all
-     * subscribers have yet completed.
-     */
-    public void close() {
-        if (!closed) {
-            BufferedSubscription<T> b;
-            synchronized (this) {
-                b = clients;
-                clients = null;
-                closed = true;
-            }
-            while (b != null) {
-                BufferedSubscription<T> next = b.next;
-                b.next = null;
-                b.onComplete();
-                b = next;
-            }
-        }
-    }
-
-    /**
-     * Unless already closed, issues {@link
-     * Flow.Subscriber#onError(Throwable) onError} signals to current
-     * subscribers with the given error, and disallows subsequent
-     * attempts to publish.  Future subscribers also receive the given
-     * error. Upon return, this method does <em>NOT</em> guarantee
-     * that all subscribers have yet completed.
-     *
-     * @param error the {@code onError} argument sent to subscribers
-     * @throws NullPointerException if error is null
-     */
-    public void closeExceptionally(Throwable error) {
-        if (error == null) {
-            throw new NullPointerException();
-        }
-        if (!closed) {
-            BufferedSubscription<T> b;
-            synchronized (this) {
-                b = clients;
-                clients = null;
-                closed = true;
-                closedException = error;
-            }
-            while (b != null) {
-                BufferedSubscription<T> next = b.next;
-                b.next = null;
-                b.onError(error);
-                b = next;
-            }
-        }
-    }
-
-    /**
-     * Returns true if this publisher is not accepting submissions.
-     *
-     * @return true if closed
-     */
-    public boolean isClosed() {
-        return closed;
-    }
-
-    /**
-     * Returns the exception associated with {@link
-     * #closeExceptionally(Throwable) closeExceptionally}, or null if
-     * not closed or if closed normally.
-     *
-     * @return the exception, or null if none
-     */
-    public Throwable getClosedException() {
-        return closedException;
-    }
-
-    /**
-     * Returns true if this publisher has any subscribers.
-     *
-     * @return true if this publisher has any subscribers
-     */
-    public boolean hasSubscribers() {
-        boolean nonEmpty = false;
-        if (!closed) {
-            synchronized (this) {
-                for (BufferedSubscription<T> b = clients; b != null; ) {
-                    BufferedSubscription<T> next = b.next;
-                    if (b.isDisabled()) {
-                        b.next = null;
-                        b = clients = next;
-                    } else {
-                        nonEmpty = true;
-                        break;
-                    }
-                }
-            }
-        }
-        return nonEmpty;
-    }
-
-    /**
-     * Returns the number of current subscribers.
-     *
-     * @return the number of current subscribers
-     */
-    public int getNumberOfSubscribers() {
-        int count = 0;
-        if (!closed) {
-            synchronized (this) {
-                BufferedSubscription<T> pred = null, next;
-                for (BufferedSubscription<T> b = clients; b != null; b = next) {
-                    next = b.next;
-                    if (b.isDisabled()) {
-                        b.next = null;
-                        if (pred == null) {
-                            clients = next;
-                        } else {
-                            pred.next = next;
-                        }
-                    } else {
-                        pred = b;
-                        ++count;
-                    }
-                }
-            }
-        }
-        return count;
-    }
-
-    /**
-     * Returns the Executor used for asynchronous delivery.
-     *
-     * @return the Executor used for asynchronous delivery
-     */
-    public Executor getExecutor() {
-        return executor;
-    }
-
-    /**
-     * Returns the maximum per-subscriber buffer capacity.
-     *
-     * @return the maximum per-subscriber buffer capacity
-     */
-    public int getMaxBufferCapacity() {
-        return maxBufferCapacity;
-    }
-
-    /**
-     * Returns a list of current subscribers for monitoring and
-     * tracking purposes, not for invoking {@link Flow.Subscriber}
-     * methods on the subscribers.
-     *
-     * @return list of current subscribers
-     */
-    public List<Flow.Subscriber<? super T>> getSubscribers() {
-        ArrayList<Flow.Subscriber<? super T>> subs = new ArrayList<>();
-        synchronized (this) {
-            BufferedSubscription<T> pred = null, next;
-            for (BufferedSubscription<T> b = clients; b != null; b = next) {
-                next = b.next;
-                if (b.isDisabled()) {
-                    b.next = null;
-                    if (pred == null) {
-                        clients = next;
-                    } else {
-                        pred.next = next;
-                    }
-                } else {
-                    subs.add(b.subscriber);
-                }
-            }
-        }
-        return subs;
-    }
-
-    /**
-     * Returns true if the given Subscriber is currently subscribed.
-     *
-     * @param subscriber the subscriber
-     * @return true if currently subscribed
-     * @throws NullPointerException if subscriber is null
-     */
-    public boolean isSubscribed(Flow.Subscriber<? super T> subscriber) {
-        if (subscriber == null) {
-            throw new NullPointerException();
-        }
-        if (!closed) {
-            synchronized (this) {
-                BufferedSubscription<T> pred = null, next;
-                for (BufferedSubscription<T> b = clients; b != null; b = next) {
-                    next = b.next;
-                    if (b.isDisabled()) {
-                        b.next = null;
-                        if (pred == null) {
-                            clients = next;
-                        } else {
-                            pred.next = next;
-                        }
-                    } else if (subscriber.equals(b.subscriber)) {
-                        return true;
-                    } else {
-                        pred = b;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns an estimate of the minimum number of items requested
-     * (via {@link Flow.Subscription#request(long) request}) but not
-     * yet produced, among all current subscribers.
-     *
-     * @return the estimate, or zero if no subscribers
-     */
-    public long estimateMinimumDemand() {
-        long min = Long.MAX_VALUE;
-        boolean nonEmpty = false;
-        synchronized (this) {
-            BufferedSubscription<T> pred = null, next;
-            for (BufferedSubscription<T> b = clients; b != null; b = next) {
-                int n;
-                long d;
-                next = b.next;
-                if ((n = b.estimateLag()) < 0) {
-                    b.next = null;
-                    if (pred == null) {
-                        clients = next;
-                    } else {
-                        pred.next = next;
-                    }
-                } else {
-                    if ((d = b.demand - n) < min) {
-                        min = d;
-                    }
-                    nonEmpty = true;
-                    pred = b;
-                }
-            }
-        }
-        return nonEmpty ? min : 0;
-    }
-
-    /**
-     * Returns an estimate of the maximum number of items produced but
-     * not yet consumed among all current subscribers.
-     *
-     * @return the estimate
-     */
-    public int estimateMaximumLag() {
-        int max = 0;
-        synchronized (this) {
-            BufferedSubscription<T> pred = null, next;
-            for (BufferedSubscription<T> b = clients; b != null; b = next) {
-                int n;
-                next = b.next;
-                if ((n = b.estimateLag()) < 0) {
-                    b.next = null;
-                    if (pred == null) {
-                        clients = next;
-                    } else {
-                        pred.next = next;
-                    }
-                } else {
-                    if (n > max) {
-                        max = n;
-                    }
-                    pred = b;
-                }
-            }
-        }
-        return max;
-    }
-
-    /**
-     * Processes all published items using the given Consumer function.
-     * Returns a CompletableFuture that is completed normally when this
-     * publisher signals {@link Flow.Subscriber#onComplete()
-     * onComplete}, or completed exceptionally upon any error, or an
-     * exception is thrown by the Consumer, or the returned
-     * CompletableFuture is cancelled, in which case no further items
-     * are processed.
-     *
-     * @param consumer the function applied to each onNext item
-     * @return a CompletableFuture that is completed normally
-     * when the publisher signals onComplete, and exceptionally
-     * upon any error or cancellation
-     * @throws NullPointerException if consumer is null
-     */
-    public CompletableFuture<Void> consume(Consumer<? super T> consumer) {
-        if (consumer == null) {
-            throw new NullPointerException();
-        }
-        CompletableFuture<Void> status = new CompletableFuture<>();
-        subscribe(new ConsumerSubscriber<T>(status, consumer));
-        return status;
-    }
-
-    /**
-     * Subscriber for method consume
-     */
-    private static final class ConsumerSubscriber<T>
-            implements Flow.Subscriber<T> {
-        final CompletableFuture<Void> status;
-        final Consumer<? super T> consumer;
-        Flow.Subscription subscription;
-
-        ConsumerSubscriber(CompletableFuture<Void> status,
-                           Consumer<? super T> consumer) {
-            this.status = status;
-            this.consumer = consumer;
-        }
-
-        public final void onSubscribe(Flow.Subscription subscription) {
-            this.subscription = subscription;
-            status.whenComplete((v, e) -> subscription.cancel());
-            if (!status.isDone()) {
-                subscription.request(Long.MAX_VALUE);
-            }
-        }
-
-        public final void onError(Throwable ex) {
-            status.completeExceptionally(ex);
-        }
-
-        public final void onComplete() {
-            status.complete(null);
-        }
-
-        public final void onNext(T item) {
-            try {
-                consumer.accept(item);
-            } catch (Throwable ex) {
-                subscription.cancel();
-                status.completeExceptionally(ex);
-            }
-        }
-    }
-
-    /**
-     * A task for consuming buffer items and signals, created and
-     * executed whenever they become available. A task consumes as
-     * many items/signals as possible before terminating, at which
-     * point another task is created when needed. The dual Runnable
-     * and ForkJoinTask declaration saves overhead when executed by
-     * ForkJoinPools, without impacting other kinds of Executors.
-     */
-    @SuppressWarnings("serial")
-    static final class ConsumerTask<T> extends ForkJoinTask<Void>
-            implements Runnable, CompletableFuture.AsynchronousCompletionTask {
-        final BufferedSubscription<T> consumer;
-
-        ConsumerTask(BufferedSubscription<T> consumer) {
-            this.consumer = consumer;
-        }
-
-        public final Void getRawResult() {
-            return null;
-        }
-
-        public final void setRawResult(Void v) {
-        }
-
-        public final boolean exec() {
-            consumer.consume();
-            return false;
-        }
-
-        public final void run() {
-            consumer.consume();
-        }
-    }
-
-    /**
-     * A bounded (ring) buffer with integrated control to start a
-     * consumer task whenever items are available.  The buffer
-     * algorithm is similar to one used inside ForkJoinPool (see its
-     * internal documentation for details) specialized for the case of
-     * at most one concurrent producer and consumer, and power of two
-     * buffer sizes. This allows methods to operate without locks even
-     * while supporting resizing, blocking, task-triggering, and
-     * garbage-free buffers (nulling out elements when consumed),
-     * although supporting these does impose a bit of overhead
-     * compared to plain fixed-size ring buffers.
-     * <p>
-     * The publisher guarantees a single producer via its lock.  We
-     * ensure in this class that there is at most one consumer.  The
-     * request and cancel methods must be fully thread-safe but are
-     * coded to exploit the most common case in which they are only
-     * called by consumers (usually within onNext).
-     * <p>
-     * Execution control is managed using the ACTIVE ctl bit. We
-     * ensure that a task is active when consumable items (and
-     * usually, SUBSCRIBE, ERROR or COMPLETE signals) are present and
-     * there is demand (unfilled requests).  This is complicated on
-     * the creation side by the possibility of exceptions when trying
-     * to execute tasks. These eventually force DISABLED state, but
-     * sometimes not directly. On the task side, termination (clearing
-     * ACTIVE) that would otherwise race with producers or request()
-     * calls uses the CONSUME keep-alive bit to force a recheck.
-     * <p>
-     * The ctl field also manages run state. When DISABLED, no further
-     * updates are possible. Disabling may be preceded by setting
-     * ERROR or COMPLETE (or both -- ERROR has precedence), in which
-     * case the associated Subscriber methods are invoked, possibly
-     * synchronously if there is no active consumer task (including
-     * cases where execute() failed). The cancel() method is supported
-     * by treating as ERROR but suppressing onError signal.
-     * <p>
-     * Support for blocking also exploits the fact that there is only
-     * one possible waiter. ManagedBlocker-compatible control fields
-     * are placed in this class itself rather than in wait-nodes.
-     * Blocking control relies on the "waiter" field. Producers set
-     * the field before trying to block, but must then recheck (via
-     * offer) before parking. Signalling then just unparks and clears
-     * waiter field. If the producer and/or consumer are using a
-     * ForkJoinPool, the producer attempts to help run consumer tasks
-     * via ForkJoinPool.helpAsyncBlocker before blocking.
-     * <p>
-     * This class uses @Contended and heuristic field declaration
-     * ordering to reduce false-sharing-based memory contention among
-     * instances of BufferedSubscription, but it does not currently
-     * attempt to avoid memory contention among buffers. This field
-     * and element packing can hurt performance especially when each
-     * publisher has only one client operating at a high rate.
-     * Addressing this may require allocating substantially more space
-     * than users expect.
-     */
-    @SuppressWarnings("serial")
-    @sun.misc.Contended
-    private static final class BufferedSubscription<T>
-            implements Flow.Subscription, ForkJoinPool.ManagedBlocker {
-        // Order-sensitive field declarations
-        long timeout;                      // > 0 if timed wait
-        volatile long demand;              // # unfilled requests
-        int maxCapacity;                   // reduced on OOME
-        int putStat;                       // offer result for ManagedBlocker
-        volatile int ctl;                  // atomic run state flags
-        volatile int head;                 // next position to take
-        int tail;                          // next position to put
-        Object[] array;                    // buffer: null if disabled
-        Flow.Subscriber<? super T> subscriber; // null if disabled
-        Executor executor;                 // null if disabled
-        BiConsumer<? super Flow.Subscriber<? super T>, ? super Throwable> onNextHandler;
-        volatile Throwable pendingError;   // holds until onError issued
-        volatile Thread waiter;            // blocked producer thread
-        T putItem;                         // for offer within ManagedBlocker
-        BufferedSubscription<T> next;      // used only by publisher
-        BufferedSubscription<T> nextRetry; // used only by publisher
-
-        // ctl values
-        static final int ACTIVE = 0x01; // consumer task active
-        static final int CONSUME = 0x02; // keep-alive for consumer task
-        static final int DISABLED = 0x04; // final state
-        static final int ERROR = 0x08; // signal onError then disable
-        static final int SUBSCRIBE = 0x10; // signal onSubscribe
-        static final int COMPLETE = 0x20; // signal onComplete when done
-
-        static final long INTERRUPTED = -1L; // timeout vs interrupt sentinel
-
-        /**
-         * Initial buffer capacity used when maxBufferCapacity is
-         * greater. Must be a power of two.
-         */
-        static final int DEFAULT_INITIAL_CAP = 32;
-
-        BufferedSubscription(Flow.Subscriber<? super T> subscriber,
-                             Executor executor,
-                             BiConsumer<? super Flow.Subscriber<? super T>,
-                                     ? super Throwable> onNextHandler,
-                             int maxBufferCapacity) {
-            this.subscriber = subscriber;
-            this.executor = executor;
-            this.onNextHandler = onNextHandler;
-            this.maxCapacity = maxBufferCapacity;
-            this.array = new Object[maxBufferCapacity < DEFAULT_INITIAL_CAP
-                    ? (maxBufferCapacity < 2 // at least 2 slots
-                        ? 2 : maxBufferCapacity)
-                        : DEFAULT_INITIAL_CAP];
-        }
-
-        @Override
-        public String toString() {
-            if (subscriber != null) {
-                return subscriber.toString();
-            } else {
-                return super.toString();
-            }
-        }
-
-        final boolean isDisabled() {
-            return ctl == DISABLED;
-        }
-
-        /**
-         * Returns estimated number of buffered items, or -1 if
-         * disabled.
-         */
-        final int estimateLag() {
-            int n;
-            return (ctl == DISABLED) ? -1 : ((n = tail - head) > 0) ? n : 0;
-        }
-
-        /**
-         * Tries to add item and start consumer task if necessary.
-         *
-         * @return -1 if disabled, 0 if dropped, else estimated lag
-         */
-        final int offer(T item) {
-            int h = head, t = tail, cap, size, stat;
-            Object[] a = array;
-            if (a != null && (cap = a.length) > 0 && cap >= (size = t + 1 - h)) {
-                a[(cap - 1) & t] = item;    // relaxed writes OK
-                tail = t + 1;
-                stat = size;
-            } else {
-                stat = growAndAdd(a, item);
-            }
-            return (stat > 0 && (ctl & (ACTIVE | CONSUME)) != (ACTIVE | CONSUME)) ? startOnOffer(stat) : stat;
-        }
-
-        /**
-         * Tries to create or expand buffer, then adds item if possible.
-         */
-        private int growAndAdd(Object[] a, T item) {
-            boolean alloc;
-            int cap, stat;
-            if ((ctl & (ERROR | DISABLED)) != 0) {
-                cap = 0;
-                stat = -1;
-                alloc = false;
-            } else if (a == null || (cap = a.length) <= 0) {
-                cap = 0;
-                stat = 1;
-                alloc = true;
-            } else {
-                U.fullFence();                   // recheck
-                int h = head, t = tail, size = t + 1 - h;
-                if (cap >= size) {
-                    a[(cap - 1) & t] = item;
-                    tail = t + 1;
-                    stat = size;
-                    alloc = false;
-                } else if (cap >= maxCapacity) {
-                    stat = 0;                    // cannot grow
-                    alloc = false;
-                } else {
-                    stat = cap + 1;
-                    alloc = true;
-                }
-            }
-            if (alloc) {
-                int newCap = (cap > 0) ? cap << 1 : 1;
-                if (newCap <= cap) {
-                    stat = 0;
-                } else {
-                    Object[] newArray = null;
-                    try {
-                        newArray = new Object[newCap];
-                    } catch (Throwable ex) {     // try to cope with OOME
-                    }
-                    if (newArray == null) {
-                        if (cap > 0) {
-                            maxCapacity = cap;   // avoid continuous failure
-                        }
-                        stat = 0;
-                    } else {
-                        array = newArray;
-                        int t = tail;
-                        int newMask = newCap - 1;
-                        if (a != null && cap > 0) {
-                            int mask = cap - 1;
-                            for (int j = head; j != t; ++j) {
-                                long k = ((long) (j & mask) << ASHIFT) + ABASE;
-                                Object x = U.getObjectVolatile(a, k);
-                                if (x != null && // races with consumer
-                                        U.compareAndSwapObject(a, k, x, null)) {
-                                    newArray[j & newMask] = x;
-                                }
-                            }
-                        }
-                        newArray[t & newMask] = item;
-                        tail = t + 1;
-                    }
-                }
-            }
-            return stat;
-        }
-
-        /**
-         * Spins/helps/blocks while offer returns 0.  Called only if
-         * initial offer return 0.
-         */
-        final int submit(T item) {
-            int stat;
-            if ((stat = offer(item)) == 0) {
-                putItem = item;
-                timeout = 0L;
-                putStat = 0;
-                // safe to comment out when executor != ForkJoinPool (TODO)
-                // ForkJoinPool.helpAsyncBlocker(executor, this);
-                if ((stat = putStat) == 0) {
-                    try {
-                        ForkJoinPool.managedBlock(this);
-                    } catch (InterruptedException ie) {
-                        timeout = INTERRUPTED;
-                    }
-                    stat = putStat;
-                }
-                if (timeout < 0L) {
-                    Thread.currentThread().interrupt();
-                }
-            }
-            return stat;
-        }
-
-        /**
-         * Timeout version; similar to submit.
-         */
-        final int timedOffer(T item, long nanos) {
-            int stat;
-            if ((stat = offer(item)) == 0 && (timeout = nanos) > 0L) {
-                putItem = item;
-                putStat = 0;
-                // safe to comment out when executor != ForkJoinPool (TODO)
-                // ForkJoinPool.helpAsyncBlocker(executor, this);
-                if ((stat = putStat) == 0) {
-                    try {
-                        ForkJoinPool.managedBlock(this);
-                    } catch (InterruptedException ie) {
-                        timeout = INTERRUPTED;
-                    }
-                    stat = putStat;
-                }
-                if (timeout < 0L) {
-                    Thread.currentThread().interrupt();
-                }
-            }
-            return stat;
-        }
-
-        /**
-         * Tries to start consumer task after offer.
-         *
-         * @return -1 if now disabled, else argument
-         */
-        private int startOnOffer(int stat) {
-            for (;;) {
-                Executor e;
-                int c;
-                if ((c = ctl) == DISABLED || (e = executor) == null) {
-                    stat = -1;
-                    break;
-                } else if ((c & ACTIVE) != 0) { // ensure keep-alive
-                    if ((c & CONSUME) != 0 || U.compareAndSwapInt(this, CTL, c, c | CONSUME)) {
-                        break;
-                    }
-                } else if (demand == 0L || tail == head) {
-                    break;
-                } else if (U.compareAndSwapInt(this, CTL, c,
-                        c | (ACTIVE | CONSUME))) {
-                    try {
-                        e.execute(new ConsumerTask<T>(this));
-                        break;
-                    } catch (RuntimeException | Error ex) { // back out
-                        do {
-                        } while (((c = ctl) & DISABLED) == 0
-                                && (c & ACTIVE) != 0
-                                && !U.compareAndSwapInt(this, CTL, c, c & ~ACTIVE));
-                        throw ex;
-                    }
-                }
-            }
-            return stat;
-        }
-
-        private void signalWaiter(Thread w) {
-            waiter = null;
-            LockSupport.unpark(w);    // release producer
-        }
-
-        /**
-         * Nulls out most fields, mainly to avoid garbage retention
-         * until publisher unsubscribes, but also to help cleanly stop
-         * upon error by nulling required components.
-         */
-        private void detach() {
-            Thread w = waiter;
-            executor = null;
-            subscriber = null;
-            pendingError = null;
-            signalWaiter(w);
-        }
-
-        /**
-         * Issues error signal, asynchronously if a task is running,
-         * else synchronously.
-         */
-        final void onError(Throwable ex) {
-            for (int c;;) {
-                if (((c = ctl) & (ERROR | DISABLED)) != 0) {
-                    break;
-                } else if ((c & ACTIVE) != 0) {
-                    pendingError = ex;
-                    if (U.compareAndSwapInt(this, CTL, c, c | ERROR)) {
-                        break; // cause consumer task to exit
-                    }
-                } else if (U.compareAndSwapInt(this, CTL, c, DISABLED)) {
-                    Flow.Subscriber<? super T> s = subscriber;
-                    if (s != null && ex != null) {
-                        try {
-                            s.onError(ex);
-                        } catch (Throwable ignore) {
-                        }
-                    }
-                    detach();
-                    break;
-                }
-            }
-        }
-
-        /**
-         * Tries to start consumer task upon a signal or request;
-         * disables on failure.
-         */
-        private void startOrDisable() {
-            Executor e;
-            if ((e = executor) != null) { // skip if already disabled
-                try {
-                    e.execute(new ConsumerTask<T>(this));
-                } catch (Throwable ex) {  // back out and force signal
-                    for (int c;;) {
-                        if ((c = ctl) == DISABLED || (c & ACTIVE) == 0) {
-                            break;
-                        }
-                        if (U.compareAndSwapInt(this, CTL, c, c & ~ACTIVE)) {
-                            onError(ex);
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        final void onComplete() {
-            for (int c;;) {
-                if ((c = ctl) == DISABLED) {
-                    break;
-                }
-                if (U.compareAndSwapInt(this, CTL, c,
-                        c | (ACTIVE | CONSUME | COMPLETE))) {
-                    if ((c & ACTIVE) == 0) {
-                        startOrDisable();
-                    }
-                    break;
-                }
-            }
-        }
-
-        final void onSubscribe() {
-            for (int c;;) {
-                if ((c = ctl) == DISABLED) {
-                    break;
-                }
-                if (U.compareAndSwapInt(this, CTL, c,
-                        c | (ACTIVE | CONSUME | SUBSCRIBE))) {
-                    if ((c & ACTIVE) == 0) {
-                        startOrDisable();
-                    }
-                    break;
-                }
-            }
-        }
-
-        /**
-         * Causes consumer task to exit if active (without reporting
-         * onError unless there is already a pending error), and
-         * disables.
-         */
-        public void cancel() {
-            for (int c;;) {
-                if ((c = ctl) == DISABLED) {
-                    break;
-                } else if ((c & ACTIVE) != 0) {
-                    if (U.compareAndSwapInt(this, CTL, c,
-                            c | (CONSUME | ERROR))) {
-                        break;
-                    }
-                } else if (U.compareAndSwapInt(this, CTL, c, DISABLED)) {
-                    detach();
-                    break;
-                }
-            }
-        }
-
-        /**
-         * Adds to demand and possibly starts task.
-         */
-        public void request(long n) {
-            if (n > 0L) {
-                for (;;) {
-                    long prev = demand, d;
-                    if ((d = prev + n) < prev) { // saturate
-                        d = Long.MAX_VALUE;
-                    }
-                    if (U.compareAndSwapLong(this, DEMAND, prev, d)) {
-                        for (int c, h;; ) {
-                            if ((c = ctl) == DISABLED) {
-                                break;
-                            } else if ((c & ACTIVE) != 0) {
-                                if ((c & CONSUME) != 0 || U.compareAndSwapInt(this, CTL, c, c | CONSUME)) {
-                                    break;
-                                }
-                            } else if ((h = head) != tail) {
-                                if (U.compareAndSwapInt(this, CTL, c,
-                                        c | (ACTIVE | CONSUME))) {
-                                    startOrDisable();
-                                    break;
-                                }
-                            } else if (head == h && tail == h) {
-                                break;          // else stale
-                            }
-                            if (demand == 0L) {
-                                break;
-                            }
-                        }
-                        break;
-                    }
-                }
-            } else if (n < 0L) {
-                onError(new IllegalArgumentException(
-                        "negative subscription request"));
-            }
-        }
-
-        public final boolean isReleasable() { // for ManagedBlocker
-            T item = putItem;
-            if (item != null) {
-                if ((putStat = offer(item)) == 0) {
-                    return false;
-                }
-                putItem = null;
-            }
-            return true;
-        }
-
-        public final boolean block() { // for ManagedBlocker
-            T item = putItem;
-            if (item != null) {
-                putItem = null;
-                long nanos = timeout;
-                long deadline = (nanos > 0L) ? System.nanoTime() + nanos : 0L;
-                while ((putStat = offer(item)) == 0) {
-                    if (Thread.interrupted()) {
-                        timeout = INTERRUPTED;
-                        if (nanos > 0L) {
-                            break;
-                        }
-                    } else if (nanos > 0L && (nanos = deadline - System.nanoTime()) <= 0L) {
-                        break;
-                    } else if (waiter == null) {
-                        waiter = Thread.currentThread();
-                    } else {
-                        if (nanos > 0L) {
-                            LockSupport.parkNanos(this, nanos);
-                        } else {
-                            LockSupport.park(this);
-                        }
-                        waiter = null;
-                    }
-                }
-            }
-            waiter = null;
-            return true;
-        }
-
-        /**
-         * Consumer loop, called from ConsumerTask, or indirectly
-         * when helping during submit.
-         */
-        final void consume() {
-            Flow.Subscriber<? super T> s;
-            int h = head;
-            if ((s = subscriber) != null) {           // else disabled
-                for (;;) {
-                    long d = demand;
-                    int c;
-                    Object[] a;
-                    int n;
-                    long i;
-                    Object x;
-                    Thread w;
-                    if (((c = ctl) & (ERROR | SUBSCRIBE | DISABLED)) != 0) {
-                        if (!checkControl(s, c)) {
-                            break;
-                        }
-                    } else if ((a = array) == null || h == tail
-                            || (n = a.length) == 0
-                            || (x = U.getObjectVolatile(a, (i = ((long) ((n - 1) & h) << ASHIFT) + ABASE))) == null) {
-                        if (!checkEmpty(s, c)) {
-                            break;
-                        }
-                    } else if (d == 0L) {
-                        if (!checkDemand(c)) {
-                            break;
-                        }
-                    } else if (((c & CONSUME) != 0
-                            || U.compareAndSwapInt(this, CTL, c, c | CONSUME))
-                            && U.compareAndSwapObject(a, i, x, null)) {
-                        U.putOrderedInt(this, HEAD, ++h);
-                        U.getAndAddLong(this, DEMAND, -1L);
-                        if ((w = waiter) != null) {
-                            signalWaiter(w);
-                        }
-                        try {
-                            @SuppressWarnings("unchecked") T y = (T) x;
-                            s.onNext(y);
-                        } catch (Throwable ex) {
-                            handleOnNext(s, ex);
-                        }
-                    }
-                }
-            }
-        }
-
-        /**
-         * Responds to control events in consume().
-         */
-        private boolean checkControl(Flow.Subscriber<? super T> s, int c) {
-            boolean stat = true;
-            if ((c & SUBSCRIBE) != 0) {
-                if (U.compareAndSwapInt(this, CTL, c, c & ~SUBSCRIBE)) {
-                    try {
-                        if (s != null) {
-                            s.onSubscribe(this);
-                        }
-                    } catch (Throwable ex) {
-                        onError(ex);
-                    }
-                }
-            } else if ((c & ERROR) != 0) {
-                Throwable ex = pendingError;
-                ctl = DISABLED;           // no need for CAS
-                if (ex != null) {         // null if errorless cancel
-                    try {
-                        if (s != null) {
-                            s.onError(ex);
-                        }
-                    } catch (Throwable ignore) {
-                    }
-                }
-            } else {
-                detach();
-                stat = false;
-            }
-            return stat;
-        }
-
-        /**
-         * Responds to apparent emptiness in consume().
-         */
-        private boolean checkEmpty(Flow.Subscriber<? super T> s, int c) {
-            boolean stat = true;
-            if (head == tail) {
-                if ((c & CONSUME) != 0) {
-                    U.compareAndSwapInt(this, CTL, c, c & ~CONSUME);
-                } else if ((c & COMPLETE) != 0) {
-                    if (U.compareAndSwapInt(this, CTL, c, DISABLED)) {
-                        try {
-                            if (s != null) {
-                                s.onComplete();
-                            }
-                        } catch (Throwable ignore) {
-                        }
-                    }
-                } else if (U.compareAndSwapInt(this, CTL, c, c & ~ACTIVE)) {
-                    stat = false;
-                }
-            }
-            return stat;
-        }
-
-        /**
-         * Responds to apparent zero demand in consume().
-         */
-        private boolean checkDemand(int c) {
-            boolean stat = true;
-            if (demand == 0L) {
-                if ((c & CONSUME) != 0) {
-                    U.compareAndSwapInt(this, CTL, c, c & ~CONSUME);
-                } else if (U.compareAndSwapInt(this, CTL, c, c & ~ACTIVE)) {
-                    stat = false;
-                }
-            }
-            return stat;
-        }
-
-        /**
-         * Processes exception in Subscriber.onNext.
-         */
-        private void handleOnNext(Flow.Subscriber<? super T> s, Throwable ex) {
-            BiConsumer<? super Flow.Subscriber<? super T>, ? super Throwable> h;
-            if ((h = onNextHandler) != null) {
-                try {
-                    h.accept(s, ex);
-                } catch (Throwable ignore) {
-                }
-            }
-            onError(ex);
-        }
-
-        // Unsafe mechanics
-        private static final sun.misc.Unsafe U = UnsafeAccessor.getUnsafe();
-        private static final long CTL;
-        private static final long TAIL;
-        private static final long HEAD;
-        private static final long DEMAND;
-        private static final int ABASE;
-        private static final int ASHIFT;
-
-        static {
-            try {
-                CTL = U.objectFieldOffset(BufferedSubscription.class.getDeclaredField("ctl"));
-                TAIL = U.objectFieldOffset(BufferedSubscription.class.getDeclaredField("tail"));
-                HEAD = U.objectFieldOffset(BufferedSubscription.class.getDeclaredField("head"));
-                DEMAND = U.objectFieldOffset(BufferedSubscription.class.getDeclaredField("demand"));
-
-                ABASE = U.arrayBaseOffset(Object[].class);
-                int scale = U.arrayIndexScale(Object[].class);
-                if ((scale & (scale - 1)) != 0) {
-                    throw new Error("data type scale not a power of two");
-                }
-                ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
-            } catch (ReflectiveOperationException e) {
-                throw new Error(e);
-            }
-
-            // Reduce the risk of rare disastrous classloading in first call to
-            // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
-            Class<?> ensureLoaded = LockSupport.class;
-        }
-    }
-}
diff --git a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/SubmissionPublisherFactory.java b/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/SubmissionPublisherFactory.java
deleted file mode 100644
index 3729469..0000000
--- a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/SubmissionPublisherFactory.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.internal.jsr166;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.ForkJoinPool;
-import java.util.function.BiConsumer;
-
-/**
- * Factory creating JDK8 compatible SubmissionPublisher (Jdk8SubmissionPublisher) or JDK 9+ SubmissionPublisher
- */
-public class SubmissionPublisherFactory {
-
-    /**
-     * Creates a new SubmissionPublisher using the {@link
-     * ForkJoinPool#commonPool()} for async delivery to subscribers
-     * (unless it does not support a parallelism level of at least two,
-     * in which case, a new Thread is created to run each task), with
-     * maximum buffer capacity of {@link Flow#defaultBufferSize}, and no
-     * handler for Subscriber exceptions in method {@link
-     * Flow.Subscriber#onNext(Object) onNext}.
-     */
-    public static <T> SubmittableFlowPublisher<T> createSubmissionPublisher() {
-        return new SubmissionPublisher<T>();
-    }
-
-    public static <T> SubmittableFlowPublisher<T> createSubmissionPublisher(Executor executor,
-                                                                            int maxBufferCapacity) {
-        return new SubmissionPublisher<T>(executor, maxBufferCapacity);
-    }
-
-    public static <T> SubmittableFlowPublisher<T> createSubmissionPublisher(Executor executor,
-                                                                            int maxBufferCapacity,
-                                                                            BiConsumer<? super Flow.Subscriber<? super T>,
-                                                                                    ? super Throwable> handler) {
-        return new SubmissionPublisher<T>(executor, maxBufferCapacity, handler);
-    }
-
-}
diff --git a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/UnsafeAccessor.java b/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/UnsafeAccessor.java
deleted file mode 100644
index 19f9887..0000000
--- a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/UnsafeAccessor.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.internal.jsr166;
-
-import sun.misc.Unsafe;
-
-import java.lang.reflect.Field;
-import java.security.PrivilegedExceptionAction;
-
-/**
- * Helper for classes in the jsr166 package to access the {@code sun.misc.Unsafe} instance.
- *
- * @author Adam Lindenthal
- */
-class UnsafeAccessor {
-    static sun.misc.Unsafe getUnsafe() {
-        try {
-            return sun.misc.Unsafe.getUnsafe();
-        } catch (SecurityException tryReflectionInstead) {
-        }
-        try {
-            return java.security.AccessController.doPrivileged((PrivilegedExceptionAction<Unsafe>) () -> {
-                Class<Unsafe> k = Unsafe.class;
-                for (Field f : k.getDeclaredFields()) {
-                    f.setAccessible(true);
-                    Object x = f.get(null);
-                    if (k.isInstance(x)) {
-                        return k.cast(x);
-                    }
-                }
-                throw new NoSuchFieldError("the Unsafe");
-            });
-        } catch (java.security.PrivilegedActionException e) {
-            throw new RuntimeException("Could not initialize intrinsics", e.getCause());
-        }
-
-
-    }
-}
diff --git a/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties b/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties
index 285b9de..b60bf25 100644
--- a/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties
+++ b/core-common/src/main/resources/org/glassfish/jersey/internal/localization.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
 # Copyright (c) 2018 Payara Foundation and/or its affiliates.
 #
 # This program and the accompanying materials are made available under the
@@ -116,6 +116,7 @@
 new.cookie.is.null=New cookie is null.
 no.container.available=No container available.
 no.error.processing.in.scope=There is no error processing in scope.
+no.entitypart.builder.found="No EntityPart.Builder implementation found. Is jersey-media-multipart on a classpath?";
 not.supported.on.outbound.message=Method not supported on an outbound message.
 osgi.registry.error.opening.resource.stream=Unable to open an input stream for resource {0}.
 osgi.registry.error.processing.resource.stream=Unexpected error occurred while processing resource stream {0}.
diff --git a/core-common/src/test/java/org/glassfish/jersey/internal/TestRuntimeDelegate.java b/core-common/src/test/java/org/glassfish/jersey/internal/TestRuntimeDelegate.java
index 55884e1..b7d0472 100644
--- a/core-common/src/test/java/org/glassfish/jersey/internal/TestRuntimeDelegate.java
+++ b/core-common/src/test/java/org/glassfish/jersey/internal/TestRuntimeDelegate.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,8 +16,10 @@
 
 package org.glassfish.jersey.internal;
 
+import jakarta.ws.rs.SeBootstrap;
 import jakarta.ws.rs.WebApplicationException;
 import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.EntityPart;
 import jakarta.ws.rs.core.Link;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
@@ -29,6 +31,8 @@
 
 import org.junit.jupiter.api.Assertions;
 
+import java.util.concurrent.CompletionStage;
+
 /**
  * Test runtime delegate.
  *
@@ -46,6 +50,22 @@
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
+    @Override
+    public SeBootstrap.Configuration.Builder createConfigurationBuilder() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public CompletionStage<SeBootstrap.Instance> bootstrap(Application application, SeBootstrap.Configuration configuration) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public CompletionStage<SeBootstrap.Instance> bootstrap(Class<? extends Application> aClass,
+                                                           SeBootstrap.Configuration configuration) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
     public void testMediaType() {
         MediaType m = new MediaType("text", "plain");
         Assertions.assertNotNull(m);
diff --git a/core-common/src/test/java/org/glassfish/jersey/message/internal/NewCookieProviderTest.java b/core-common/src/test/java/org/glassfish/jersey/message/internal/NewCookieProviderTest.java
new file mode 100644
index 0000000..f160690
--- /dev/null
+++ b/core-common/src/test/java/org/glassfish/jersey/message/internal/NewCookieProviderTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.message.internal;
+
+import jakarta.ws.rs.core.NewCookie;
+import org.junit.jupiter.api.Test;
+
+import java.util.Date;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class NewCookieProviderTest {
+
+    private final NewCookie newCookie = new NewCookie(
+            "test",
+            "value",
+            "/",
+            "localhost",
+            1,
+            "comment",
+            60,
+            new Date(),
+            true,
+            true,
+            NewCookie.SameSite.STRICT
+    );
+
+    @Test
+    public void SameSiteTest() {
+        final NewCookieProvider provider = new NewCookieProvider();
+        final String newCookieString = provider.toString(newCookie);
+        assertTrue(newCookieString.contains("SameSite=STRICT"));
+        assertEquals(NewCookie.SameSite.STRICT, provider.fromString(newCookieString).getSameSite());
+    }
+
+}
diff --git a/core-server/pom.xml b/core-server/pom.xml
index cdb694e..4885dc1 100644
--- a/core-server/pom.xml
+++ b/core-server/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.core</groupId>
@@ -243,6 +243,12 @@
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <profiles>
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
index 42d11dd..7d75df1 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
@@ -222,7 +222,20 @@
      *                              application handler.
      */
     public ApplicationHandler(final Class<? extends Application> jaxrsApplicationClass) {
-        initialize(new ApplicationConfigurator(jaxrsApplicationClass), Injections.createInjectionManager(), null);
+        this(jaxrsApplicationClass, null);
+    }
+
+    /**
+     * Create a new Jersey server-side application handler configured by a
+     * {@link Application JAX-RS Application (sub-)class}.
+     *
+     * @param applicationClass JAX-RS {@code Application} (sub-)class that will be
+     *                              instantiated and used to configure the new Jersey
+     *                              application handler.
+     * @param customBinder additional custom bindings used to configure the application's.
+     */
+    public ApplicationHandler(final Class<? extends Application> applicationClass, final Binder customBinder) {
+        initialize(new ApplicationConfigurator(applicationClass), Injections.createInjectionManager(), customBinder);
     }
 
     /**
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ContainerRequest.java b/core-server/src/main/java/org/glassfish/jersey/server/ContainerRequest.java
index 3105c2f..6d9fba2 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ContainerRequest.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ContainerRequest.java
@@ -301,6 +301,11 @@
     }
 
     @Override
+    public boolean hasProperty(final String name) {
+        return propertiesDelegate.hasProperty(name);
+    }
+
+    @Override
     public Object getProperty(final String name) {
         return propertiesDelegate.getProperty(name);
     }
@@ -821,13 +826,13 @@
     }
 
     /**
-     * Get the values of a HTTP request header. The returned List is read-only.
-     * This is a shortcut for {@code getRequestHeaders().get(name)}.
+     * Get the values of an HTTP request header if the header exists on the current request. The returned value will be
+     * a read-only List if the specified header exists or {@code null} if it does not. This is a shortcut for
+     * {@code getRequestHeaders().get(name)}.
      *
      * @param name the header name, case insensitive.
-     * @return a read-only list of header values.
-     *
-     * @throws IllegalStateException if called outside the scope of a request.
+     * @return a read-only list of header values if the specified header exists, otherwise {@code null}.
+     * @throws java.lang.IllegalStateException if called outside the scope of a request.
      */
     @Override
     public List<String> getRequestHeader(final String name) {
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/DefaultExceptionMapper.java b/core-server/src/main/java/org/glassfish/jersey/server/DefaultExceptionMapper.java
new file mode 100644
index 0000000..bd7c4d1
--- /dev/null
+++ b/core-server/src/main/java/org/glassfish/jersey/server/DefaultExceptionMapper.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.server;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import org.glassfish.jersey.server.internal.LocalizationMessages;
+
+class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
+    @Override
+    public Response toResponse(Throwable exception) {
+        return (exception instanceof WebApplicationException)
+                ? processWebApplicationException((WebApplicationException) exception)
+                : processDefaultException(exception);
+    }
+
+    private static Response processWebApplicationException(WebApplicationException exception) {
+        return (exception.getResponse() == null)
+                ? processDefaultException(exception)
+                : exception.getResponse();
+    }
+
+    private static Response processDefaultException(Throwable exception) {
+        return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
+                .entity(LocalizationMessages.ERROR_EXCEPTION_MAPPING_THROWN_TO_CONTAINER())
+                .build();
+    }
+}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/JerseySeBootstrapConfiguration.java b/core-server/src/main/java/org/glassfish/jersey/server/JerseySeBootstrapConfiguration.java
new file mode 100644
index 0000000..0f1d6d7
--- /dev/null
+++ b/core-server/src/main/java/org/glassfish/jersey/server/JerseySeBootstrapConfiguration.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.server;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.UriBuilder;
+import org.glassfish.jersey.internal.config.ExternalPropertiesConfigurationFactory;
+import org.glassfish.jersey.internal.config.SystemPropertiesConfigurationModel;
+import org.glassfish.jersey.internal.util.PropertiesClass;
+import org.glassfish.jersey.server.internal.LocalizationMessages;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.WebServer;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.URI;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Random;
+import java.util.function.BiFunction;
+import java.util.logging.Logger;
+
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+
+/**
+ * Jersey implementation of {@link SeBootstrap.Configuration} implementing arbitrary methods for acquiring
+ * the configuration settings.
+ * @since 3.1.0
+ */
+public final class JerseySeBootstrapConfiguration implements SeBootstrap.Configuration {
+    private static final Logger LOGGER = Logger.getLogger(JerseySeBootstrapConfiguration.class.getName());
+    protected static final Random RANDOM = new Random();
+    private final SeBootstrap.Configuration configuration;
+
+    private JerseySeBootstrapConfiguration(SeBootstrap.Configuration configuration) {
+        this.configuration = configuration;
+    }
+
+    @Override
+    public Object property(String name) {
+        return configuration.property(name);
+    }
+
+    /**
+     * Compose {@link URI} based on properties defined in this configuration.
+     * @param resolveDefaultPort if {@code true} the port is not set, it is resolved as
+     *                           {@link Container#DEFAULT_HTTP_PORT} or {@link Container#DEFAULT_HTTPS_PORT}
+     *                           based on the protocol scheme.
+     * @return Composed {@link URI} based on properties defined in this configuration.
+     */
+    public URI uri(boolean resolveDefaultPort) {
+        final String protocol = configuration.protocol();
+        final String host = configuration.host();
+        final int port = resolveDefaultPort ? resolvePort() : configuration.port();
+        final String rootPath = configuration.rootPath();
+        final URI uri = UriBuilder.newInstance().scheme(protocol.toLowerCase()).host(host).port(port).path(rootPath)
+                .build();
+        return uri;
+    }
+
+    private int resolvePort() {
+        final int configPort = configuration.port();
+        final int basePort = allowPrivilegedPorts() ? 0 : 8000;
+        final int port;
+        switch (configPort) {
+            case SeBootstrap.Configuration.DEFAULT_PORT:
+                port = basePort + (isHttps() ? Container.DEFAULT_HTTPS_PORT : Container.DEFAULT_HTTP_PORT);
+                break;
+            case SeBootstrap.Configuration.FREE_PORT:
+               port = _resolvePort(basePort == 0);
+               break;
+            default:
+                port = configPort;
+                break;
+        }
+        return port;
+    }
+
+    private int _resolvePort(boolean allowPrivilegedPort) {
+        final int basePort = allowPrivilegedPort ? 0 : 1024;
+        // Get the initial range parameters
+        final int lower = basePort;
+        final int range = 0xFFFF;
+
+        // Select a start point in the range
+        final int initialOffset = RANDOM.nextInt(range - lower);
+
+        // Loop the offset through all ports in the range and attempt
+        // to bind to each
+        int offset = initialOffset;
+        ServerSocket socket;
+        do {
+            final int port = lower + offset;
+            try {
+                socket = new ServerSocket(port);
+                socket.close();
+                return port;
+            } catch (IOException caught) {
+                // Swallow exceptions until the end
+            }
+            offset = (offset + 1) % range;
+        } while (offset != initialOffset);
+
+        // If a port can't be bound, throw the exception
+        throw new IllegalArgumentException(LocalizationMessages.COULD_NOT_BIND_TO_ANY_PORT());
+    }
+
+    /**
+     * Return {@link SSLContext} in the configuration if the protocol scheme is {@code HTTPS}.
+     * @return the SSLContext in the configuration.
+     */
+    @Override
+    public SSLContext sslContext() {
+        final SSLContext sslContext = configuration.sslContext();
+        return isHttps() ? sslContext : null;
+    }
+
+    /**
+     * If the protocol schema is {@code HTTPS}, return {@code true}.
+     * @return {@code true} when the protocol schema is {@code HTTPS}.
+     */
+    public boolean isHttps() {
+        return "HTTPS".equalsIgnoreCase(configuration.protocol());
+    }
+
+    /**
+     * Defines if the {@link WebServer} should automatically start.
+     * @return false if {@link ServerProperties#WEBSERVER_AUTO_START} is {@code false}, {@code true} otherwise.
+     */
+    public boolean autoStart() {
+        final boolean autoStart = Optional.ofNullable(
+                (Boolean) configuration.property(ServerProperties.WEBSERVER_AUTO_START))
+                .orElse(TRUE);
+        return autoStart;
+    }
+
+    /**
+     * Defines if the {@link WebServer} should start on a privileged port when port is not set.
+     * @return true if {@link ServerProperties#WEBSERVER_AUTO_START} is {@code true}, {@code false} otherwise.
+     */
+    public boolean allowPrivilegedPorts() {
+        return Optional.ofNullable(
+                (Boolean) configuration.property(ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS))
+                .orElse(FALSE);
+    }
+
+    /**
+     * Factory method creating {@code JerseySeBootstrapConfiguration} wrapper around {@link SeBootstrap.Configuration}.
+     * @param configuration wrapped configuration
+     * @return {@code JerseySeBootstrapConfiguration} wrapper around {@link SeBootstrap.Configuration}.
+     */
+    public static JerseySeBootstrapConfiguration from(SeBootstrap.Configuration configuration) {
+        return JerseySeBootstrapConfiguration.class.isInstance(configuration)
+                ? (JerseySeBootstrapConfiguration) configuration
+                : new JerseySeBootstrapConfiguration(configuration);
+    }
+
+    /**
+     * Return a Jersey instance of {@link SeBootstrap.Configuration.Builder} with prefilled values.
+     * @return a Jersey instance of {@link SeBootstrap.Configuration.Builder}.
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static final class Builder implements SeBootstrap.Configuration.Builder {
+        private static final Map<String, Class<?>> PROPERTY_TYPES = new HashMap<>();
+
+        static {
+            PROPERTY_TYPES.put(SeBootstrap.Configuration.PROTOCOL, String.class);
+            PROPERTY_TYPES.put(SeBootstrap.Configuration.HOST, String.class);
+            PROPERTY_TYPES.put(SeBootstrap.Configuration.PORT, Integer.class);
+            PROPERTY_TYPES.put(SeBootstrap.Configuration.ROOT_PATH, String.class);
+            PROPERTY_TYPES.put(SeBootstrap.Configuration.SSL_CONTEXT, SSLContext.class);
+            PROPERTY_TYPES.put(SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION, SSLClientAuthentication.class);
+            PROPERTY_TYPES.put(ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS, Boolean.class);
+            PROPERTY_TYPES.put(ServerProperties.WEBSERVER_AUTO_START, Boolean.class);
+            PROPERTY_TYPES.put(ServerProperties.WEBSERVER_CLASS, Class.class);
+        }
+
+        private final Map<String, Object> properties = new HashMap<>();
+
+        private Builder() {
+            this.properties.put(SeBootstrap.Configuration.PROTOCOL, "HTTP"); // upper case mandated by javadoc
+            this.properties.put(SeBootstrap.Configuration.HOST, "localhost");
+            this.properties.put(SeBootstrap.Configuration.PORT, -1); // Auto-select port 8080 for HTTP or 8443 for HTTPS
+            this.properties.put(SeBootstrap.Configuration.ROOT_PATH, "/");
+            this.properties.put(ServerProperties.WEBSERVER_CLASS, WebServer.class); // Auto-select first provider
+            try {
+                this.properties.put(SeBootstrap.Configuration.SSL_CONTEXT, SSLContext.getDefault());
+            } catch (final NoSuchAlgorithmException e) {
+                throw new RuntimeException(e);
+            }
+            this.properties.put(SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION,
+                    SeBootstrap.Configuration.SSLClientAuthentication.NONE);
+            this.properties.put(ServerProperties.WEBSERVER_AUTO_START, TRUE);
+            this.properties.put(ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS, FALSE);
+
+            SystemPropertiesConfigurationModel propertiesConfigurationModel = new SystemPropertiesConfigurationModel(
+                    Collections.singletonList(Properties.class.getName())
+            );
+            from((name, aClass) -> String.class.equals(aClass) || Integer.class.equals(aClass) || Boolean.class.equals(aClass)
+                    ? propertiesConfigurationModel.getOptionalProperty(name, aClass)
+                    : Optional.empty()
+            );
+        }
+
+        @Override
+        public JerseySeBootstrapConfiguration build() {
+            return JerseySeBootstrapConfiguration.from(this.properties::get);
+        }
+
+        @Override
+        public Builder property(String name, Object value) {
+            this.properties.put(name, value);
+            return this;
+        }
+
+        /**
+         * Set the the respective {@link WebServer} class to be used by the
+         * {@link org.glassfish.jersey.server.spi.WebServerProvider}.
+         * @param webServerClass the class implementing {@link WebServer}.
+         * @return the updated builder.
+         */
+        public Builder webServerClass(Class<? extends WebServer> webServerClass) {
+            return property(ServerProperties.WEBSERVER_CLASS, webServerClass);
+        }
+
+        /**
+         * Define if the {@link WebServer} should auto-start at bootstrap.
+         * @param autostart the auto-start flag.
+         * @return the updated builder.
+         */
+        public Builder autoStart(Boolean autostart) {
+            return property(ServerProperties.WEBSERVER_AUTO_START, autostart);
+        }
+
+        @Override
+        public <T> JerseySeBootstrapConfiguration.Builder from(BiFunction<String, Class<T>, Optional<T>> configProvider) {
+            PROPERTY_TYPES.forEach(
+                    (propertyName, propertyType) -> configProvider.apply(propertyName, (Class<T>) propertyType)
+                            .ifPresent(propertyValue -> this.properties.put(propertyName, propertyValue)));
+            return this;
+        }
+
+        @Override
+        public JerseySeBootstrapConfiguration.Builder from(Object externalConfig) {
+            if (SeBootstrap.Configuration.class.isInstance(externalConfig)) {
+                final SeBootstrap.Configuration other = (SeBootstrap.Configuration) externalConfig;
+                from((name, clazz) -> {
+                    final Object property = other.property(name);
+                    if (property != null) {
+                        if (clazz.equals(property.getClass())) {
+                            return Optional.of(property);
+                        } else {
+                            LOGGER.warning(LocalizationMessages.IGNORE_SEBOOTSTRAP_CONFIGURATION_PROPERTY(name, clazz));
+                        }
+                    }
+                    return Optional.empty();
+                });
+            }
+            return this;
+        }
+    }
+
+    /**
+     * Name the properties to be internally read from System properties by {@link ExternalPropertiesConfigurationFactory}.
+     * This is required just when SecurityManager is on, otherwise all system properties are read.
+     */
+    @PropertiesClass
+    private static class Properties {
+        /**
+         * See {@link SeBootstrap.Configuration#PROTOCOL} property.
+         */
+        public static final String SE_BOOTSTRAP_CONFIGURATION_PROTOCOL = SeBootstrap.Configuration.PROTOCOL;
+
+        /**
+         * See {@link SeBootstrap.Configuration#HOST} property.
+         */
+        public static final String SE_BOOTSTRAP_CONFIGURATION_HOST = SeBootstrap.Configuration.HOST;
+
+        /**
+         * See {@link SeBootstrap.Configuration#PORT} property.
+         */
+        public static final String SE_BOOTSTRAP_CONFIGURATION_PORT = SeBootstrap.Configuration.PORT;
+
+        /**
+         * See {@link SeBootstrap.Configuration#ROOT_PATH} property.
+         */
+        public static final String SE_BOOTSTRAP_CONFIGURATION_ROOT_PATH = SeBootstrap.Configuration.ROOT_PATH;
+
+        /**
+         * See {@link ServerProperties#WEBSERVER_ALLOW_PRIVILEGED_PORTS} property.
+         */
+        public static final String WEBSERVER_ALLOW_PRIVILEGED_PORTS  = ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS;
+
+        /**
+         * See {@link ServerProperties#WEBSERVER_AUTO_START} property.
+         */
+        public static final String WEBSERVER_AUTO_START = ServerProperties.WEBSERVER_AUTO_START;
+    }
+}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java b/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java
index 291b76f..ae39a68 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -756,6 +756,11 @@
     }
 
     @Override
+    public final boolean hasProperty(final String name) {
+        return state.hasProperty(name);
+    }
+
+    @Override
     public final Object getProperty(final String name) {
         return state.getProperty(name);
     }
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ServerBinder.java b/core-server/src/main/java/org/glassfish/jersey/server/ServerBinder.java
index 03482f9..4cf65c8 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ServerBinder.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ServerBinder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,6 +16,7 @@
 
 package org.glassfish.jersey.server;
 
+import jakarta.ws.rs.ext.ExceptionMapper;
 import jakarta.ws.rs.ext.MessageBodyWriter;
 import jakarta.ws.rs.ext.WriterInterceptor;
 
@@ -44,5 +45,8 @@
 
         // JSONP
         bind(JsonWithPaddingInterceptor.class).to(WriterInterceptor.class).in(Singleton.class);
+
+        //Default exception mapper
+        bind(DefaultExceptionMapper.class).to(ExceptionMapper.class).in(Singleton.class);
     }
 }
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java b/core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java
index 4c06c5c..5d8a3ad 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -24,6 +24,8 @@
 import org.glassfish.jersey.internal.util.PropertiesClass;
 import org.glassfish.jersey.internal.util.PropertiesHelper;
 import org.glassfish.jersey.internal.util.PropertyAlias;
+import org.glassfish.jersey.server.spi.Container;
+import org.glassfish.jersey.server.spi.WebServer;
 
 
 /**
@@ -764,6 +766,50 @@
             "jersey.config.server.empty.request.media.matches.any.consumes";
 
     /**
+     * Defines whether to allow privileged ports (0-1023) to be used to start the {@link WebServer} implementation
+     * to be chosen from the unused ports when the {@link jakarta.ws.rs.SeBootstrap.Configuration#PORT} is set to {@code -1}
+     * or unset.
+     * <p>
+     * The default ports are {@link Container#DEFAULT_HTTP_PORT} for HTTP and {@link Container#DEFAULT_HTTPS_PORT}
+     * for HTTPS when {@code WEBSERVER_ALLOW_PRIVILEGED_PORTS} is {@code true} or 8080 for HTTP and 8443 for HTTPS when
+     * {@code WEBSERVER_ALLOW_PRIVILEGED_PORTS} is {@code false}.
+     * </p>
+     * <p>
+     * If {@link jakarta.ws.rs.SeBootstrap.Configuration#PORT} is set to {@code 0}, the implementation scans for random unused
+     * port (0-65535) when {@code WEBSERVER_ALLOW_PRIVILEGED_PORTS} is {@code true}, or (1024-65535) when
+     * {@code WEBSERVER_ALLOW_PRIVILEGED_PORTS} is {@code false.}
+     * </p>
+     * <p>
+     * The default this is {@code false}. Use {@code true} to allow a restricted port number. The name of the configuration
+     * property is <tt>{@value}</tt>.
+     * </p>
+     * @since 3.1.0
+     */
+    public static final String WEBSERVER_ALLOW_PRIVILEGED_PORTS =
+            "jersey.config.server.bootstrap.webserver.allow.privileged.ports";
+
+    /**
+     * Whether to automatically startup {@link WebServer} at bootstrap.
+     * <p>
+     * By default, servers are immediately listening to connections after bootstrap,
+     * so no explicit invocation of {@link WebServer#start()} is needed. The name of the configuration
+     * property is <tt>{@value}</tt>.
+     * </p>
+     * @since 3.1.0
+     */
+    public static final String WEBSERVER_AUTO_START = "jersey.config.server.bootstrap.webserver.autostart";
+
+    /**
+     * Defines the implementation of {@link WebServer} to bootstrap.
+     * <p>
+     * By default auto-selects the first server provider found. The name of the configuration
+     * property is <tt>{@value}</tt>.
+     * </p>
+     * @since 3.1.0
+     */
+    public static final String WEBSERVER_CLASS = "jersey.config.server.bootstrap.webserver.class";
+
+    /**
      * JVM argument to define the value of
      * {@link org.glassfish.jersey.server.internal.monitoring.core.ReservoirConstants#COLLISION_BUFFER_POWER}.
      * Lower values reduce the memory footprint.
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java b/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java
index 6c5740e..7078db8 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java
@@ -128,6 +128,11 @@
     /** Resolve relative URIs according to RFC7231 (not JAX-RS 2.0 compliant */
     private final boolean rfc7231LocationHeaderRelativeUriResolution;
 
+    /**
+     * Default exception mapper (@since 3.1.0 according to JAX-RS 3.1 spec)
+     */
+    private static final ExceptionMapper<Throwable> DEFAULT_EXCEPTION_MAPPER = new DefaultExceptionMapper();
+
     static ServerRuntime createServerRuntime(
             InjectionManager injectionManager,
             ServerBootstrapBag bootstrapBag,
@@ -367,11 +372,11 @@
 
         public void process(ContainerResponse response) {
             processingContext.monitoringEventBuilder().setContainerResponse(response);
-            response = processResponse(response);
+            response = processResponse(response, null);
             release(response);
         }
 
-        private ContainerResponse processResponse(ContainerResponse response) {
+        private ContainerResponse processResponse(ContainerResponse response, Throwable unmappedThrowable) {
             final Stage<ContainerResponse> respondingRoot = processingContext.createRespondingRoot();
 
             if (respondingRoot != null) {
@@ -381,7 +386,23 @@
 
             // no-exception zone
             // the methods below are guaranteed to not throw any exceptions
-            completionCallbackRunner.onComplete(null);
+            completionCallbackRunner.onComplete(unmappedThrowable);
+            return response;
+        }
+
+        private ContainerResponse preProcessResponse(Response exceptionResponse, ContainerRequest request) {
+            final ContainerResponse response;
+            try {
+                response = convertResponse(exceptionResponse);
+                if (!runtime.disableLocationHeaderRelativeUriResolution) {
+                    ensureAbsolute(response.getLocation(), response.getHeaders(), request,
+                            runtime.rfc7231LocationHeaderRelativeUriResolution);
+                }
+                processingContext.monitoringEventBuilder().setContainerResponse(response)
+                        .setResponseSuccessfullyMapped(true);
+            } finally {
+                processingContext.triggerEvent(RequestEvent.Type.EXCEPTION_MAPPING_FINISHED);
+            }
             return response;
         }
 
@@ -408,22 +429,12 @@
             processingContext.triggerEvent(RequestEvent.Type.ON_EXCEPTION);
 
             ContainerResponse response = null;
+            ContainerResponse defaultMapperResponse = null;
             try {
                 final Response exceptionResponse = mapException(throwable);
                 try {
-                    try {
-                        response = convertResponse(exceptionResponse);
-                        if (!runtime.disableLocationHeaderRelativeUriResolution) {
-                            ensureAbsolute(response.getLocation(), response.getHeaders(), request,
-                                    runtime.rfc7231LocationHeaderRelativeUriResolution);
-                        }
-                        processingContext.monitoringEventBuilder().setContainerResponse(response)
-                                .setResponseSuccessfullyMapped(true);
-                    } finally {
-                        processingContext.triggerEvent(RequestEvent.Type.EXCEPTION_MAPPING_FINISHED);
-                    }
-
-                    processResponse(response);
+                    response = preProcessResponse(exceptionResponse, request);
+                    processResponse(response, null);
                 } catch (final Throwable respError) {
                     LOGGER.log(Level.SEVERE, LocalizationMessages.ERROR_PROCESSING_RESPONSE_FROM_ALREADY_MAPPED_EXCEPTION());
                     processingContext.monitoringEventBuilder()
@@ -439,16 +450,21 @@
 
                 if (!processResponseError(responseError)) {
                     // Pass the exception to the container.
-                    LOGGER.log(Level.FINE, LocalizationMessages.ERROR_EXCEPTION_MAPPING_THROWN_TO_CONTAINER(), responseError);
+                    LOGGER.log(Level.WARNING, LocalizationMessages.ERROR_EXCEPTION_MAPPING_THROWN_TO_CONTAINER(), responseError);
 
                     try {
                         request.getResponseWriter().failure(responseError);
                     } finally {
-                        completionCallbackRunner.onComplete(responseError);
+                        defaultMapperResponse = processResponseWithDefaultExceptionMapper(responseError, request);
+
+                        // completionCallbackRunner.onComplete(responseError); is called from
+                        // processResponseWithDefaultExceptionMapper
                     }
+
                 }
+
             } finally {
-                release(response);
+                release(response, defaultMapperResponse);
             }
         }
 
@@ -480,7 +496,7 @@
 
                     if (processedError != null) {
                         processedResponse =
-                                processResponse(new ContainerResponse(processingContext.request(), processedError));
+                                processResponse(new ContainerResponse(processingContext.request(), processedError), null);
                         processed = true;
                     }
                 } catch (final Throwable throwable) {
@@ -510,6 +526,7 @@
 
             do {
                 final Throwable throwable = wrap.getCurrent();
+
                 if (wrap.isInMappable() || throwable instanceof WebApplicationException) {
                     // in case ServerProperties.PROCESSING_RESPONSE_ERRORS_ENABLED is true, allow
                     // wrapped MessageBodyProviderNotFoundException to propagate
@@ -526,56 +543,19 @@
                         processingContext.routingContext().setMappedThrowable(throwable);
 
                         waeResponse = webApplicationException.getResponse();
-                        if (waeResponse.hasEntity()) {
-                            LOGGER.log(Level.FINE, LocalizationMessages
-                                    .EXCEPTION_MAPPING_WAE_ENTITY(waeResponse.getStatus()), throwable);
+                        if (waeResponse != null && waeResponse.hasEntity()) {
+                            LOGGER.log(Level.FINE,
+                                    LocalizationMessages.EXCEPTION_MAPPING_WAE_ENTITY(waeResponse.getStatus()),
+                                    throwable);
                             return waeResponse;
                         }
                     }
 
                     final long timestamp = tracingLogger.timestamp(ServerTraceEvent.EXCEPTION_MAPPING);
                     final ExceptionMapper mapper = runtime.exceptionMappers.findMapping(throwable);
-                    if (mapper != null) {
-                        processingContext.monitoringEventBuilder().setExceptionMapper(mapper);
-                        processingContext.triggerEvent(RequestEvent.Type.EXCEPTION_MAPPER_FOUND);
-                        try {
-                            final Response mappedResponse = mapper.toResponse(throwable);
-
-                            if (tracingLogger.isLogEnabled(ServerTraceEvent.EXCEPTION_MAPPING)) {
-                                tracingLogger.logDuration(ServerTraceEvent.EXCEPTION_MAPPING,
-                                        timestamp, mapper, throwable, throwable.getLocalizedMessage(),
-                                        mappedResponse != null ? mappedResponse.getStatusInfo() : "-no-response-");
-                            }
-
-                            // set mapped throwable
-                            processingContext.routingContext().setMappedThrowable(throwable);
-
-                            if (mappedResponse != null) {
-                                // response successfully mapped
-                                if (LOGGER.isLoggable(Level.FINER)) {
-                                    final String message = String.format(
-                                            "Exception '%s' has been mapped by '%s' to response '%s' (%s:%s).",
-                                            throwable.getLocalizedMessage(),
-                                            mapper.getClass().getName(),
-                                            mappedResponse.getStatusInfo().getReasonPhrase(),
-                                            mappedResponse.getStatusInfo().getStatusCode(),
-                                            mappedResponse.getStatusInfo().getFamily());
-                                    LOGGER.log(Level.FINER, message);
-                                }
-                                return mappedResponse;
-                            } else {
-                                return Response.noContent().build();
-                            }
-                        } catch (final Throwable mapperThrowable) {
-                            // spec: If the exception mapping provider throws an exception while creating a Response
-                            // then return a server error (status code 500) response to the client.
-                            LOGGER.log(Level.SEVERE, LocalizationMessages.EXCEPTION_MAPPER_THROWS_EXCEPTION(mapper.getClass()),
-                                    mapperThrowable);
-                            LOGGER.log(Level.SEVERE, LocalizationMessages.EXCEPTION_MAPPER_FAILED_FOR_EXCEPTION(), throwable);
-                            return Response.serverError().build();
-                        }
+                    if (mapper != null && !DefaultExceptionMapper.class.isInstance(mapper)) {
+                        return processExceptionWithMapper(mapper, throwable, timestamp);
                     }
-
                     if (waeResponse != null) {
                         LOGGER.log(Level.FINE, LocalizationMessages
                                 .EXCEPTION_MAPPING_WAE_NO_ENTITY(waeResponse.getStatus()), throwable);
@@ -589,7 +569,6 @@
                         return Response.status(Response.Status.BAD_REQUEST).build();
                     }
                 }
-
                 if (!wrap.isInMappable() || !wrap.isWrapped()) {
                     // user failures (thrown from Resource methods or provider methods)
 
@@ -605,6 +584,55 @@
             throw originalThrowable;
         }
 
+        private Response processExceptionWithMapper(ExceptionMapper mapper,
+                                                                      Throwable throwable, long timestamp) {
+            processingContext.monitoringEventBuilder().setExceptionMapper(mapper);
+            processingContext.triggerEvent(RequestEvent.Type.EXCEPTION_MAPPER_FOUND);
+            try {
+                final Response mappedResponse = mapper.toResponse(throwable);
+
+                if (isTracingLoggingEnabled(mapper, throwable, tracingLogger)) {
+                    tracingLogger.logDuration(ServerTraceEvent.EXCEPTION_MAPPING,
+                            timestamp, mapper, throwable, throwable.getLocalizedMessage(),
+                            mappedResponse != null ? mappedResponse.getStatusInfo() : "-no-response-");
+                }
+
+                // set mapped throwable
+                processingContext.routingContext().setMappedThrowable(throwable);
+
+                if (mappedResponse != null) {
+                    // response successfully mapped
+                    if (LOGGER.isLoggable(Level.FINER)) {
+                        final String message = String.format(
+                                "Exception '%s' has been mapped by '%s' to response '%s' (%s:%s).",
+                                throwable.getLocalizedMessage(),
+                                mapper.getClass().getName(),
+                                mappedResponse.getStatusInfo().getReasonPhrase(),
+                                mappedResponse.getStatusInfo().getStatusCode(),
+                                mappedResponse.getStatusInfo().getFamily());
+                        LOGGER.log(Level.FINER, message);
+                    }
+                    return mappedResponse;
+                } else {
+                    return Response.noContent().build();
+                }
+            } catch (final Throwable mapperThrowable) {
+                // spec: If the exception mapping provider throws an exception while creating a Response
+                // then return a server error (status code 500) response to the client.
+                LOGGER.log(Level.SEVERE, LocalizationMessages.EXCEPTION_MAPPER_THROWS_EXCEPTION(mapper.getClass()),
+                        mapperThrowable);
+                LOGGER.log(Level.SEVERE, LocalizationMessages.EXCEPTION_MAPPER_FAILED_FOR_EXCEPTION(), throwable);
+                return Response.serverError().build();
+            }
+        }
+
+        private ContainerResponse processResponseWithDefaultExceptionMapper(Throwable exception,
+                                                                            ContainerRequest request) {
+            long timestamp = tracingLogger.timestamp(ServerTraceEvent.EXCEPTION_MAPPING);
+            final Response response = processExceptionWithMapper(DEFAULT_EXCEPTION_MAPPER, exception, timestamp);
+            return processResponse(preProcessResponse(response, request), exception);
+        }
+
         private ContainerResponse writeResponse(final ContainerResponse response) {
             final ContainerRequest request = processingContext.request();
             final ContainerResponseWriter writer = request.getResponseWriter();
@@ -736,16 +764,14 @@
                     .setResponseWritten(true);
         }
 
-        private void release(final ContainerResponse responseContext) {
+        private void release(final ContainerResponse... responseContexts) {
             try {
                 processingContext.closeableService().close();
 
                 // Commit the container response writer if not in chunked mode
                 // responseContext may be null in case the request processing was cancelled.
-                if (responseContext != null && !responseContext.isChunked()) {
-                    // responseContext.commitStream();
-                    responseContext.close();
-                }
+                Arrays.stream(responseContexts).filter(responseContext -> responseContext != null
+                        && !responseContext.isChunked()).forEach(ContainerResponse::close);
 
             } catch (final Throwable throwable) {
                 LOGGER.log(Level.WARNING, LocalizationMessages.RELEASING_REQUEST_PROCESSING_RESOURCES_FAILED(), throwable);
@@ -754,6 +780,14 @@
                 processingContext.triggerEvent(RequestEvent.Type.FINISHED);
             }
         }
+
+        private static boolean isTracingLoggingEnabled(ExceptionMapper mapper, Throwable throwable, TracingLogger tracingLogger) {
+            boolean defaultLoggingState = mapper instanceof DefaultExceptionMapper
+                    && throwable instanceof WebApplicationException;
+            return !defaultLoggingState
+                    && tracingLogger.isLogEnabled(ServerTraceEvent.EXCEPTION_MAPPING);
+
+        }
     }
 
     private static class AsyncResponder implements AsyncContext, ContainerResponseWriter.TimeoutHandler, CompletionCallback {
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/WebServerFactory.java b/core-server/src/main/java/org/glassfish/jersey/server/WebServerFactory.java
new file mode 100644
index 0000000..2b61d4a
--- /dev/null
+++ b/core-server/src/main/java/org/glassfish/jersey/server/WebServerFactory.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.server;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.internal.ServiceFinder;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+
+/**
+ * Factory for creating specific HTTP servers.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class WebServerFactory {
+
+    /**
+     * Prevents instantiation.
+     */
+    private WebServerFactory() {
+    }
+
+    /**
+     * Creates a server of a given type which runs the given application using the
+     * given bootstrap configuration.
+     * <p>
+     * The list of service-providers supporting the {@link WebServerProvider}
+     * service-provider will be iterated over until one returns a non-null server
+     * instance.
+     * <p>
+     *
+     * @param <T>
+     *            the type of the server.
+     * @param type
+     *            the type of the server. Providers SHOULD support at least
+     *            {@link WebServer}.
+     * @param application
+     *            The application to host.
+     * @param configuration
+     *            The configuration (host, port, etc.) to be used for bootstrapping.
+     * @return the created server.
+     * @throws ProcessingException
+     *             if there is an error creating the server.
+     * @throws IllegalArgumentException
+     *             if no server provider supports the type.
+     */
+    public static <T extends WebServer> T createServer(final Class<T> type, final Application application,
+                                                       final SeBootstrap.Configuration configuration) {
+        for (final WebServerProvider webServerProvider : ServiceFinder.find(WebServerProvider.class)) {
+            final T server = webServerProvider.createServer(type, application, configuration);
+            if (server != null) {
+                return server;
+            }
+        }
+
+        throw new IllegalArgumentException("No server provider supports the type " + type);
+    }
+
+    /**
+     * Creates a server of a given type which runs the given application using the
+     * given bootstrap configuration.
+     * <p>
+     * The list of service-providers supporting the {@link WebServerProvider}
+     * service-provider will be iterated over until one returns a non-null server
+     * instance.
+     * <p>
+     *
+     * @param <T>
+     *            the type of the server.
+     * @param type
+     *            the type of the server. Providers SHOULD support at least
+     *            {@link WebServer}.
+     * @param application
+     *            The application to host.
+     * @param configuration
+     *            The configuration (host, port, etc.) to be used for bootstrapping.
+     * @return the created server.
+     * @throws ProcessingException
+     *             if there is an error creating the server.
+     * @throws IllegalArgumentException
+     *             if no server provider supports the type.
+     */
+    public static <T extends WebServer> T createServer(final Class<T> type, final Class<? extends Application> application,
+                                                       final SeBootstrap.Configuration configuration) {
+        for (final WebServerProvider webServerProvider : ServiceFinder.find(WebServerProvider.class)) {
+            final T server = webServerProvider.createServer(type, application, configuration);
+            if (server != null) {
+                return server;
+            }
+        }
+
+        throw new IllegalArgumentException("No server provider supports the type " + type);
+    }
+
+}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/RuntimeDelegateImpl.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/RuntimeDelegateImpl.java
index ab70a02..bfaad0e 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/RuntimeDelegateImpl.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/RuntimeDelegateImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,16 +16,26 @@
 
 package org.glassfish.jersey.server.internal;
 
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+
+import jakarta.ws.rs.SeBootstrap;
 import jakarta.ws.rs.core.Application;
 
 import org.glassfish.jersey.internal.AbstractRuntimeDelegate;
 import org.glassfish.jersey.message.internal.MessagingBinders;
 import org.glassfish.jersey.server.ContainerFactory;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.WebServerFactory;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.spi.WebServer;
 
 /**
  * Server-side implementation of JAX-RS {@link jakarta.ws.rs.ext.RuntimeDelegate}.
- * This overrides the default implementation of {@link jakarta.ws.rs.ext.RuntimeDelegate} from
- * jersey-common which does not implement {@link #createEndpoint(jakarta.ws.rs.core.Application, java.lang.Class)}
+ * This overrides the default implementation of
+ * {@link jakarta.ws.rs.ext.RuntimeDelegate} from jersey-common which does not
+ * implement
+ * {@link #createEndpoint(jakarta.ws.rs.core.Application, java.lang.Class)}
  * method.
  *
  * @author Jakub Podlesak
@@ -39,11 +49,84 @@
     }
 
     @Override
-    public <T> T createEndpoint(Application application, Class<T> endpointType)
+    public <T> T createEndpoint(final Application application, final Class<T> endpointType)
             throws IllegalArgumentException, UnsupportedOperationException {
         if (application == null) {
             throw new IllegalArgumentException("application is null.");
         }
         return ContainerFactory.createContainer(endpointType, application);
     }
+
+    @Override
+    public JerseySeBootstrapConfiguration.Builder createConfigurationBuilder() {
+        return JerseySeBootstrapConfiguration.builder();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public CompletableFuture<SeBootstrap.Instance> bootstrap(final Application application,
+            final SeBootstrap.Configuration configuration) {
+
+        return CompletableFuture.supplyAsync(() -> {
+            final Class<WebServer> httpServerClass = configuration.hasProperty(ServerProperties.WEBSERVER_CLASS)
+                    ? (Class<WebServer>) configuration.property(ServerProperties.WEBSERVER_CLASS)
+                    : WebServer.class;
+
+            final WebServer webServer
+                    = WebServerFactory.createServer(httpServerClass, application, configuration);
+            return instance(configuration, webServer);
+        });
+    }
+
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<SeBootstrap.Instance> bootstrap(final Class<? extends Application> applicationClass,
+                                                             final SeBootstrap.Configuration configuration) {
+
+        return CompletableFuture.supplyAsync(() -> {
+            final Class<WebServer> httpServerClass = configuration.hasProperty(ServerProperties.WEBSERVER_CLASS)
+                    ? (Class<WebServer>) configuration.property(ServerProperties.WEBSERVER_CLASS)
+                    : WebServer.class;
+
+            final WebServer webServer
+                    = WebServerFactory.createServer(httpServerClass, applicationClass, configuration);
+            return instance(configuration, webServer);
+        });
+    }
+
+    private SeBootstrap.Instance instance(final SeBootstrap.Configuration configuration,
+                                          final WebServer _webServer) {
+        return new SeBootstrap.Instance() {
+            final WebServer webServer = _webServer;
+            @Override
+            public final JerseySeBootstrapConfiguration configuration() {
+                return JerseySeBootstrapConfiguration.from(name -> {
+                    switch (name) {
+                        case SeBootstrap.Configuration.PORT:
+                            return webServer.port();
+                        case ServerProperties.WEBSERVER_CLASS:
+                            return webServer.getClass();
+                        default:
+                            return configuration.property(name);
+                    }
+                });
+            }
+
+            @Override
+            public final CompletionStage<StopResult> stop() {
+                return this.webServer.stop().thenApply(nativeResult -> new StopResult() {
+
+                    @Override
+                    public final <T> T unwrap(final Class<T> nativeClass) {
+                        return nativeClass.cast(nativeResult);
+                    }
+                });
+            }
+
+            @Override
+            public final <T> T unwrap(final Class<T> nativeClass) {
+                return nativeClass.isInstance(this.webServer) ? nativeClass.cast(this.webServer)
+                        : this.webServer.unwrap(nativeClass);
+            }
+        };
+    }
 }
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/FormParamValueParamProvider.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/FormParamValueParamProvider.java
index f1fcbeb..73c9684 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/FormParamValueParamProvider.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/FormParamValueParamProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,19 +16,26 @@
 
 package org.glassfish.jersey.server.internal.inject;
 
+import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.net.URLDecoder;
 import java.net.URLEncoder;
+import java.security.AccessController;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.BiFunction;
 import java.util.function.Function;
 
 import jakarta.ws.rs.Encoded;
 import jakarta.ws.rs.FormParam;
 import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.EntityPart;
 import jakarta.ws.rs.core.Form;
+import jakarta.ws.rs.core.GenericType;
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.MultivaluedMap;
@@ -37,7 +44,13 @@
 import jakarta.inject.Singleton;
 
 import org.glassfish.jersey.internal.inject.ExtractorException;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.Providers;
+import org.glassfish.jersey.internal.util.ReflectionHelper;
+import org.glassfish.jersey.internal.util.collection.LazyValue;
 import org.glassfish.jersey.internal.util.collection.NullableMultivaluedHashMap;
+import org.glassfish.jersey.internal.util.collection.Value;
+import org.glassfish.jersey.internal.util.collection.Values;
 import org.glassfish.jersey.message.internal.MediaTypes;
 import org.glassfish.jersey.message.internal.ReaderWriter;
 import org.glassfish.jersey.server.ContainerRequest;
@@ -45,6 +58,7 @@
 import org.glassfish.jersey.server.internal.InternalServerProperties;
 import org.glassfish.jersey.server.internal.LocalizationMessages;
 import org.glassfish.jersey.server.model.Parameter;
+import org.glassfish.jersey.server.spi.internal.ValueParamProvider;
 
 /**
  * Value factory provider supporting the {@link FormParam} injection annotation.
@@ -55,13 +69,17 @@
 @Singleton
 final class FormParamValueParamProvider extends AbstractValueParamProvider {
 
+    private final MultipartFormParamValueProvider multipartProvider;
     /**
      * Injection constructor.
      *
      * @param mpep extractor provider.
+     * @param injectionManager
      */
-    public FormParamValueParamProvider(Provider<MultivaluedParameterExtractorProvider> mpep) {
+    public FormParamValueParamProvider(Provider<MultivaluedParameterExtractorProvider> mpep,
+                                       InjectionManager injectionManager) {
         super(mpep, Parameter.Source.FORM);
+        this.multipartProvider = new MultipartFormParamValueProvider(injectionManager);
     }
 
     @Override
@@ -73,22 +91,37 @@
             return null;
         }
 
+        if (EntityPart.class == parameter.getType()) {
+            return new Function<ContainerRequest, Object>() {
+                @Override
+                public Object apply(ContainerRequest containerRequest) {
+                    return multipartProvider.getEntityPart(containerRequest, parameter);
+                }
+            };
+        }
+
         MultivaluedParameterExtractor e = get(parameter);
         if (e == null) {
             return null;
         }
-        return new FormParamValueProvider(e, !parameter.isEncoded());
+        return new FormParamValueProvider(e, multipartProvider, !parameter.isEncoded(), parameter);
     }
 
     private static final class FormParamValueProvider implements Function<ContainerRequest, Object> {
 
         private static final Annotation encodedAnnotation = getEncodedAnnotation();
         private final MultivaluedParameterExtractor<?> extractor;
+        private final MultipartFormParamValueProvider multipartProvider;
         private final boolean decode;
+        private final Parameter parameter;
 
-        FormParamValueProvider(MultivaluedParameterExtractor<?> extractor, boolean decode) {
+        FormParamValueProvider(MultivaluedParameterExtractor<?> extractor,
+                               MultipartFormParamValueProvider multipartProvider,
+                               boolean decode, Parameter parameter) {
             this.extractor = extractor;
+            this.multipartProvider = multipartProvider;
             this.decode = decode;
+            this.parameter = parameter;
         }
 
         private static Form getCachedForm(final ContainerRequest request, boolean decode) {
@@ -121,24 +154,27 @@
 
         @Override
         public Object apply(ContainerRequest request) {
-            Form form = getCachedForm(request, decode);
+            if (MediaTypes.typeEqual(MediaType.MULTIPART_FORM_DATA_TYPE, request.getMediaType())) {
+                return multipartProvider.apply(request, parameter);
+            } else {
+                Form form = getCachedForm(request, decode);
 
-            if (form == null) {
-                Form otherForm = getCachedForm(request, !decode);
-                if (otherForm != null) {
-                    form = switchUrlEncoding(request, otherForm);
-                    cacheForm(request, form);
-                } else {
-                    form = getForm(request);
+                if (form == null) {
+                    Form otherForm = getCachedForm(request, !decode);
+                    if (otherForm != null) {
+                        form = switchUrlEncoding(request, otherForm);
+                    } else {
+                        form = getForm(request);
+                    }
                     cacheForm(request, form);
                 }
-            }
 
-            try {
-                return extractor.extract(form.asMap());
-            } catch (ExtractorException e) {
-                throw new ParamException.FormParamException(e.getCause(),
-                        extractor.getName(), extractor.getDefaultValueString());
+                try {
+                    return extractor.extract(form.asMap());
+                } catch (ExtractorException e) {
+                    throw new ParamException.FormParamException(e.getCause(),
+                            extractor.getName(), extractor.getDefaultValueString());
+                }
             }
         }
 
@@ -199,4 +235,96 @@
             }
         }
     }
+
+    @Singleton
+    private static class MultipartFormParamValueProvider implements BiFunction<ContainerRequest, Parameter, Object> {
+        private static final class FormParamHolder {
+            @FormParam("name")
+            public static final Void dummy = null; // field to get an instance of FormParam annotation
+        }
+        private static Parameter entityPartParameter =
+                Parameter.create(
+                        EntityPart.class, EntityPart.class, false, EntityPart.class, EntityPart.class,
+                        AccessController.doPrivileged(ReflectionHelper.getDeclaredFieldsPA(FormParamHolder.class))[0]
+                            .getAnnotations()
+                );
+
+        private final InjectionManager injectionManager;
+        private final LazyValue<ValueParamProvider> entityPartProvider;
+
+        private MultipartFormParamValueProvider(InjectionManager injectionManager) {
+            this.injectionManager = injectionManager;
+
+            //Get the provider from jersey-media-multipart
+            entityPartProvider = Values.lazy((Value<ValueParamProvider>) () -> {
+                Set<ValueParamProvider> providers = Providers.getProviders(injectionManager, ValueParamProvider.class);
+                for (ValueParamProvider vfp : providers) {
+                    Function<ContainerRequest, ?> paramValueSupplier = vfp.getValueProvider(entityPartParameter);
+                    if (paramValueSupplier != null && !FormParamValueParamProvider.class.isInstance(vfp)) {
+                        return vfp;
+                    }
+                }
+                return null;
+            });
+        }
+
+        @Override
+        public Object apply(ContainerRequest containerRequest, Parameter parameter) {
+            Object entity = null;
+            final EntityPart entityPart = getEntityPart(containerRequest, parameter);
+            if (entityPart != null) { // else jersey-multipart module is missing
+                try {
+                    entity = parameter.getType() != parameter.getRawType()
+                            ? entityPart.getContent(genericType(parameter.getRawType(), parameter.getType()))
+                            : entityPart.getContent(parameter.getRawType());
+                } catch (IOException e) {
+                    throw new ProcessingException(e);
+                }
+            }
+
+            return entity;
+        }
+
+        private EntityPart getEntityPart(ContainerRequest containerRequest, Parameter parameter) {
+            final ValueParamProvider valueParamProvider = entityPartProvider.get();
+            if (valueParamProvider != null) { // else jersey-multipart module is missing
+                final Function<ContainerRequest, ?> valueSupplier = valueParamProvider.getValueProvider(
+                        new WrappingFormParamParameter(entityPartParameter, parameter));
+                return (EntityPart) valueSupplier.apply(containerRequest);
+            }
+            return null;
+        }
+
+        private GenericType genericType(Type rawType, Type genericType) {
+            return new GenericType(new ParameterizedType() {
+                @Override
+                public Type[] getActualTypeArguments() {
+                    return new Type[]{genericType};
+                }
+
+                @Override
+                public Type getRawType() {
+                    return rawType;
+                }
+
+                @Override
+                public Type getOwnerType() {
+                    return null;
+                }
+            });
+        }
+
+        private static class WrappingFormParamParameter extends Parameter {
+            protected WrappingFormParamParameter(Parameter entityPartDataParam, Parameter realDataParam) {
+                super(realDataParam.getAnnotations(),
+                        realDataParam.getSourceAnnotation(),
+                        realDataParam.getSource(),
+                        realDataParam.getSourceName(),
+                        entityPartDataParam.getRawType(),
+                        entityPartDataParam.getType(),
+                        realDataParam.isEncoded(),
+                        realDataParam.getDefaultValue());
+            }
+        }
+    }
 }
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ValueParamProviderConfigurator.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ValueParamProviderConfigurator.java
index b9ddc55..07337eb 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ValueParamProviderConfigurator.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/inject/ValueParamProviderConfigurator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -87,7 +87,7 @@
         EntityParamValueParamProvider entityProvider = new EntityParamValueParamProvider(paramExtractor);
         suppliers.add(entityProvider);
 
-        FormParamValueParamProvider formProvider = new FormParamValueParamProvider(paramExtractor);
+        FormParamValueParamProvider formProvider = new FormParamValueParamProvider(paramExtractor, injectionManager);
         suppliers.add(formProvider);
 
         HeaderParamValueParamProvider headerProvider = new HeaderParamValueParamProvider(paramExtractor);
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/spi/WebServer.java b/core-server/src/main/java/org/glassfish/jersey/server/spi/WebServer.java
new file mode 100644
index 0000000..731e4eb
--- /dev/null
+++ b/core-server/src/main/java/org/glassfish/jersey/server/spi/WebServer.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.server.spi;
+
+import java.util.concurrent.CompletionStage;
+
+import jakarta.ws.rs.ConstrainedTo;
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.spi.Contract;
+
+/**
+ * Jersey service contract for self-contained servers.
+ * <p>
+ *      Runs a self-contained {@link Application} in a {@link Container} using a
+ *      Web Server implicitly started and stopped together with the application.
+ * </p>
+ * <p>
+ *     The WebServer instance is wrapped by the implementation of {@link jakarta.ws.rs.SeBootstrap.Instance}.
+ * </p>
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+@Contract
+@ConstrainedTo(RuntimeType.SERVER)
+public interface WebServer {
+
+    /**
+     * @return container in which the application lives.
+     */
+    public Container container();
+
+    /**
+     * @return IP port the application listens to for requests.
+     */
+    public int port();
+
+    /**
+     * Initiates server bootstrap.
+     * <p>
+     * Startup happens in background. The completion stage produces a native startup
+     * result.
+     * </p>
+     * <p>
+     * Portable applications should not expect any particular result type, as it is
+     * implementation-specific.
+     * </p>
+     *
+     * @return A {@link CompletionStage} providing a native startup result of the
+     *         bootstrap process. The native result MAY be {@code null}.
+     */
+    public CompletionStage<?> start();
+
+    /**
+     * Initiates server shutdown.
+     * <p>
+     * Shutdown happens in background. The completion stage produces a native
+     * shutdown result.
+     * </p>
+     * </p>
+     * Portable applications should not expect any particular result type, as it is
+     * implementation-specific.
+     * </p>
+     *
+     * @return A {@link CompletionStage} providing a native shutdown result of the
+     *         shutdown process. The native result MAY be {@code null}.
+     */
+    public CompletionStage<?> stop();
+
+    /**
+     * Provides access to the native handle(s) of the server, if it holds at least
+     * one.
+     * <p>
+     * Implementations MAY use native handles to identify the server instance, and /
+     * or use those to communicate with and control the instance. Whether or not
+     * such handles exist, and their respective data types, is
+     * implementation-specific.
+     * </p>
+     * <p>
+     * Portable applications should not invoke this method, as the types of
+     * supported handles are implementation-specific.
+     * </p>
+     *
+     * @param nativeClass
+     *            The class of the native handle.
+     * @return The native handle, or {@code null} if no handle of this type exists.
+     */
+    public <T> T unwrap(Class<T> nativeClass);
+
+}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/spi/WebServerProvider.java b/core-server/src/main/java/org/glassfish/jersey/server/spi/WebServerProvider.java
new file mode 100644
index 0000000..d1d5d2c
--- /dev/null
+++ b/core-server/src/main/java/org/glassfish/jersey/server/spi/WebServerProvider.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.server.spi;
+
+import jakarta.ws.rs.ConstrainedTo;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.server.ApplicationHandler;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.spi.Contract;
+
+/**
+ * Service-provider interface for creating server instances.
+ *
+ * If supported by the provider, a server instance of the requested Java type
+ * will be created.
+ * <p>
+ * The created server uses an internally created {@link Container} which is
+ * responsible for listening on a communication channel provided by the server
+ * for new client requests, dispatching these requests to the registered
+ * {@link ApplicationHandler Jersey application handler} using the handler's
+ * {@link ApplicationHandler#handle(org.glassfish.jersey.server.ContainerRequest)
+ * handle(requestContext)} method and sending the responses provided by the
+ * application back to the client.
+ * </p>
+ * <p>
+ * A provider shall support a one-to-one mapping between a type, provided the
+ * type is not {@link Object}. A provider may also support mapping of sub-types
+ * of a type (provided the type is not {@code Object}). It is expected that each
+ * provider supports mapping for distinct set of types and subtypes so that
+ * different providers do not conflict with each other. In addition, a provider
+ * SHOULD support the super type {@link WebServer} to participate in auto-selection
+ * of providers (in this case the <em>first</em> supporting provider found is
+ * used).
+ * </p>
+ * <p>
+ * An implementation can identify itself by placing a Java service provider
+ * configuration file (if not already present) -
+ * {@code org.glassfish.jersey.server.spi.WebServerProvider} - in the resource
+ * directory {@code META-INF/services}, and adding the fully qualified
+ * service-provider-class of the implementation in the file.
+ * </p>
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+@Contract
+@ConstrainedTo(RuntimeType.SERVER)
+public interface WebServerProvider {
+
+    /**
+     * Creates a server of a given type which runs the given application using the
+     * given bootstrap configuration.
+     *
+     * @param <T>
+     *            the type of the web server.
+     * @param type
+     *            the type of the web server. Providers SHOULD support at least
+     *            {@link WebServer}.
+     * @param application
+     *            The application to host.
+     * @param configuration
+     *            The configuration (host, port, etc.) to be used for bootstrapping.
+     * @return the server, otherwise {@code null} if the provider does not support
+     *         the requested {@code type}.
+     * @throws ProcessingException
+     *             if there is an error creating the server.
+     */
+    <T extends WebServer> T createServer(Class<T> type,
+                                         Application application,
+                                         SeBootstrap.Configuration configuration) throws ProcessingException;
+
+    /**
+     * Creates a server of a given type which runs the given application using the
+     * given bootstrap configuration.
+     *
+     * @param <T>
+     *            the type of the web server.
+     * @param type
+     *            the type of the web server. Providers SHOULD support at least
+     *            {@link WebServer}.
+     * @param applicationClass
+     *            The class of application to host.
+     * @param configuration
+     *            The configuration (host, port, etc.) to be used for bootstrapping.
+     * @return the server, otherwise {@code null} if the provider does not support
+     *         the requested {@code type}.
+     * @throws ProcessingException
+     *             if there is an error creating the server.
+     */
+    <T extends WebServer> T createServer(Class<T> type,
+                                         Class<? extends Application> applicationClass,
+                                         SeBootstrap.Configuration configuration) throws ProcessingException;
+
+
+    /**
+     * Utility function that matches {@code WebServerProvider} supported type with the user type passed either
+     * as {@link ServerProperties#WEBSERVER_CLASS} property (higher priority) or by the {@code userType} argument
+     * (lower priority).
+     * @param supportedType The type supported by the {@code WebServerProvider} implementation
+     * @param userType The user type passed in by the user, usually {@link WebServer} class.
+     * @param configuration The configuration to check {@link ServerProperties#WEBSERVER_CLASS} property
+     * @param <T> The {@link WebServer} subtype
+     * @return @{code true} if the user provided type matches the supported type.
+     */
+    static <T extends WebServer> boolean isSupportedWebServer(
+            Class<? extends WebServer> supportedType, Class<T> userType, SeBootstrap.Configuration configuration) {
+        final Object webServerObj = configuration.property(ServerProperties.WEBSERVER_CLASS);
+        final Class<? extends WebServer> webServerCls = webServerObj == null || WebServer.class.equals(webServerObj)
+                ? null : (Class<? extends WebServer>) webServerObj;
+        // WebServer.class.equals(webServerObj) is the default, and then we want userType
+        return (webServerCls != null  && webServerCls.isAssignableFrom(supportedType))
+                || (webServerCls == null && userType.isAssignableFrom(supportedType));
+    }
+}
diff --git a/core-server/src/main/resources/org/glassfish/jersey/server/internal/localization.properties b/core-server/src/main/resources/org/glassfish/jersey/server/internal/localization.properties
index 3e0ab6c..7a482f2 100644
--- a/core-server/src/main/resources/org/glassfish/jersey/server/internal/localization.properties
+++ b/core-server/src/main/resources/org/glassfish/jersey/server/internal/localization.properties
@@ -33,6 +33,7 @@
 closeable.unable.to.close=Error while closing {0}.
 collection.extractor.type.unsupported=Unsupported collection type.
 contract.cannot.be.bound.to.resource.method=The given contract ({0}) of {1} provider cannot be bound to a resource method.
+could.not.bind.to.any.port=Could not bind to any port.
 default.could.not.process.method=Default value, {0} could not be processed by method {1}.
 error.async.callback.failed=Callback {0} invocation failed.
 error.committing.output.stream=Error while committing the output stream.
@@ -40,7 +41,7 @@
 error.closing.finder=Error while closing {0} resource finder.
 error.exception.mapping.original.exception=An exception mapping did not successfully produce and processed a response. Logging the original error.
 error.exception.mapping.processed.response.error=A response error mapping did not successfully produce and processed a response.
-error.exception.mapping.thrown.to.container=An exception mapping did not successfully produce and processed a response. Logging the exception propagated to the container.
+error.exception.mapping.thrown.to.container=An exception mapping did not successfully produce and processed a response. Logging the exception propagated to the default exception mapper.
 error.marshalling.jaxb=Error marshalling JAXB object of type "{0}".
 error.msg=ERROR: {0}
 error.monitoring.statistics.generation=Error generating monitoring statistics.
@@ -112,6 +113,7 @@
 event.sink.returns.type=A HTTP GET method {0} that is being injected with SseEventSink should return void. The output will propagate automatically.
 multiple.event.sink.injection=A HTTP GET method {0} defines to SseEventSink parameters to be injected. Only one of the injected event sinks will be connected to the output.
 chunked.output.closed=This chunked output has been closed.
+ignore.sebootstrap.configuration.property="SeBootstrap.Configuration property {0} is not of expected type {1} and it is ignored.
 illegal.client.config.class.property.value="{0}" property value ({1}) does not represent a valid client configuration class. Falling back to "{2}".
 init.msg=Initiating Jersey application, version {0}...
 injected.webtarget.uri.invalid="@Uri" annotation value is not a valid URI template: "{0}"
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/DefaultExceptionMapperTest.java b/core-server/src/test/java/org/glassfish/jersey/server/DefaultExceptionMapperTest.java
new file mode 100644
index 0000000..2f9b346
--- /dev/null
+++ b/core-server/src/test/java/org/glassfish/jersey/server/DefaultExceptionMapperTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.server;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.container.AsyncResponse;
+import jakarta.ws.rs.container.CompletionCallback;
+import jakarta.ws.rs.container.Suspended;
+import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.internal.ExceptionMapperFactory;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class DefaultExceptionMapperTest {
+    public static final String MESSAGE = "DefaultExceptionMapperTest I/O Exception";
+    @Test
+    public void testIOException() {
+        IOException ioe = new IOException(MESSAGE);
+        DefaultExceptionMapper mapper = new DefaultExceptionMapper();
+        Response response = mapper.toResponse(ioe);
+        assertThat(response.getEntity().toString().contains(MESSAGE)).isFalse();
+    }
+
+    @Test
+    public void testCompletionCallback() {
+        AtomicInteger counter = new AtomicInteger();
+        CompletionCallback hitOnceCallback = new CompletionCallback() {
+            @Override
+            public void onComplete(Throwable throwable) {
+                counter.incrementAndGet();
+            }
+        };
+        ResourceConfig resourceConfig = new ResourceConfig().register(new IOExThrowingResource(hitOnceCallback));
+        ApplicationHandler applicationHandler = new ApplicationHandler(resourceConfig);
+        try {
+            applicationHandler.apply(RequestContextBuilder.from("/", "GET").build()).get();
+        } catch (Exception e) {
+            // expected
+        }
+
+        assertEquals(1, counter.get());
+    }
+
+    @Test
+    public void testDefaultExceptionMapperNotRegisteredInExceptionMapperFactory() {
+        ResourceConfig resourceConfig = new ResourceConfig();
+        ApplicationHandler applicationHandler = new ApplicationHandler(resourceConfig);
+
+        // use InjectionManager from ApplicationHandler to set up the default bindings
+        ExceptionMapperFactory exceptionMapperFactory = new ExceptionMapperFactory(applicationHandler.getInjectionManager());
+
+        assertThat(exceptionMapperFactory.find(Throwable.class)).isNull();
+    }
+
+    @Path("/")
+    public static class IOExThrowingResource {
+        private final CompletionCallback callback;
+
+        public IOExThrowingResource(CompletionCallback callback) {
+            this.callback = callback;
+        }
+
+        @GET
+        public String doGet(@Suspended AsyncResponse asyncResponse) throws IOException {
+            asyncResponse.register(callback);
+            throw new IOException(MESSAGE);
+        }
+    }
+}
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/internal/RuntimeDelegateImplTest.java b/core-server/src/test/java/org/glassfish/jersey/server/internal/RuntimeDelegateImplTest.java
index 3b81936..9aa7419 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/internal/RuntimeDelegateImplTest.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/internal/RuntimeDelegateImplTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,11 +16,17 @@
 
 package org.glassfish.jersey.server.internal;
 
+import jakarta.ws.rs.SeBootstrap;
 import jakarta.ws.rs.core.Application;
 import jakarta.ws.rs.ext.RuntimeDelegate;
 
 import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
 import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
 /**
@@ -43,8 +49,64 @@
         }
     }
 
+    /**
+     * Checks that the right RuntimeDelegateImpl is loaded by JAX-RS.
+     */
     @Test
     public void testRuntimeDelegateInstance() {
         assertSame(RuntimeDelegateImpl.class, RuntimeDelegate.getInstance().getClass());
     }
+
+    @Test
+    public final void shouldCreateConfigurationBuilder() {
+        // given
+        final RuntimeDelegate runtimeDelegate = new RuntimeDelegateImpl();
+        // when
+        final SeBootstrap.Configuration.Builder configurationBuilder = runtimeDelegate.createConfigurationBuilder();
+        // then
+        assertThat(configurationBuilder, is(notNullValue()));
+    }
+
+    @Test
+    public final void shouldBuildDefaultConfiguration() {
+        // given
+        final SeBootstrap.Configuration.Builder configurationBuilder = new RuntimeDelegateImpl().createConfigurationBuilder();
+        // when
+        final SeBootstrap.Configuration configuration = configurationBuilder.build();
+
+        // then
+        assertThat(configuration, is(notNullValue()));
+        assertTrue(configuration.hasProperty(SeBootstrap.Configuration.PROTOCOL));
+        assertTrue(configuration.hasProperty(SeBootstrap.Configuration.HOST));
+        assertTrue(configuration.hasProperty(SeBootstrap.Configuration.PORT));
+        assertTrue(configuration.hasProperty(SeBootstrap.Configuration.ROOT_PATH));
+        assertTrue(configuration.hasProperty(SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION));
+        assertTrue(configuration.hasProperty(SeBootstrap.Configuration.SSL_CONTEXT));
+        assertThat(configuration.property(SeBootstrap.Configuration.PROTOCOL), is("HTTP"));
+        assertThat(configuration.property(SeBootstrap.Configuration.HOST), is("localhost"));
+        assertThat(configuration.property(SeBootstrap.Configuration.PORT), is(SeBootstrap.Configuration.DEFAULT_PORT));
+        assertThat(configuration.property(SeBootstrap.Configuration.ROOT_PATH), is("/"));
+        assertThat(configuration.property(SeBootstrap.Configuration.SSL_CLIENT_AUTHENTICATION),
+                is(SeBootstrap.Configuration.SSLClientAuthentication.NONE));
+//        assertThat(configuration.property(SeBootstrap.Configuration.SSL_CONTEXT), is(theInstance(SSLContext.getDefault())));
+        assertThat(configuration.protocol(), is("HTTP"));
+        assertThat(configuration.host(), is("localhost"));
+        assertThat(configuration.port(), is(SeBootstrap.Configuration.DEFAULT_PORT));
+        assertThat(configuration.rootPath(), is("/"));
+        assertThat(configuration.sslClientAuthentication(), is(SeBootstrap.Configuration.SSLClientAuthentication.NONE));
+//        assertThat(configuration.sslContext(), is(theInstance(SSLContext.getDefault())));
+    }
+
+    @Test
+    public final void shouldBuildConfigurationContainingCustomProperties() {
+        // given
+        final SeBootstrap.Configuration.Builder configurationBuilder = new RuntimeDelegateImpl().createConfigurationBuilder();
+        // when
+        final SeBootstrap.Configuration configuration = configurationBuilder.property("property", "value").build();
+
+        // then
+        assertThat(configuration, is(notNullValue()));
+        assertTrue(configuration.hasProperty("property"));
+        assertThat(configuration.property("property"), is("value"));
+    }
 }
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java b/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java
index 8413a07..9e53639 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java
@@ -17,6 +17,8 @@
 
 package org.glassfish.jersey.server.internal.inject;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
@@ -51,6 +53,7 @@
 import org.glassfish.jersey.server.RequestContextBuilder;
 import org.glassfish.jersey.server.ResourceConfig;
 
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -304,6 +307,24 @@
         }
     }
 
+    @Path("/")
+    public static class InpuStreamConverterTestResource {
+        @GET
+        public String inputStream(@QueryParam("param") InputStream inputStream) throws IOException {
+            return new String(inputStream.readAllBytes());
+        }
+    }
+
+    @Test
+    public void inputStreamTest() throws ExecutionException, InterruptedException {
+        initiateWebApplication(InpuStreamConverterTestResource.class);
+
+        final ContainerResponse responseContext = getResponseContext(UriBuilder.fromPath("/")
+                .queryParam("param", "Hello").build().toString());
+
+        Assertions.assertEquals("Hello", responseContext.getEntity());
+    }
+
     public static class MyEagerParamProvider implements ParamConverterProvider {
 
         @Override
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/model/MethodListTest.java b/core-server/src/test/java/org/glassfish/jersey/server/model/MethodListTest.java
index b618c59..78dff45 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/model/MethodListTest.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/model/MethodListTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -105,7 +105,7 @@
 
     @Test
     public void testSyntheticMethods() {
-        assertTrue(CSynthetic.CWithField.class.getDeclaredMethods().length == 2);
+        // assertEquals(2, CSynthetic.CWithField.class.getDeclaredMethods().length);
 
         MethodList ml = new MethodList(CSynthetic.CWithField.class, true);
         assertTrue(!ml.iterator().hasNext());
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/spi/WebServerProviderTest.java b/core-server/src/test/java/org/glassfish/jersey/server/spi/WebServerProviderTest.java
new file mode 100644
index 0000000..0176683
--- /dev/null
+++ b/core-server/src/test/java/org/glassfish/jersey/server/spi/WebServerProviderTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.server.spi;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+import org.glassfish.jersey.server.ServerProperties;
+import org.junit.jupiter.api.Test;
+
+import java.util.concurrent.CompletionStage;
+
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class WebServerProviderTest {
+    @Test
+    public void testPropertySetsDifferentClass() {
+        SeBootstrap.Configuration config =
+            SeBootstrap.Configuration.builder().property(ServerProperties.WEBSERVER_CLASS, WebServerTestImpl2.class).build();
+
+        assertNull(new WebServerProviderTestImpl().createServer(WebServerTestImpl.class, Application.class, config));
+    }
+
+    @Test
+    public void testPropertySetsCorrectClass() {
+        SeBootstrap.Configuration config =
+                SeBootstrap.Configuration.builder().property(ServerProperties.WEBSERVER_CLASS, WebServerTestImpl.class).build();
+
+        assertTrue(
+                WebServerTestImpl.class.isInstance(
+                        new WebServerProviderTestImpl().createServer(WebServerTestImpl2.class, Application.class, config)
+                )
+        );
+    }
+
+    @Test
+    public void testPropertySetsNothingUserTypeIsWrong() {
+        SeBootstrap.Configuration config =
+                SeBootstrap.Configuration.builder().build();
+
+        assertNull(new WebServerProviderTestImpl().createServer(WebServerTestImpl2.class, Application.class, config));
+    }
+
+    @Test
+    public void testPropertySetsNothingUserTypeIsCorrectClass() {
+        SeBootstrap.Configuration config =
+                SeBootstrap.Configuration.builder().build();
+
+        assertTrue(
+                WebServerTestImpl.class.isInstance(
+                        new WebServerProviderTestImpl().createServer(WebServerTestImpl.class, Application.class, config)
+                )
+        );
+    }
+
+    @Test
+    public void testPropertySetsNothingUserTypeIsSuperClass() {
+        SeBootstrap.Configuration config =
+                SeBootstrap.Configuration.builder().build();
+
+        assertTrue(
+                WebServerTestImpl.class.isInstance(
+                        new WebServerProviderTestImpl().createServer(WebServer.class, Application.class, config)
+                )
+        );
+    }
+
+    public static class WebServerProviderTestImpl implements WebServerProvider {
+
+        @Override
+        public <T extends WebServer> T createServer(
+                Class<T> type, Application application, SeBootstrap.Configuration configuration) throws ProcessingException {
+            if (WebServerProvider.isSupportedWebServer(WebServerTestImpl.class, type, configuration)) {
+                return (T) new WebServerTestImpl();
+            }
+            return null;
+        }
+
+        @Override
+        public <T extends WebServer> T createServer(
+                Class<T> type,
+                Class<? extends Application> applicationClass,
+                SeBootstrap.Configuration configuration) throws ProcessingException {
+            if (WebServerProvider.isSupportedWebServer(WebServerTestImpl.class, type, configuration)) {
+                return (T) new WebServerTestImpl();
+            }
+            return null;
+        }
+    }
+
+    public static class WebServerTestImpl implements WebServer {
+
+        @Override
+        public Container container() {
+            return null;
+        }
+
+        @Override
+        public int port() {
+            return 0;
+        }
+
+        @Override
+        public CompletionStage<?> start() {
+            return null;
+        }
+
+        @Override
+        public CompletionStage<?> stop() {
+            return null;
+        }
+
+        @Override
+        public <T> T unwrap(Class<T> nativeClass) {
+            return null;
+        }
+    }
+
+    public static class WebServerTestImpl2 implements WebServer {
+
+        @Override
+        public Container container() {
+            return null;
+        }
+
+        @Override
+        public int port() {
+            return 0;
+        }
+
+        @Override
+        public CompletionStage<?> start() {
+            return null;
+        }
+
+        @Override
+        public CompletionStage<?> stop() {
+            return null;
+        }
+
+        @Override
+        public <T> T unwrap(Class<T> nativeClass) {
+            return null;
+        }
+    };
+}
diff --git a/docs/pom.xml b/docs/pom.xml
index f73f210..c099bc2 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <artifactId>jersey-documentation</artifactId>
     <packaging>pom</packaging>
diff --git a/docs/src/main/docbook/appendix-properties.xml b/docs/src/main/docbook/appendix-properties.xml
index 9e7dc27..aa4aee9 100644
--- a/docs/src/main/docbook/appendix-properties.xml
+++ b/docs/src/main/docbook/appendix-properties.xml
@@ -786,6 +786,78 @@
         </table>
     </section>
 
+    <section xml:id="appendix-properties-webserver">
+        <title>SeBootstrap and WebServer related configuration properties</title>
+
+        <para>
+            List of SeBootstrap configuration properties that can be found in &jersey.server.ServerProperties; class.
+        </para>
+
+        <table>
+        <title>List of SeBootstrap and WebServer configuration properties</title>
+        <tgroup cols="3">
+        <thead>
+            <row>
+                <entry>Constant</entry>
+                <entry>Value</entry>
+                <entry>Description</entry>
+            </row>
+        </thead>
+        <tbody>
+            <row>
+                <entry>&jersey.server.ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS;</entry>
+                <entry><literal>jersey.config.server.bootstrap.webserver.allow.privileged.ports</literal></entry>
+                <entry>
+                    <para>
+                        Defines whether to allow privileged ports (0-1023) to be used to start the
+                        &lit.jersey.server.spi.WebServer; implementation to be chosen from the unused ports when the
+                        &lit.jaxrs.SeBootstrap.Configuration; PORT is set to <literal>-1</literal> or unset.
+                    </para>
+                    <para>
+                        The default ports are 80 for HTTP and 443 for HTTPS when
+                        <literal>WEBSERVER_ALLOW_PRIVILEGED_PORTS</literal> is &lit.true; or 8080 for HTTP and 8443 for HTTPS when
+                        <literal>WEBSERVER_ALLOW_PRIVILEGED_PORTS</literal> is &lit.false;.
+                    </para>
+                    <para>
+                        If &lit.jaxrs.SeBootstrap.Configuration; PORT is set to <literal>0</literal>, the implementation scans for
+                        random port (0-65535) when <literal>WEBSERVER_ALLOW_PRIVILEGED_PORTS</literal> is &lit.true;, or
+                        (1024-65535) when <literal>WEBSERVER_ALLOW_PRIVILEGED_PORTS</literal> is &lit.false;.
+                    </para>
+                    <para>
+                        The default this is &lit.false;. Use &lit.true; to allow a restricted port number.
+                    </para>
+                </entry>
+            </row>
+            <row>
+                <entry>&jersey.server.ServerProperties.WEBSERVER_AUTO_START;</entry>
+                <entry><literal>jersey.config.server.bootstrap.webserver.autostart</literal></entry>
+                <entry>
+                    <para>
+                        Whether to automatically startup <literal>WebServer</literal> at bootstrap.
+                    </para>
+                    <para>
+                        By default, servers are immediately listening to connections after bootstrap,
+                        so no explicit invocation of <literal>WebServer#start()</literal> is needed.
+                    </para>
+                </entry>
+            </row>
+            <row>
+                <entry>&jersey.server.ServerProperties.WEBSERVER_CLASS;</entry>
+                <entry><literal>jersey.config.server.bootstrap.webserver.class</literal></entry>
+                <entry>
+                    <para>
+                        Defines the implementation of <literal>WebServer</literal> to bootstrap.
+                    </para>
+                    <para>
+                        By default auto-selects the first server provider found.
+                    </para>
+                </entry>
+            </row>
+        </tbody>
+        </tgroup>
+        </table>
+    </section>
+
     <section xml:id="appendix-properties-servlet">
         <title>Servlet configuration properties</title>
 
@@ -1049,7 +1121,8 @@
                                     &jersey.apache5.Apache5ConnectorProvider;,
                                     &jersey.grizzly.GrizzlyConnectorProvider;,
                                     &jersey.helidon.HelidonConnectorProvider;,
-                                    &jersey.netty.NettyConnectorProvider;, and
+                                    &jersey.netty.NettyConnectorProvider;,
+                                    &jersey.jetty11.Jetty11ConnectorProvider;, and
                                     &jersey.jetty.JettyConnectorProvider; only.</emphasis>
                             </para>
                         </entry>
@@ -1137,6 +1210,23 @@
                         </entry>
                     </row>
                     <row>
+                        <entry>&jersey.client.ClientProperties.SNI_HOST_NAME;</entry>
+                        <entry><literal>jersey.config.client.sniHostName</literal></entry>
+                        <entry>
+                            <para>
+                                Most connectors support HOST header value to be used as an SNIHostName. However, the HOST header is restricted in JDK.
+                                <literal>HttpUrlConnector</literal> and <literal>JavaNetHttpConnector</literal> need
+                                an extra System Property set to allow HOST header.
+                                As an option to HOST header, this property allows the HOST name to be pre-set on a Client and does not need to
+                                be set on each request.
+                                <literal>Since 3.1.2</literal>
+                            </para>
+                            <para>
+                                The value MUST be an instance of &lit.jdk6.String;
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
                         <entry>&jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_CLIENT;
                         </entry>
                         <entry>
@@ -2113,4 +2203,108 @@
             </tgroup>
         </table>
     </section>
+    <section xml:id="appendix-properties-client-jnh">
+        <title>Java Net HTTP client configuration properties</title>
+
+        <para>
+            List of client configuration properties that can be found in &jersey.jnh.JavaNetHttpClientProperties; class.
+        </para>
+
+        <table>
+            <title>List of Java Net HTTP client configuration properties</title>
+            <tgroup cols="3">
+                <thead>
+                    <row>
+                        <entry>Constant</entry>
+                        <entry>Value</entry>
+                        <entry>Description</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>&jersey.jnh.JavaNetHttpClientProperties.COOKIE_HANDLER;</entry>
+                        <entry><literal>jersey.config.jnh.client.cookieHandler</literal></entry>
+                        <entry>
+                            <para>
+                                Configuration of the <literal>java.net.CookieHandler</literal> that should be used by the
+                                <literal>java.net.http.HttpClient</literal>. If this option is not set,
+                                <literal>java.net.http.HttpClient#cookieHandler()</literal> will return an empty
+                                <literal>java.util.Optional</literal> and therefore no cookie handler will be used.
+                            </para>
+                            <para>
+                                A provided value to this option has to be of type <literal>java.net.CookieHandler</literal>.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jnh.JavaNetHttpClientProperties.SSL_PARAMETERS;</entry>
+                        <entry><literal>jersey.config.jnh.client.sslParameters</literal></entry>
+                        <entry>
+                            <para>
+                                Configuration of SSL parameters used by the <literal>java.net.http.HttpClient</literal>.
+                                If this option is not set, then the <literal>java.net.http.HttpClient</literal> will use
+                                <it>implementation specific</it> default values.
+                            </para>
+                            <para>
+                                A provided value to this option has to be of type <literal>javax.net.ssl.SSLParameters</literal>.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jnh.JavaNetHttpClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION;</entry>
+                        <entry><literal>jersey.config.jnh.client.preemptiveBasicAuthentication</literal></entry>
+                        <entry>
+                            <para>
+                                An instance of the Authenticator class which represents an object that knows how to
+                                obtain authentication for a network connection should be used.
+                            </para>
+                            <para>
+                                If an <literal>java.net.Authenticator</literal> instance is found,
+                                it is then used for the given request.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>java.net.Authenticator</literal>.
+                                If the property is absent, no authentication is used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jnh.JavaNetHttpClientProperties.DISABLE_COOKIES;</entry>
+                        <entry><literal>jersey.config.jnh.client.disableCookies</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.false; indicates the client should handle cookies
+                                automatically using HttpClient's default cookie policy. A value
+                                of &lit.true; will cause the client to ignore all cookies.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>java.lang.Boolean</literal>.
+                            </para>
+                            <para>
+                                The default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jnh.JavaNetHttpClientProperties.HTTP_VERSION;</entry>
+                        <entry><literal>jersey.config.jnh.client.httpVersion</literal></entry>
+                        <entry>
+                            <para>
+                                HTTP version - if null or instance of HttpClient.Version.HTTP_1_1
+                                the version will be set to HTTP_1_1. If version is HttpClient.Version.HTTP_2
+                                the client will attempt to perform each request using HTTP_2 protocol
+                                but if not supported by server, the protocol will be still HTTP_1_1
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>java.net.http.HttpClient.Version</literal>.
+                            </para>
+                            <para>
+                                The default value is &lit.null;.
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+    </section>
 </appendix>
\ No newline at end of file
diff --git a/docs/src/main/docbook/client.xml b/docs/src/main/docbook/client.xml
index b496268..0999166 100644
--- a/docs/src/main/docbook/client.xml
+++ b/docs/src/main/docbook/client.xml
@@ -656,11 +656,16 @@
                             <entry><literal>org.glassfish.jersey.connectors:jersey-helidon-connector</literal></entry>
                         </row>
                         <row>
-                            <entry>Jetty HTTP client</entry>
+                            <entry>Jetty HTTP client (JDK 17+)</entry>
                             <entry>&jersey.jetty.JettyConnectorProvider;</entry>
                             <entry><literal>org.glassfish.jersey.connectors:jersey-jetty-connector</literal></entry>
                         </row>
                         <row>
+                            <entry>Jetty 11.x HTTP client</entry>
+                            <entry>&jersey.jetty11.Jetty11ConnectorProvider;</entry>
+                            <entry><literal>org.glassfish.jersey.connectors:jersey-jetty11-connector</literal></entry>
+                        </row>
+                        <row>
                             <entry>Jetty HTTP/2 client</entry>
                             <entry>&jersey.jetty.JettyHttp2ConnectorProvider;</entry>
                             <entry><literal>org.glassfish.jersey.connectors:jersey-jetty-http2-connector</literal></entry>
@@ -675,6 +680,11 @@
                             <entry>&jersey.jdk.JdkConnectorProvider;</entry>
                             <entry><literal>org.glassfish.jersey.connectors:jersey-jdk-connector</literal></entry>
                         </row>
+                        <row>
+                            <entry>Java java.net.http client</entry>
+                            <entry>&jersey.jnh.JavaNetHttpConnectorProvider;</entry>
+                            <entry><literal>org.glassfish.jersey.connectors:jersey-jnh-connector</literal></entry>
+                        </row>
                     </tbody>
                 </tgroup>
             </table>
@@ -858,6 +868,21 @@
                     </programlisting>
                 </para>
             </section>
+            <section>
+                <title>Jetty 11.x HttpClient Configuration</title>
+                <para>
+                    For Jetty Connector, an &jersey.jetty11.Jetty11HttpClientSupplier; SPI allows for providing a configured instance
+                    of <literal>org.eclipse.jetty.client.HttpClient</literal>:
+                    <programlisting language="java" linenumbering="numbered">
+                        HttpClient httpClient = new HttpClient(...);
+                        ClientConfig clientConfig = new ClientConfig()
+                            .connectorProvider(new Jetty11ConnectorProvider())
+                            .register(new Jetty11HttpClientSupplier(httpClient));
+                        Client client = ClientBuilder.newClient(clientConfig);
+                        ...
+                    </programlisting>
+                </para>
+            </section>
         </section>
     </section>
 
@@ -1008,9 +1033,9 @@
                 revalidate URL using a custom implementation of &lit.jdk6.HostnameVerifier; and go on in a handshake processing.
                 &lit.jersey.jetty.JettyConnectorProvider; and &lit.jersey.grizzly.GrizzlyConnectorProvider; provide only host URL verification
                 and throw a &lit.jdk6.CertificateException; without any possibility to use custom &lit.jdk6.HostnameVerifier;.
-                Moreover, in case of &lit.jersey.jetty.JettyConnectorProvider; there is a property
-                &jersey.jetty.JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION; to disable an entire host URL verification
-                mechanism in a handshake.
+                Moreover, in case of &lit.jersey.jetty.JettyConnectorProvider; and &lit.jersey.jetty11.Jetty11ConnectorProvider; there are the properties
+                &jersey.jetty.JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION; and &jersey.jetty11.Jetty11ClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION;
+                to disable an entire host URL verification mechanism in a handshake.
             </para>
         </important>
 
diff --git a/docs/src/main/docbook/dependencies.xml b/docs/src/main/docbook/dependencies.xml
index 94c62e8..176fe08 100644
--- a/docs/src/main/docbook/dependencies.xml
+++ b/docs/src/main/docbook/dependencies.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Public License v. 2.0, which is available at
@@ -29,7 +29,7 @@
          xml:id="modules-and-dependencies">
     <title>Modules and dependencies</title>
 
-    <section>
+    <section xml:id="se_compatibility">
         <title>Java SE Compatibility</title>
 
         <para>
@@ -39,11 +39,24 @@
                     <para>This user guide refers only to version 3 and above of Jersey, its compatibility is described below</para>
                 </listitem>
                 <listitem>
-                    <para>Since version 3.0.0* all Jersey components are compiled with Java SE 1.8 target.
+                    <para>Since version 3.0.0 all Jersey components are compiled with Java SE 1.8 target.
                     It means, that you will need at least Java SE 1.8 to be able to compile and run your application
-                        which uses the latest Jersey 3.x.
-                    All modules however are fully compatible with JDK 11 and above. So, it's possible to use JDK 11+ to
-                        build your app.
+                        which uses the latest Jersey 3.0.x.
+                    Some modules, however, are fully compatible with JDK 11 and above (Jetty modules based on Jetty 11).
+                    Some modules (Helidon Connector, Spring 6) require JDK 17.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>Since version 3.1.0 all Jersey components are compiled with Java SE 11 target.
+                        It means, that you will need at least Java SE 11 to be able to compile and run your application
+                        which uses the latest Jersey 3.1.x.
+                        Some modules, however, are fully compatible with JDK 17 and above (Jetty modules based on Jetty 12
+                        [since 3.1.4], Helidon Connector, Spring 6).
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Please see <xref linkend="migration"/> for additional compatibility information.
                     </para>
                 </listitem>
             </itemizedlist>
@@ -162,7 +175,12 @@
     &lt;artifactId&gt;jersey-apache-connector&lt;/artifactId&gt;
     &lt;version&gt;&version;&lt;/version&gt;
 &lt;/dependency&gt;
-<!-- Requires JDK 11+ -->
+&lt;dependency&gt;
+    &lt;groupId&gt;org.glassfish.jersey.connectory&lt;/groupId&gt;
+    &lt;artifactId&gt;jersey-jetty11-connector&lt;/artifactId&gt;
+    &lt;version&gt;&version;&lt;/version&gt;
+&lt;/dependency&gt;
+<!-- Requires JDK 17+ -->
 &lt;dependency&gt;
     &lt;groupId&gt;org.glassfish.jersey.connectors&lt;/groupId&gt;
     &lt;artifactId&gt;jersey-jetty-connector&lt;/artifactId&gt;
diff --git a/docs/src/main/docbook/deployment.xml b/docs/src/main/docbook/deployment.xml
index 474fd63..9fac43c 100644
--- a/docs/src/main/docbook/deployment.xml
+++ b/docs/src/main/docbook/deployment.xml
@@ -110,6 +110,9 @@
             classpath, unless explicitly stated otherwise in the documentation of each particular extension.
             Users are expected to explicitly register the extension &jaxrs.core.Feature;s using their
             &lit.jaxrs.core.Application; subclass.
+            Since Jersey 3.1.0 all features which extends &jaxrs.core.Feature; and are listed as SPI of the &lit.jaxrs.core.Feature;
+            interface are automatically registered (not required to be registered within &lit.jaxrs.core.Application; subclass).
+            For server site Jersey 3.1.0 also registers SPIs for &lit.jaxrs.container.DynamicFeature; interface.
             For a few Jersey provided modules however there is no need to explicitly register their extension
             &lit.jaxrs.core.Feature;s as these are discovered and registered in the &jaxrs.core.Configuration; (on client/server)
             automatically by Jersey runtime whenever the modules implementing these features are present on the classpath
@@ -193,6 +196,17 @@
         </section>
 
     </section>
+    <section  xml:id="deployment.feature.dynamicFeature">
+        <title>Feature and Dynamic Feature SPI automatic registration</title>
+        <para>
+            Since Jersey 3.1.0 there is a new specification requirement to automatically discover and register classes that
+            implement &jaxrs.core.Feature; and &jaxrs.container.DynamicFeature; interfaces. This is being done via SPI search
+            thus all those classes in order to be discovered automatically shall be listed as SPIs for given interfaces.
+            This automatic registration can also be disabled by <literal>jakarta.ws.rs.loadServices</literal>
+            (which is new specification property) to be set to false. This is also valid for
+            &jersey.common.CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE; lookup.
+        </para>
+    </section>
 
     <section xml:id="deployment.classpath-scanning">
         <title>Configuring the Classpath Scanning</title>
@@ -207,6 +221,12 @@
             <itemizedlist>
                 <title>List of SPIs recognized by Jersey</title>
                 <listitem>
+                    <para>&lit.jaxrs.core.Feature; (server, client) -
+                        Features are being registered similarly to AutoDiscoverable feature. In addition
+                        property jakarta.ws.rs.loadServices is checked before registration.
+                    </para>
+                </listitem>
+                <listitem>
                     <para><literal>AutoDiscoverable</literal> (server, client) -
                         it means if you disable service loading the AutoDiscoverable feature is automatically disabled too</para>
                 </listitem>
@@ -218,6 +238,10 @@
                     <para><literal>HeaderDelegateProvider</literal> (server, client)</para>
                 </listitem>
                 <listitem>
+                    <para>&lit.jaxrs.container.DynamicFeature; (server) -
+                    Similar to &lit.jaxrs.core.Feature; registration but only for server.</para>
+                </listitem>
+                <listitem>
                     <para><literal>ComponentProvider</literal> (server)</para>
                 </listitem>
                 <listitem>
@@ -484,6 +508,88 @@
                 </note>
             </section>
         </section>
+
+        <section xml:id="deployment.bootstrap.api">
+            <title>Jakarta REST Bootstrap API</title>
+            <para>
+                Jakarta REST 3.1 comes with a new API for starting an application in Java SE environment. This
+                <literal>Bootstrap</literal> API is mainly represented by &lit.jaxrs.SeBootstrap; interface.
+                The Jakarta REST application is started as follows:
+                <programlisting language="java">Application application = new MyApplication();
+SeBootstrap.Configuration.Builder configBuilder = SeBootstrap.Configuration.builder();
+CompletionStage&lt;SeBootstrap.Instance&gt; completionStage = SeBootstrap.start(application, configBuilder.build());</programlisting>
+            </para>
+            <para>
+                Later, when the SE application is no longer needed, it can be shutdown as follows:
+                <programlisting language="java">CompletionStage&lt;SeBootstrap.Instance&gt; completionStage = ...
+SeBootstrap.Instance instance = completionStage().get();
+instance.stop();</programlisting>
+            </para>
+            <para>
+                The &lit.jaxrs.SeBootstrap.Configuration; allows for configuring the Jersey runtime. The Jakarta REST 3.1 allows
+                for configuring the HTTP port, the protocol (HTTP), the hostname, the root path, and SSL. The
+                &lit.jaxrs.SeBootstrap; is configured as follows:
+                <programlisting language="java">SeBootstrap.Configuration.Builder configBuilder = SeBootstrap.Configuration.builder();
+configBuilder.property(SeBootstrap.Configuration.PROTOCOL, "HTTP")
+    .property(SeBootstrap.Configuration.HOST, "localhost")
+    .property(SeBootstrap.Configuration.PORT, 1234)
+    .property(SeBootstrap.Configuration.ROOT_PATH, "/root/path");</programlisting>
+            </para>
+            <para>
+                The &lit.jaxrs.SeBootstrap; deployment is backed up by an HTTP server described in
+                <xref linkend="deployment.http"/>. If multiple Jersey container modules are on the classpath,
+                the first found is used.
+            </para>
+        </section>
+
+        <section xml:id="deployment.webserver.spi">
+            <title>Jersey WebServer SPI</title>
+            <para>
+                Jersey &jersey.server.spi.WebServer; and &jersey.server.spi.WebServerProvider; are SPI interfaces similar to
+                &jersey.server.spi.ContainerProvider; but they are used for the SE deployment. They serve as a bridge between
+                Jersey containers and &lit.jaxrs.SeBootstrap; API.
+                The Jakarta REST application can be started as follows:
+                <programlisting language="java">Application application = new MyApplication();
+SeBootstrap.Configuration.Builder configBuilder = SeBootstrap.Configuration.builder();
+WebServer webServer = WebServerFactory.createServer(WebServer.class, application, configBuilder.build());</programlisting>
+            </para>
+            <para>
+                Later, when the SE application is no longer needed, it can be shutdown as follows:
+                <programlisting language="java">WebServer webServer = ...
+webServer.stop();</programlisting>
+            </para>
+            <para>
+                &jersey.server.WebServerFactory; is used to automatically choose among available implementations on a classpath.
+                If there are multiple implementations available, the first found is used. The user can choose the implementation
+                of a &lit.jersey.server.spi.WebServer; by a concrete WebServer subclass, for instance:
+                <programlisting language="java">
+WebServer webServer = WebServerFactory.createServer(GrizzlyHttpServer.class, application, configBuilder.build());</programlisting>
+                Another way to choose the &lit.jersey.server.spi.WebServer; implementation is by the
+                &lit.jersey.server.spi.WebServerProvider; implementation:
+                <programlisting language="java">
+WebServer webServer = GrizzlyHttpServerProvider.createServer(WebServer.class, application, configBuilder.build());</programlisting>
+            </para>
+            <para>
+                For additional customization of the WebServer settings, see <xref linkend="appendix-properties-webserver"/>.
+            </para>
+        </section>
+
+        <warning xml:id="ports.warning" xreflabel="Default ports">
+            <para>
+                When the port is set to -1, the default ports are used.
+                Unlike the default ports used by the <xref linkend="deployment.http"/>, the &lit.jaxrs.SeBootstrap; API and
+                &lit.jersey.server.spi.WebServer; SPI use default ports 8080 and 8443, respectively.
+            </para>
+            <para>
+                When the port is set to 0, the implementation scans for a free port. The privileged ports are skipped, and the
+                scanning starts with port 1024.
+            </para>
+            <para>
+                Using the restricted ports can be ensured either by setting directly the port, or by setting
+                &jersey.server.ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS; property to true in the
+                &lit.jaxrs.SeBootstrap.Configuration;
+            </para>
+        </warning>
     </section>
 
     <section xml:id="deployment.jaxrs.endpoint">
diff --git a/docs/src/main/docbook/jaxrs-resources.xml b/docs/src/main/docbook/jaxrs-resources.xml
index d6cb100..884209d 100644
--- a/docs/src/main/docbook/jaxrs-resources.xml
+++ b/docs/src/main/docbook/jaxrs-resources.xml
@@ -480,6 +480,11 @@
             </example>
         </para>
 
+        <para>
+            For quicker getting of values for a known header name there is a shortcut for <literal>hh.getRequestHeaders().get(name)</literal>
+            which is <literal>hh.getRequestHeader(name)</literal>.
+        </para>
+
         <para>In general &jaxrs.core.Context; can be used to obtain contextual Java types related to the request or response.
         </para>
 
diff --git a/docs/src/main/docbook/jersey.ent b/docs/src/main/docbook/jersey.ent
index 69217f0..b37d41f 100644
--- a/docs/src/main/docbook/jersey.ent
+++ b/docs/src/main/docbook/jersey.ent
@@ -28,6 +28,7 @@
 <!ENTITY jaxb-api-jar.version "$jaxb-api-jar-version">
 <!ENTITY jax-rs.version "$jax-rs-api-jar-version">
 <!ENTITY jax-rs21.version "2.1.6">
+<!ENTITY jax-rs31.spec.version "3.1">
 <!ENTITY jakarta.el.version "$jakarta.el-version">
 <!ENTITY jakarta.el-impl.version "$jakarta.el-impl-version">
 <!ENTITY jax-rs-api-jar.version "$jax-rs-api-jar-version">
@@ -60,6 +61,7 @@
 <!ENTITY jaxrs.release.uri "https://github.com/eclipse-ee4j/jaxrs-api">
 <!ENTITY jaxrs.javadoc.uri "https://jakartaee.github.io/rest/apidocs/&jax-rs.version;/jakarta/ws/rs">
 <!ENTITY jaxrs21.javadoc.uri "https://jakartaee.github.io/rest/apidocs/&jax-rs21.version;/javax/ws/rs">
+<!ENTITY jaxrs31.spec.uri "https://jakarta.ee/specifications/restful-ws/&jax-rs31.spec.version;/jakarta-restful-ws-spec-&jax-rs31.spec.version;.html">
 <!ENTITY jsonb.javadoc.uri "https://javaee.github.io/javaee-spec/javadocs/javax/json/bind">
 <!ENTITY jersey.documentation.uri "https://eclipse-ee4j.github.io/jersey.github.io">
 
@@ -215,6 +217,7 @@
 <!ENTITY jaxrs.core.Configuration "<link xlink:href='&jaxrs.javadoc.uri;/core/Configuration.html'>Configuration</link>">
 <!ENTITY jaxrs.core.Context "<link xlink:href='&jaxrs.javadoc.uri;/core/Context.html'>@Context</link>">
 <!ENTITY jaxrs.core.Cookie "<link xlink:href='&jaxrs.javadoc.uri;/core/Cookie.html'>Cookie</link>">
+<!ENTITY jaxrs.core.EntityPart "<link xlink:href='&jaxrs.javadoc.uri;/core/EntityPart.html'>EntityPart</link>">
 <!ENTITY jaxrs.core.EntityTag "<link xlink:href='&jaxrs.javadoc.uri;/core/EntityTag.html'>EntityTag</link>">
 <!ENTITY jaxrs.core.Feature "<link xlink:href='&jaxrs.javadoc.uri;/core/Feature.html'>Feature</link>">
 <!ENTITY jaxrs.core.Form "<link xlink:href='&jaxrs.javadoc.uri;/core/Form.html'>Form</link>">
@@ -233,6 +236,7 @@
 <!ENTITY jaxrs.core.Response.Status "<link xlink:href='&jaxrs.javadoc.uri;/core/Response.Status.html'>Response.Status</link>">
 <!ENTITY jaxrs.core.Response.Status.Family "<link xlink:href='&jaxrs.javadoc.uri;/core/Response.Status.Family.html'>Response.Status.Family</link>">
 <!ENTITY jaxrs.core.Response.StatusType "<link xlink:href='&jaxrs.javadoc.uri;/core/Response.StatusType.html'>Response.StatusType</link>">
+<!ENTITY jaxrs.core.SeBootstrap "<link xlink:href='&jaxrs.javadoc.uri;/SeBootstrap.html'>SeBootstrap</link>">
 <!ENTITY jaxrs.core.SecurityContext "<link xlink:href='&jaxrs.javadoc.uri;/core/SecurityContext.html'>SecurityContext</link>">
 <!ENTITY jaxrs.core.StreamingOutput "<link xlink:href='&jaxrs.javadoc.uri;/core/StreamingOutput.html'>StreamingOutput</link>">
 <!ENTITY jaxrs.core.UriBuilder "<link xlink:href='&jaxrs.javadoc.uri;/core/UriBuilder.html'>UriBuilder</link>">
@@ -251,6 +255,7 @@
 <!ENTITY jaxrs.ext.RuntimeDelegate.HeaderDelegate "<link xlink:href='&jaxrs.javadoc.uri;/ext/RuntimeDelegate.HeaderDelegate.html'>RuntimeDelegate.HeaderDelegate&lt;T&gt;</link>">
 <!ENTITY jaxrs21.sse.SseEventSink "<link xlink:href='&jaxrs21.javadoc.uri;/sse/SseEventSink.html'>SseEventSink</link>">
 <!ENTITY jaxrs21.sse.Sse "<link xlink:href='&jaxrs21.javadoc.uri;/sse/Sse.html'>Sse</link>">
+<!ENTITY jaxrs31.exceptionMapperProvider "<link xlink:href='&jaxrs31.spec.uri;#exceptionmapper'>Exception Mapping Providers</link>">
 
 <!ENTITY jdk6.Boolean "<link xlink:href='&jdk6.javadoc.uri;/java/lang/Boolean.html'>Boolean</link>">
 <!ENTITY jdk6.CountDownLatch "<link xlink:href='&jdk6.javadoc.uri;/java/util/concurrent/CountDownLatch.html'>CountDownLatch</link>">
@@ -360,6 +365,7 @@
 <!ENTITY jersey.client.ClientProperties.DIGESTAUTH_URI_CACHE_SIZELIMIT "<link xlink:href='&jersey.javadoc.uri.prefix;/client/ClientProperties.html#DIGESTAUTH_URI_CACHE_SIZELIMIT'>ClientProperties.DIGESTAUTH_URI_CACHE_SIZELIMIT</link>" >
 <!ENTITY jersey.client.ClientProperties.EXPECT_100_CONTINUE "<link xlink:href='&jersey.javadoc.uri.prefix;/client/ClientProperties.html#EXPECT_100_CONTINUE'>ClientProperties.EXPECT_100_CONTINUE</link>" >
 <!ENTITY jersey.client.ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE "<link xlink:href='&jersey.javadoc.uri.prefix;/client/ClientProperties.html#EXPECT_100_CONTINUE_THRESHOLD_SIZE'>ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE</link>" >
+<!ENTITY jersey.client.ClientProperties.SNI_HOST_NAME "<link xlink:href='&jersey.javadoc.uri.prefix;/client/ClientProperties.html#SNI_HOST_NAME'>ClientProperties.SNI_HOST_NAME</link>" >
 <!ENTITY jersey.client.ClientLifecycleListener "<link xlink:href='&jersey.javadoc.uri.prefix;/client/ClientLifecycleListener.html'>ClientLifecycleListener</link>">
 <!ENTITY jersey.client.Connector "<link xlink:href='&jersey.javadoc.uri.prefix;/client/spi/Connector.html'>Connector</link>">
 <!ENTITY jersey.client.ConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/client/spi/ConnectorProvider.html'>ConnectorProvider</link>">
@@ -485,6 +491,21 @@
 <!ENTITY jersey.jetty.JettyHttpContainerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/JettyHttpContainerFactory.html'>JettyHttpContainerFactory</link>">
 <!ENTITY jersey.jetty.JettyHttpContainerProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/JettyHttpContainerProvider.html'>JettyHttpContainerProvider</link>">
 <!ENTITY jersey.jetty.JettyWebContainerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/servlet/JettyWebContainerFactory.html'>JettyWebContainerFactory</link>">
+<!ENTITY jersey.jetty11.Jetty11ClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html'>Jetty11ClientProperties</link>" >
+<!ENTITY jersey.jetty11.Jetty11HttpClientSupplier "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11HttpClientSupplier.html'>Jetty11HttpClientSupplier</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#ENABLE_SSL_HOSTNAME_VERIFICATION'>Jetty11ClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.DISABLE_COOKIES "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#DISABLE_COOKIES'>Jetty11ClientProperties.DISABLE_COOKIES</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#PREEMPTIVE_BASIC_AUTHENTICATION'>Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#SYNC_LISTENER_RESPONSE_MAX_SIZE'>Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.TOTAL_TIMEOUT "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#TOTAL_TIMEOUT'>Jetty11ClientProperties.TOTAL_TIMEOUT</link>" >
+<!ENTITY jersey.jetty11.Jetty11ConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ConnectorProvider.html'>Jetty11ConnectorProvider</link>">
+<!ENTITY jersey.jnh.JavaNetHttpConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpConnectorProvider.html'>JavaNetHttpConnectorProvider</link>">
+<!ENTITY jersey.jnh.JavaNetHttpClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html'>JavaNetHttpClientProperties</link>">
+<!ENTITY jersey.jnh.JavaNetHttpClientProperties.COOKIE_HANDLER "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#COOKIE_HANDLER'>JavaNetHttpClientProperties.COOKIE_HANDLER</link>">
+<!ENTITY jersey.jnh.JavaNetHttpClientProperties.SSL_PARAMETERS "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#SSL_PARAMETERS'>JavaNetHttpClientProperties.SSL_PARAMETERS</link>">
+<!ENTITY jersey.jnh.JavaNetHttpClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#PREEMPTIVE_BASIC_AUTHENTICATION'>JavaNetHttpClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION</link>">
+<!ENTITY jersey.jnh.JavaNetHttpClientProperties.DISABLE_COOKIES "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#DISABLE_COOKIES'>JavaNetHttpClientProperties.DISABLE_COOKIES</link>">
+<!ENTITY jersey.jnh.JavaNetHttpClientProperties.HTTP_VERSION "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#HTTP_VERSION'>JavaNetHttpClientProperties.HTTP_VERSION</link>">
 <!ENTITY jersey.linking.DeclarativeLinkingFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/linking/DeclarativeLinkingFeature.html'>DeclarativeLinkingFeature</link>">
 <!ENTITY jersey.logging.LoggingFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html'>LoggingFeature</link>">
 <!ENTITY jersey.logging.LoggingFeature.DEFAULT_LOGGER_NAME "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#DEFAULT_LOGGER_NAME'>LoggingFeature.DEFAULT_LOGGER_NAME</link>">
@@ -621,11 +642,15 @@
 <!ENTITY jersey.server.ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231 "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231'>ServerProperties.LOCATION_HEADER_RELATIVE_URI_RESOLUTION_RFC7231</link>" >
 <!ENTITY jersey.server.ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE'>ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE</link>" >
 <!ENTITY jersey.server.ServerProperties.EMPTY_REQUEST_MEDIA_TYPE_MATCHES_ANY_CONSUMES "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#EMPTY_REQUEST_MEDIA_TYPE_MATCHES_ANY_CONSUMES'>ServerProperties.EMPTY_REQUEST_MEDIA_TYPE_MATCHES_ANY_CONSUMES</link>" >
+<!ENTITY jersey.server.ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#WEBSERVER_ALLOW_PRIVILEGED_PORTS'>ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS</link>" >
+<!ENTITY jersey.server.ServerProperties.WEBSERVER_AUTO_START "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#WEBSERVER_AUTO_START'>ServerProperties.WEBSERVER_AUTO_START</link>" >
+<!ENTITY jersey.server.ServerProperties.WEBSERVER_CLASS "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ServerProperties.html#WEBSERVER_CLASS'>ServerProperties.WEBSERVER_CLASS</link>" >
 <!ENTITY jersey.server.Uri "<link xlink:href='&jersey.javadoc.uri.prefix;/server/Uri.html'>Uri</link>">
 <!ENTITY jersey.server.UriConnegFilter "<link xlink:href='&jersey.javadoc.uri.prefix;/server/filter/UriConnegFilter.html'>UriConnegFilter</link>">
 <!ENTITY jersey.server.WadlFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/server/wadl/WadlFeature.html'>WadlFeature</link>">
 <!ENTITY jersey.server.WadlGenerator "<link xlink:href='&jersey.javadoc.uri.prefix;/server/wadl/WadlGenerator.html'>WadlGenerator</link>">
 <!ENTITY jersey.server.WadlGeneratorConfig "<link xlink:href='&jersey.javadoc.uri.prefix;/server/wadl/config/WadlGeneratorConfig.html'>WadlGeneratorConfig</link>">
+<!ENTITY jersey.server.WebServerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/server/WebServerFactory.html'>WebServerFactory</link>">
 <!ENTITY jersey.server.model.MethodHandler "<link xlink:href='&jersey.javadoc.uri.prefix;/server/model/MethodHandler.html'>MethodHandler</link>">
 <!ENTITY jersey.server.model.ComponentModelValidator "<link xlink:href='&jersey.javadoc.uri.prefix;/server/model/ComponentModelValidator.html'>ComponentModelValidator</link>">
 <!ENTITY jersey.server.monitoring.ApplicationEvent "<link xlink:href='&jersey.javadoc.uri.prefix;/server/monitoring/ApplicationEvent.html'>ApplicationEvent</link>">
@@ -668,6 +693,8 @@
 <!ENTITY jersey.server.spi.ContainerProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/server/spi/ContainerProvider.html'>ContainerProvider</link>">
 <!ENTITY jersey.server.spi.ExternalRequestScope "<link xlink:href='&jersey.javadoc.uri.prefix;/server/spi/ExternalRequestScope.html'>ExternalRequestScope</link>">
 <!ENTITY jersey.server.spi.RequestScopedInitializer "<link xlink:href='&jersey.javadoc.uri.prefix;/server/spi/RequestScopedInitializer.html'>RequestScopedInitializer</link>">
+<!ENTITY jersey.server.spi.WebServer "<link xlink:href='&jersey.javadoc.uri.prefix;/server/spi/WebServer.html'>WebServer</link>">
+<!ENTITY jersey.server.spi.WebServerProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/server/spi/WebServerProvider.html'>WebServerProvider</link>">
 <!ENTITY jersey.servlet.ServletContainer "<link xlink:href='&jersey.javadoc.uri.prefix;/servlet/ServletContainer.html'>ServletContainer</link>">
 <!ENTITY jersey.servlet.ServletProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/servlet/ServletProperties.html'>ServletProperties</link>">
 <!ENTITY jersey.servlet.ServletProperties.FILTER_CONTEXT_PATH "<link xlink:href='&jersey.javadoc.uri.prefix;/servlet/ServletProperties.html#FILTER_CONTEXT_PATH'>ServletProperties.FILTER_CONTEXT_PATH</link>">
@@ -807,6 +834,8 @@
 <!ENTITY lit.jaxrs.QueryParam "<literal>@QueryParam</literal>">
 <!ENTITY lit.jaxrs.ReaderInterceptor "<literal>ReaderInterceptor</literal>">
 <!ENTITY lit.jaxrs.ReaderInterceptorContext "<literal>ReaderInterceptorContext</literal>">
+<!ENTITY lit.jaxrs.SeBootstrap "<literal>SeBootstrap</literal>">
+<!ENTITY lit.jaxrs.SeBootstrap.Configuration "<literal>SeBootstrap.Configuration</literal>">
 <!ENTITY lit.jaxrs.WebApplicationException "<literal>WebApplicationException</literal>">
 <!ENTITY lit.jaxrs.WriterInterceptor "<literal>WriterInterceptor</literal>">
 <!ENTITY lit.jaxrs.WriterInterceptorContext "<literal>WriterInterceptorContext</literal>">
@@ -840,6 +869,7 @@
 <!ENTITY lit.jaxrs.core.Context "<literal>@Context</literal>">
 <!ENTITY lit.jaxrs.core.Cookie "<literal>Cookie</literal>">
 <!ENTITY lit.jaxrs.core.EntityTag "<literal>EntityTag</literal>">
+<!ENTITY lit.jaxrs.core.EntityPart "<literal>EntityPart</literal>">
 <!ENTITY lit.jaxrs.core.Feature "<literal>Feature</literal>">
 <!ENTITY lit.jaxrs.core.Form "<literal>Form</literal>">
 <!ENTITY lit.jaxrs.core.GenericEntity "<literal>GenericEntity&lt;T&gt;</literal>">
@@ -885,6 +915,7 @@
 <!ENTITY lit.jdk6.InputStream "<literal>InputStream</literal>">
 <!ENTITY lit.jdk6.JAXBElement "<literal>JAXBElement</literal>">
 <!ENTITY lit.jdk6.KeyStore "<literal>KeyStore</literal>">
+<!ENTITY lit.jdk6.List "<literal>List</literal>">
 <!ENTITY lit.jdk6.Number "<literal>Number</literal>">
 <!ENTITY lit.jdk6.ObjectName "<literal>ObjectName</literal>">
 <!ENTITY lit.jdk6.ParameterizedType "<literal>ParameterizedType</literal>">
@@ -988,6 +1019,7 @@
 <!ENTITY lit.jersey.jetty.JettyHttpContainerFactory "<literal>JettyHttpContainerFactory</literal>">
 <!ENTITY lit.jersey.jetty.JettyHttpContainerProvider "<literal>JettyHttpContainerProvider</literal>">
 <!ENTITY lit.jersey.jetty.JettyWebContainerFactory "<literal>JettyWebContainerFactory</literal>">
+<!ENTITY lit.jersey.jetty11.Jetty11ConnectorProvider "<literal>Jetty11ConnectorProvider</literal>">
 <!ENTITY lit.jersey.linking.DeclarativeLinkingFeature "<literal>DeclarativeLinkingFeature</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature "<literal>LoggingFeature</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.DEFAULT_LOGGER_NAME "<literal>LoggingFeature.DEFAULT_LOGGER_NAME</literal>">
@@ -1126,6 +1158,8 @@
 <!ENTITY lit.jersey.server.oauth1.TokenResource "<literal>TokenResource</literal>">
 <!ENTITY lit.jersey.server.spi.ComponentProvider "<literal>ComponentProvider</literal>">
 <!ENTITY lit.jersey.server.spi.ContainerProvider "<literal>ContainerProvider</literal>">
+<!ENTITY lit.jersey.server.spi.WebServer "<literal>WebServer</literal>">
+<!ENTITY lit.jersey.server.spi.WebServerProvider "<literal>WebServerProvider</literal>">
 <!ENTITY lit.jersey.servlet.ServletContainer "<literal>ServletContainer</literal>">
 <!ENTITY lit.jersey.servlet.ServletProperties "<literal>ServletProperties</literal>">
 <!ENTITY lit.jersey.servlet.ServletProperties.FILTER_CONTEXT_PATH "<literal>ServletProperties.FILTER_CONTEXT_PATH</literal>">
diff --git a/docs/src/main/docbook/media.xml b/docs/src/main/docbook/media.xml
index 6849118..288b923 100644
--- a/docs/src/main/docbook/media.xml
+++ b/docs/src/main/docbook/media.xml
@@ -23,6 +23,10 @@
         <!ENTITY link.jackson "<link linkend='json.jackson'>Jackson</link>" >
         <!ENTITY link.jettison "<link linkend='json.jettison'>Jettison</link>" >
         <!ENTITY link.json-b "<link linkend='json.json-b'>Java API for JSON Binding (JSON-B)</link>" >
+        <!ENTITY link.multipart.client.jersey "<link linkend='multipart.client.jersey'>Client using Jersey API</link>" >
+        <!ENTITY link.multipart.client.rest "<link linkend='multipart.client.rest'>Client using Jakarta REST API</link>" >
+        <!ENTITY link.multipart.server.jersey "<link linkend='multipart.server.jersey'>Server using Jersey API</link>" >
+        <!ENTITY link.multipart.server.rest "<link linkend='multipart.server.rest'>Server using Jakarta REST API</link>" >
 
         <!ENTITY % ents SYSTEM "jersey.ent" > %ents;
 ]>
@@ -1566,25 +1570,11 @@
                 <title>Registration</title>
 
                 <para>
-                    Before you can use capabilities of the &lit.jersey-media-multipart; module in your client/server code, you
-                    need to register &jersey.media.multipart.MultiPartFeature;.
+                    Prior to Jersey 3.1.0, before you can use the capabilities of the &lit.jersey-media-multipart;
+                    module in your client/server code, you need to register &jersey.media.multipart.MultiPartFeature;.
 
-                    <example>
-                        <title>Building client with MultiPart feature enabled.</title>
-
-                        <programlisting language="java">final Client client = ClientBuilder.newBuilder()
-    .register(MultiPartFeature.class)
-    .build();</programlisting>
-                    </example>
-
-                    <example>
-                        <title>Creating JAX-RS application with MultiPart feature enabled.</title>
-
-                        <programlisting language="java">// Create JAX-RS application.
-final Application application = new ResourceConfig()
-    .packages("org.glassfish.jersey.examples.multipart")
-    .register(MultiPartFeature.class)</programlisting>
-                    </example>
+                    The multipart feature is supported by Jakarta RESTful Web Services 3.1 multipart API. From Jersey 3.1.0 on,
+                    the &jersey.media.multipart.MultiPartFeature; is no longer required to be registered and it is registered automatically.
                 </para>
             </section>
 
@@ -1599,20 +1589,30 @@
 
         <section>
             <title>Client</title>
+            <itemizedlist>
+                <listitem>
+                    <para>&link.multipart.client.jersey;</para>
+                </listitem>
+                <listitem>
+                    <para>&link.multipart.client.rest;</para>
+                </listitem>
+            </itemizedlist>
+            <section xml:id="multipart.client.jersey">
+                <title>Client using Jersey API</title>
 
-            <para>
-                &jersey.media.multipart.MultiPart; class (or it's subclasses) can be used as an entry point to use
-                &lit.jersey-media-multipart; module on the client side. This class represents a
-                <link xlink:href='&wikipedia.uri;MIME#Multipart_messages'>MIME multipart message</link> and is able
-                to hold an arbitrary number of &jersey.media.multipart.BodyPart;s. Default media type is
-                <link xlink:href='&wikipedia.uri;MIME#Mixed'>multipart/mixed</link>
-                for &lit.jersey.media.multipart.MultiPart; entity and <literal>text/plain</literal> for
-                &lit.jersey.media.multipart.BodyPart;.
+                <para>
+                    &jersey.media.multipart.MultiPart; class (or it's subclasses) can be used as an entry point to use
+                    &lit.jersey-media-multipart; module on the client side. This class represents a
+                    <link xlink:href='&wikipedia.uri;MIME#Multipart_messages'>MIME multipart message</link> and is able
+                    to hold an arbitrary number of &jersey.media.multipart.BodyPart;s. Default media type is
+                    <link xlink:href='&wikipedia.uri;MIME#Mixed'>multipart/mixed</link>
+                    for &lit.jersey.media.multipart.MultiPart; entity and <literal>text/plain</literal> for
+                    &lit.jersey.media.multipart.BodyPart;.
 
-                <example>
-                    <title>&lit.jersey.media.multipart.MultiPart; entity</title>
+                    <example>
+                        <title>&lit.jersey.media.multipart.MultiPart; entity</title>
 
-                    <programlisting language="java">final MultiPart multiPartEntity = new MultiPart()
+                        <programlisting language="java">final MultiPart multiPartEntity = new MultiPart()
         .bodyPart(new BodyPart().entity("hello"))
         .bodyPart(new BodyPart(new JaxbBean("xml"), MediaType.APPLICATION_XML_TYPE))
         .bodyPart(new BodyPart(new JaxbBean("json"), MediaType.APPLICATION_JSON_TYPE));
@@ -1621,15 +1621,15 @@
 final Response response = target
         .request()
         .post(Entity.entity(multiPartEntity, multiPartEntity.getMediaType()));</programlisting>
-                </example>
+                    </example>
 
-                If you send a <literal>multiPartEntity</literal> to the server the entity with <literal>Content-Type</literal>
-                header in HTTP message would look like (don't forget to register a JSON provider):
+                    If you send a <literal>multiPartEntity</literal> to the server the entity with <literal>Content-Type</literal>
+                    header in HTTP message would look like:
 
-                <example>
-                    <title>&lit.jersey.media.multipart.MultiPart; entity in HTTP message.</title>
+                    <example>
+                        <title>&lit.jersey.media.multipart.MultiPart; entity in HTTP message.</title>
 
-                    <screen language="text" linenumbering="unnumbered"><emphasis>Content-Type: multipart/mixed; boundary=Boundary_1_829077776_1369128119878</emphasis>
+                        <screen language="text" linenumbering="unnumbered"><emphasis>Content-Type: multipart/mixed; boundary=Boundary_1_829077776_1369128119878</emphasis>
 
 --Boundary_1_829077776_1369128119878
 Content-Type: text/plain
@@ -1644,34 +1644,34 @@
 
 {"value":"json"}
 --Boundary_1_829077776_1369128119878--</screen>
-                </example>
-            </para>
-            <para>
-                When working with forms (e.g. media type <literal>multipart/form-data</literal>) and various fields in them,
-                there is a more convenient class to be used - &jersey.media.multipart.FormDataMultiPart;. It automatically sets
-                the media type for the &lit.jersey.media.multipart.FormDataMultiPart; entity to
-                <literal>multipart/form-data</literal> and <literal>Content-Disposition</literal> header to
-                &lit.jersey.media.multipart.FormDataBodyPart; body parts.
+                    </example>
+                </para>
+                <para>
+                    When working with forms (e.g. media type <literal>multipart/form-data</literal>) and various fields in them,
+                    there is a more convenient class to be used - &jersey.media.multipart.FormDataMultiPart;. It automatically sets
+                    the media type for the &lit.jersey.media.multipart.FormDataMultiPart; entity to
+                    <literal>multipart/form-data</literal> and <literal>Content-Disposition</literal> header to
+                    &lit.jersey.media.multipart.FormDataBodyPart; body parts.
 
-                <example>
-                    <title>&lit.jersey.media.multipart.FormDataMultiPart; entity</title>
-                    <programlisting language="java">final FormDataMultiPart multipart = new FormDataMultiPart()
+                    <example>
+                        <title>&lit.jersey.media.multipart.FormDataMultiPart; entity</title>
+                        <programlisting language="java">final FormDataMultiPart multipart = new FormDataMultiPart()
     .field("hello", "hello")
     .field("xml", new JaxbBean("xml"))
     .field("json", new JaxbBean("json"), MediaType.APPLICATION_JSON_TYPE);
 
 final WebTarget target = // Create WebTarget.
 final Response response = target.request().post(Entity.entity(multipart, multipart.getMediaType()));</programlisting>
-                </example>
+                    </example>
 
-                To illustrate the difference when using &lit.jersey.media.multipart.FormDataMultiPart; instead of
-                &lit.jersey.media.multipart.FormDataBodyPart; you can take a look at the
-                &lit.jersey.media.multipart.FormDataMultiPart; entity from HTML message:
+                    To illustrate the difference when using &lit.jersey.media.multipart.FormDataMultiPart; instead of
+                    &lit.jersey.media.multipart.FormDataBodyPart; you can take a look at the
+                    &lit.jersey.media.multipart.FormDataMultiPart; entity from HTML message:
 
-                <example>
-                    <title>&lit.jersey.media.multipart.FormDataMultiPart; entity in HTTP message.</title>
+                    <example>
+                        <title>&lit.jersey.media.multipart.FormDataMultiPart; entity in HTTP message.</title>
 
-                    <screen language="text" linenumbering="unnumbered"><emphasis>Content-Type: multipart/form-data; boundary=Boundary_1_511262261_1369143433608</emphasis>
+                        <screen language="text" linenumbering="unnumbered"><emphasis>Content-Type: multipart/form-data; boundary=Boundary_1_511262261_1369143433608</emphasis>
 
 --Boundary_1_511262261_1369143433608
 Content-Type: text/plain
@@ -1689,17 +1689,17 @@
 
 {"value":"json"}
 --Boundary_1_511262261_1369143433608--</screen>
-                </example>
-            </para>
-            <para>
-                A common use-case for many users is sending files from client to server. For this purpose you can use classes from
-                <literal>org.glassfish.jersey.jersey.media.multipart</literal> package, such as
-                &jersey.media.multipart.FileDataBodyPart; or &jersey.media.multipart.StreamDataBodyPart;.
+                    </example>
+                </para>
+                <para>
+                    A common use-case for many users is sending files from client to server. For this purpose you can use classes from
+                    <literal>org.glassfish.jersey.jersey.media.multipart</literal> package, such as
+                    &jersey.media.multipart.FileDataBodyPart; or &jersey.media.multipart.StreamDataBodyPart;.
 
-                <example>
-                    <title>Multipart - sending files.</title>
+                    <example>
+                        <title>Multipart - sending files.</title>
 
-                    <programlisting language="java">// MediaType of the body part will be derived from the file.
+                        <programlisting language="java">// MediaType of the body part will be derived from the file.
 final FileDataBodyPart filePart = new FileDataBodyPart("my_pom", new File("pom.xml"));
 
 final FormDataMultiPart multipart = new FormDataMultiPart()
@@ -1709,19 +1709,76 @@
 final WebTarget target = // Create WebTarget.
 final Response response = target.request()
     .post(Entity.entity(multipart, multipart.getMediaType()));</programlisting>
-                </example>
-            </para>
-            <warning>
-                <para>
-                    Do not use &lit.jersey.apache.ApacheConnectorProvider; nor &lit.jersey.grizzly.GrizzlyConnectorProvider;
-                    neither &lit.jersey.jetty.JettyConnectorProvider; connector implementations with Jersey Multipart
-                    features. See <xref linkend="connectors.warning"/> warning for more details.
+                    </example>
                 </para>
-            </warning>
+                <warning>
+                    <para>
+                        Do not use &lit.jersey.apache.ApacheConnectorProvider; nor &lit.jersey.grizzly.GrizzlyConnectorProvider;
+                        neither &lit.jersey.jetty.JettyConnectorProvider; connector implementations with Jersey Multipart
+                        features. See <xref linkend="connectors.warning"/> warning for more details.
+                    </para>
+                </warning>
+            </section>
+
+            <section xml:id="multipart.client.rest">
+                <title>Client using Jakarta REST API</title>
+
+                <para>
+                &jaxrs.core.EntityPart; interface can be used as an entry point to use
+                &lit.jersey-media-multipart; module on the client side. This class represents multipart message is able
+                to hold an arbitrary number of &jaxrs.core.EntityPart;s. Default media type is
+                <link xlink:href='&wikipedia.uri;MIME#Mixed'>multipart/form-data</link>.
+
+                <example>
+                    <title>Using <literal>EntityPart.Builder</literal> for building an Entity</title>
+
+                    <programlisting language="java">
+final List&lt;EntityPart&gt; multiPartEntity = new List&lt;&gt;();
+list.add(EntityPart.withName("part-01").content("hello").build());
+list.add(EntityPart.withName("part-01").content(new JaxbBean("xml")).mediaType(MediaType.APPLICATION_XML_TYPE).build()); //same name
+list.add(EntityPart.withName("part-02").content(new JaxbBean("json")).mediaType(MediaType.APPLICATION_JSON_TYPE).build()); //other name
+final GenericEntity&lt;List&lt;EntityPart&gt;&gt; genericEntity = new GenericEntity&lt;&gt;(list) {};
+final Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+
+final WebTarget target = // Create WebTarget.
+final Response response = target.request().post(entity);
+                    </programlisting>
+                </example>
+                </para>
+                <para>
+                    The common use-case for many users is sending files from client to server. It is also covered by
+                    &jaxrs.core.EntityPart;.Builder.
+                    <example>
+                        <title>EntityPart - sending files.</title>
+
+                        <programlisting language="java">// MediaType of the body part will be derived from the file.
+final List&lt;EntityPart&gt; multiPartEntity = new List&lt;&gt;();
+list.add(EntityPart.withFileName("file001.txt").content(new FileInputStream("file001.txt")).build());
+list.add(EntityPart.withFileName("mypom.xml").content(new FileInputStream("pom.xml")).build());
+
+final GenericEntity&lt;List&lt;EntityPart&gt;&gt; genericEntity = new GenericEntity&lt;&gt;(list) {};
+final Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+
+final WebTarget target = // Create WebTarget.
+final Response response = target.request().post(entity);
+                        </programlisting>
+                    </example>
+                </para>
+            </section>
         </section>
 
         <section>
             <title>Server</title>
+            <itemizedlist>
+                <listitem>
+                    <para>&link.multipart.server.jersey;</para>
+                </listitem>
+                <listitem>
+                    <para>&link.multipart.server.rest;</para>
+                </listitem>
+            </itemizedlist>
+            <section xml:id="multipart.server.jersey">
+            <title>Jersey Server API</title>
 
             <para>
                 Returning a multipart response from server to client is not much different from the parts described in the client
@@ -1878,5 +1935,60 @@
                 </tip>
             </section>
         </section>
+        <section xml:id="multipart.server.rest">
+                <title>Server using Jakarta REST API</title>
+                <para>
+                    Using &jaxrs.core.EntityPart; on the server side is similar to the client side.
+                    Jakarta REST specification allows for
+                    returning a &lit.jaxrs.core.Response; or a &lit.jdk6.List; of &lit.jaxrs.core.EntityPart;s.
+                </para>
+                <para>
+                    Receiving the &jaxrs.core.EntityPart;s can be done either using &lit.jaxrs.FormParam; annotations and
+                    &lit.jaxrs.core.EntityPart;, &lit.jdk6.InputStream; or &lit.jdk6.String; data-types, or using a
+                    &lit.jdk6.List; of &lit.jaxrs.core.EntityPart;s.
+                </para>
+
+                <example>
+                <title>Use of &lit.jaxrs.FormParam; annotation with &lit.jaxrs.core.EntityPart; &lit.jdk6.InputStream;
+                    and &lit.jdk6.String; types and returning a &lit.jaxrs.core.Response;</title>
+                <programlisting language="java">@POST
+@Path("/postFormVarious")
+public Response postFormVarious(@FormParam("name1") EntityPart part1,
+                @FormParam("name2") InputStream part2,
+                @FormParam("name3") String part3) throws IOException {
+    final List&lt;EntityPart&gt; list = new LinkedList&lt;&gt;();
+    list.add(EntityPart.withName(part1.getName())
+        .content(part1.getContent(String.class) + new String(part2.readAllBytes()) + part3)
+        .mediaType(MediaType.TEXT_PLAIN_TYPE)
+        .build());
+    final GenericEntity&lt;List&lt;EntityPart&gt;&gt; genericEntity = new GenericEntity&lt;&gt;(list) {};
+    return Response.ok(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE).build();
+}
+            </programlisting>
+            </example>
+            <example>
+                <title>Receiving a &lit.jdk6.List; of &lit.jaxrs.core.EntityPart;s</title>
+                <programlisting language="java">@POST
+@Path("/postListForm")
+public String postEntityPartForm(@FormParam("part-0x") List&lt;EntityPart&gt; part) throws IOException {
+    final String entity = part.get(0).getContent(String.class) + part.get(1).getContent(String.class);
+    return entity;
+}
+                </programlisting>
+            </example>
+            <example>
+                <title>Returning a &lit.jdk6.List; of &lit.jaxrs.core.EntityPart;s</title>
+                <programlisting language="java">@GET
+@Produces(MediaType.MULTIPART_FORM_DATA)
+@Path("/getList")
+public List&lt;EntityPart&gt; getList() throws IOException {
+    final List&lt;EntityPart&gt; list = new LinkedList&lt;&gt;();
+    list.add(EntityPart.withName("name1").content("data1").build());
+    return list;
+}
+                </programlisting>
+            </example>
+        </section>
+    </section>
     </section>
 </chapter>
diff --git a/docs/src/main/docbook/migration.xml b/docs/src/main/docbook/migration.xml
index d9adba0..a20c235 100644
--- a/docs/src/main/docbook/migration.xml
+++ b/docs/src/main/docbook/migration.xml
@@ -48,25 +48,28 @@
                 <itemizedlist>
                     <listitem>
                         <para>
-                            The most fundamental change in Jersey &version; and later is namespace change.
+                            The most fundamental change in Jersey 3.0.0 and later is namespace change.
                             Since Jakarta EE 9 the <literal>jakarta.</literal> namespace is introduced as a replacement
                             for javax namespace from Java EE.
                         </para>
+                    </listitem>
+                    <listitem>
                         <para>
-                            Due to required jakartification several modules where omitted (because of not satisfied dependencies).
-                            Or require higher JDK (11+).
+                            Some Jersey modules require higher versions of Java SE. See <xref linkend="se_compatibility"/>.
                         </para>
-                        <para>
-                            Spring for now is not supported.
-                        </para>
-                        <para>
-                            Helidon connector for now is not supported.
-                        </para>
+                    </listitem>
+                    <listitem>
                         <para>
                             Examples and tests are reduced in quantity (so you probably will not find all those examples which were available
                             in the 2.32 version).
                         </para>
                     </listitem>
+                    <listitem>
+                        <para>
+                            &jersey.server.ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE; is by default
+                            <literal>true</literal>.
+                        </para>
+                    </listitem>
                 </itemizedlist>
             </para>
         </section>
@@ -107,16 +110,46 @@
                             Jakarta EE 10. Jakarta EE 10 defines the minimum JDK 11 requirement and hence Jersey no longer
                             supports JDK 8.
                         </para>
+                        <para>
+                            Some Jersey modules require higher versions of Java SE. See <xref linkend="se_compatibility"/>.
+                        </para>
                     </listitem>
                     <listitem>
                         <para>
-                            &jersey.server.ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE; is by default
-                            <literal>true</literal>.
+                            Since Jersey 3.1.0+ the <literal>getRequestHeader(String name)</literal> method of the
+                            <literal>ClientRequest</literal> class returns NULL (instead of an empty List) in case if
+                            the specified header does not exist.
                         </para>
                     </listitem>
                 </itemizedlist>
             </para>
         </section>
+        <section xml:id="mig-3.1.0-application-path">
+            <title>@ApplicationPath Annotation Support</title>
+            <para>
+                Jersey 3.1 supports <literal>@ApplicationPath</literal> annotation by every container, not only the
+                <literal>Servlet</literal> container. This can affect tests, as well as deployments to containers
+                where the annotation used to be ignored by previous versions of Jersey.
+            </para>
+        </section>
+        <section xml:id="mig-3.1.4-jetty-modules">
+            <title>Jetty Modules</title>
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Jersey 3.0.x, and 3.1.0 - 3.1.3 Jetty modules (jersey-jetty-connector, jersey-container-jetty-http,
+                        jersey-container-jetty-servlet, jersey-test-framework-provider-jetty) are based on Jetty 11,
+                        which is Jakarta EE 9 related.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Jersey 3.1.4 modules use Jetty 12 which is Jakarta EE 10 related (as well as Jersey 3.1.x).
+                        Jetty 12 dependencies use modules names different from Jetty 11.
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </section>
     </section>
 
 </chapter>
diff --git a/docs/src/main/docbook/modules.xml b/docs/src/main/docbook/modules.xml
index 5981ced..e2e1494 100644
--- a/docs/src/main/docbook/modules.xml
+++ b/docs/src/main/docbook/modules.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Public License v. 2.0, which is available at
@@ -230,7 +230,15 @@
     jersey-jetty-connector
 </link>
 </entry>
-<entry>Jersey Client Transport via Jetty (for JDK 11+)</entry>
+<entry>Jersey Client Transport via Jetty (for JDK 17+)</entry>
+</row>
+<row>
+<entry>
+<link xlink:href="https://eclipse-ee4j.github.io/jersey.github.io/project-info/&version;/jersey/project/jersey-jetty11-connector/dependencies.html">
+    jersey-jetty11-connector
+</link>
+</entry>
+<entry>Jersey Client Transport via Jetty 11.x</entry>
 </row>
 <row>
     <row>
diff --git a/docs/src/main/docbook/representations.xml b/docs/src/main/docbook/representations.xml
index 50515d6..12ef126 100644
--- a/docs/src/main/docbook/representations.xml
+++ b/docs/src/main/docbook/representations.xml
@@ -298,6 +298,19 @@
             and let other provider to be chosen for the exception mapping.
         </para>
 
+        <para>
+            Since Jersey 3.1.0 the default <literal>ExceptionMapper</literal> is implemented.
+            It is required by JAX-RS 3.1 specification (&jaxrs31.exceptionMapperProvider;).
+            The default behaviour of the mapper is to return a message from an exception caught and set the response status
+            to 500 (internal server error). In case of a &jaxrs.WebApplicationException; with a response that response is returned.
+            If response inside the &lit.jaxrs.WebApplicationException; is NULL the exception is being processed according to the
+            default behaviour.
+
+            The Default exception mapper is package private and can not be referenced. Its presence is required only by
+            JAX-RS 3.1 specification. Processing of the default Exception Mapper occurs at the very end of the exception
+            processing chain. It is invoked only if nothing else in the chain was invoked before.
+        </para>
+
     </section>
 
     <section>
diff --git a/etc/config/copyright-exclude b/etc/config/copyright-exclude
index 9577477..62b47fc 100644
--- a/etc/config/copyright-exclude
+++ b/etc/config/copyright-exclude
@@ -72,8 +72,6 @@
 /tests/e2e-tls/src/test/java/org/glassfish/jersey/tests/e2e/tls/explorer
 /core-server/src/main/java/com/sun/research/ws/wadl
 /core-common/src/main/java/org/glassfish/jersey/internal/jsr166
-/core-common/src/main/jsr166/org/glassfish/jersey/internal/jsr166
-/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166
 /tests/performance/etc/data/MEASUREMENT_DATA
 /core-common/src/main/java/org/glassfish/jersey/internal/guava/
 /core-server/src/main/java/org/glassfish/jersey/server/internal/monitoring/core/AbstractSlidingWindowTimeReservoir.java
diff --git a/etc/jenkins/Jenkinsfile_ci_build b/etc/jenkins/Jenkinsfile_ci_build
index cba5276..4a622e4 100644
--- a/etc/jenkins/Jenkinsfile_ci_build
+++ b/etc/jenkins/Jenkinsfile_ci_build
@@ -8,20 +8,6 @@
     stages {
         stage('Jersey build') {
             parallel {
-                stage('JDK 8') {
-                    agent {
-                        label 'centos-7'
-                    }
-                    tools {
-                        jdk 'oracle-jdk8-latest'
-                        maven 'apache-maven-latest'
-                    }
-                    steps {
-                        sh '''
-                                bash ${WORKSPACE}/etc/jenkins/jenkins_build.sh
-                            '''
-                    }
-                }
                 stage('JDK 11') {
                     agent {
                         label 'centos-7'
diff --git a/etc/jenkins/jenkins_build.sh b/etc/jenkins/jenkins_build.sh
index 4e96c4e..9983a05 100644
--- a/etc/jenkins/jenkins_build.sh
+++ b/etc/jenkins/jenkins_build.sh
@@ -2,5 +2,4 @@
 
 export DEBUG=true
 
-mvn -V -U -B -e -Pstaging clean install glassfish-copyright:check -Dcopyright.quiet=false
-
+mvn -V -U -B -e -Pstaging clean install glassfish-copyright:check -Dcopyright.quiet=false
\ No newline at end of file
diff --git a/examples/NOTICE.md b/examples/NOTICE.md
index aafa80c..0dcc83c 100644
--- a/examples/NOTICE.md
+++ b/examples/NOTICE.md
@@ -43,7 +43,7 @@
 * Copyright: 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
 * by the @authors tag.
 
-Hibernate Validator CDI, 7.0.5.Final
+Hibernate Validator CDI, 8.0.1.Final
 * License: Apache License, 2.0
 * Project: https://beanvalidation.org/
 * Repackaged in org.glassfish.jersey.server.validation.internal.hibernate
diff --git a/examples/assemblies/pom.xml b/examples/assemblies/pom.xml
index ce6d8f7..3a18a6a 100644
--- a/examples/assemblies/pom.xml
+++ b/examples/assemblies/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>assemblies</artifactId>
diff --git a/examples/bookmark-em/pom.xml b/examples/bookmark-em/pom.xml
index cbbc01e..df1856d 100644
--- a/examples/bookmark-em/pom.xml
+++ b/examples/bookmark-em/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>bookmark-em</artifactId>
diff --git a/examples/bookmark/pom.xml b/examples/bookmark/pom.xml
index 9666be8..702dd74 100644
--- a/examples/bookmark/pom.xml
+++ b/examples/bookmark/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>bookmark</artifactId>
diff --git a/examples/bookstore-webapp/pom.xml b/examples/bookstore-webapp/pom.xml
index 62d7941..f2d9c25 100644
--- a/examples/bookstore-webapp/pom.xml
+++ b/examples/bookstore-webapp/pom.xml
@@ -35,7 +35,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>bookstore-webapp</artifactId>
@@ -56,7 +56,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -69,6 +68,11 @@
             <groupId>jakarta.xml.bind</groupId>
             <artifactId>jakarta.xml.bind-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-osgi</artifactId>
+            <scope>runtime</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -77,6 +81,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
                 <configuration>
                     <webApp>
                         <contextPath>/bookstore-webapp</contextPath>
@@ -88,19 +93,6 @@
 
     <profiles>
         <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>com.sun.xml.bind</groupId>
-                    <artifactId>jaxb-osgi</artifactId>
-                    <scope>runtime</scope>
-                </dependency>
-            </dependencies>
-        </profile>
-        <profile>
             <!-- mvn test -Prun-external-tests -->
             <id>run-external-tests</id>
             <build>
diff --git a/examples/cdi-webapp/pom.xml b/examples/cdi-webapp/pom.xml
index 632153f..6117e18 100644
--- a/examples/cdi-webapp/pom.xml
+++ b/examples/cdi-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-webapp</artifactId>
diff --git a/examples/cdi-webapp/src/main/resources/META-INF/beans.xml b/examples/cdi-webapp/src/main/resources/META-INF/beans.xml
index 5d361e9..77e336a 100644
--- a/examples/cdi-webapp/src/main/resources/META-INF/beans.xml
+++ b/examples/cdi-webapp/src/main/resources/META-INF/beans.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -11,4 +11,9 @@
 
 -->
 
-<beans/>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                           http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="all">
+</beans>
diff --git a/examples/cdi-webapp/src/main/webapp/WEB-INF/beans.xml b/examples/cdi-webapp/src/main/webapp/WEB-INF/beans.xml
index 5d361e9..77e336a 100644
--- a/examples/cdi-webapp/src/main/webapp/WEB-INF/beans.xml
+++ b/examples/cdi-webapp/src/main/webapp/WEB-INF/beans.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -11,4 +11,9 @@
 
 -->
 
-<beans/>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                           http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="all">
+</beans>
diff --git a/examples/clipboard-programmatic/pom.xml b/examples/clipboard-programmatic/pom.xml
index 472521d..858940e 100644
--- a/examples/clipboard-programmatic/pom.xml
+++ b/examples/clipboard-programmatic/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>clipboard-programmatic</artifactId>
diff --git a/examples/clipboard/pom.xml b/examples/clipboard/pom.xml
index fab9876..21cc365 100644
--- a/examples/clipboard/pom.xml
+++ b/examples/clipboard/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>clipboard</artifactId>
diff --git a/examples/configured-client/pom.xml b/examples/configured-client/pom.xml
index 6269291..d74df09 100644
--- a/examples/configured-client/pom.xml
+++ b/examples/configured-client/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>configured-client</artifactId>
diff --git a/examples/declarative-linking/pom.xml b/examples/declarative-linking/pom.xml
index 4fead71..6a4b5a0 100644
--- a/examples/declarative-linking/pom.xml
+++ b/examples/declarative-linking/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>declarative-linking</artifactId>
diff --git a/examples/entity-filtering-security/pom.xml b/examples/entity-filtering-security/pom.xml
index e093c35..093d43f 100644
--- a/examples/entity-filtering-security/pom.xml
+++ b/examples/entity-filtering-security/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>entity-filtering-security</artifactId>
diff --git a/examples/entity-filtering-selectable/pom.xml b/examples/entity-filtering-selectable/pom.xml
index ee430fb..24ce8f8 100644
--- a/examples/entity-filtering-selectable/pom.xml
+++ b/examples/entity-filtering-selectable/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>entity-filtering-selectable</artifactId>
diff --git a/examples/entity-filtering/pom.xml b/examples/entity-filtering/pom.xml
index b849b3a..364fe5b 100644
--- a/examples/entity-filtering/pom.xml
+++ b/examples/entity-filtering/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>entity-filtering</artifactId>
diff --git a/examples/exception-mapping/pom.xml b/examples/exception-mapping/pom.xml
index 38f69b4..dba824e 100644
--- a/examples/exception-mapping/pom.xml
+++ b/examples/exception-mapping/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>exception-mapping</artifactId>
diff --git a/examples/extended-wadl-webapp/pom.xml b/examples/extended-wadl-webapp/pom.xml
index 01cd7ef..410bf9b 100644
--- a/examples/extended-wadl-webapp/pom.xml
+++ b/examples/extended-wadl-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>extended-wadl-webapp</artifactId>
@@ -139,8 +139,8 @@
             <artifactId>jakarta.xml.bind-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>com.sun.activation</groupId>
-            <artifactId>jakarta.activation</artifactId>
+            <groupId>org.eclipse.angus</groupId>
+            <artifactId>angus-activation</artifactId>
         </dependency>
     </dependencies>
 
@@ -177,7 +177,7 @@
                     <dependency>
                         <groupId>jakarta.activation</groupId>
                         <artifactId>jakarta.activation-api</artifactId>
-                        <version>${jakarta.activation.version}</version>
+                        <version>${jakarta.activation-api.version}</version>
                     </dependency>
                     <dependency>
                         <groupId>jakarta.xml.bind</groupId>
diff --git a/examples/freemarker-webapp/pom.xml b/examples/freemarker-webapp/pom.xml
index c98071a..90490a4 100644
--- a/examples/freemarker-webapp/pom.xml
+++ b/examples/freemarker-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>freemarker-webapp</artifactId>
@@ -40,7 +40,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -55,6 +54,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
             </plugin>
         </plugins>
     </build>
diff --git a/examples/groovy/pom.xml b/examples/groovy/pom.xml
index 99ab8ae..f7f4577 100644
--- a/examples/groovy/pom.xml
+++ b/examples/groovy/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <artifactId>groovy</artifactId>
     <packaging>jar</packaging>
diff --git a/examples/helloworld-benchmark/pom.xml b/examples/helloworld-benchmark/pom.xml
index b068285..6411c8c 100644
--- a/examples/helloworld-benchmark/pom.xml
+++ b/examples/helloworld-benchmark/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>helloworld-benchmark</artifactId>
diff --git a/examples/helloworld-cdi2-se/pom.xml b/examples/helloworld-cdi2-se/pom.xml
index 0078ce7..c7a9c0b 100644
--- a/examples/helloworld-cdi2-se/pom.xml
+++ b/examples/helloworld-cdi2-se/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>helloworld-cdi2-se</artifactId>
diff --git a/examples/helloworld-netty/pom.xml b/examples/helloworld-netty/pom.xml
index 773e001..e627917 100644
--- a/examples/helloworld-netty/pom.xml
+++ b/examples/helloworld-netty/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>helloworld-netty</artifactId>
diff --git a/examples/helloworld-programmatic/pom.xml b/examples/helloworld-programmatic/pom.xml
index 0744312..6b3bd42 100644
--- a/examples/helloworld-programmatic/pom.xml
+++ b/examples/helloworld-programmatic/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>helloworld-programmatic</artifactId>
diff --git a/examples/helloworld-pure-jax-rs/pom.xml b/examples/helloworld-pure-jax-rs/pom.xml
index b1cd526..bb04ce6 100644
--- a/examples/helloworld-pure-jax-rs/pom.xml
+++ b/examples/helloworld-pure-jax-rs/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>helloworld-pure-jax-rs</artifactId>
diff --git a/examples/helloworld-spring-annotations/pom.xml b/examples/helloworld-spring-annotations/pom.xml
index 9ffd7cc..e9453d5 100644
--- a/examples/helloworld-spring-annotations/pom.xml
+++ b/examples/helloworld-spring-annotations/pom.xml
@@ -15,7 +15,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.examples</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>helloworld-spring-annotations</artifactId>
@@ -83,7 +83,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
         </dependency>
     </dependencies>
 
diff --git a/examples/helloworld-spring-webapp/pom.xml b/examples/helloworld-spring-webapp/pom.xml
index 2369ef5..a1471eb 100644
--- a/examples/helloworld-spring-webapp/pom.xml
+++ b/examples/helloworld-spring-webapp/pom.xml
@@ -25,7 +25,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>helloworld-spring-webapp</artifactId>
@@ -81,7 +81,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
         </dependency>
 
         <dependency>
@@ -115,6 +115,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
                 <configuration>
                     <webApp>
                         <contextPath>/helloworld-spring-webapp</contextPath>
diff --git a/examples/helloworld-webapp/pom.xml b/examples/helloworld-webapp/pom.xml
index 616aac5..5ff86d7 100644
--- a/examples/helloworld-webapp/pom.xml
+++ b/examples/helloworld-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>helloworld-webapp</artifactId>
@@ -32,7 +32,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
 <!--            <scope>provided</scope> Make this provided for jetty:run -->
         </dependency>
 
@@ -62,6 +61,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
                 <configuration>
                     <webApp>
                         <contextPath>/helloworld-webapp</contextPath>
diff --git a/examples/helloworld-weld/pom.xml b/examples/helloworld-weld/pom.xml
index 6d5ae4a..e2b6353 100644
--- a/examples/helloworld-weld/pom.xml
+++ b/examples/helloworld-weld/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>helloworld-weld</artifactId>
@@ -60,6 +60,18 @@
         <dependency>
             <groupId>org.jboss.weld.se</groupId>
             <artifactId>weld-se-core</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.jboss.logging</groupId>
+                    <artifactId>jboss-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <version>${jboss.logging.version}</version>
+            <scope>provided</scope>
         </dependency>
 
         <dependency>
diff --git a/examples/helloworld-weld/src/main/resources/META-INF/beans.xml b/examples/helloworld-weld/src/main/resources/META-INF/beans.xml
index 5d361e9..77e336a 100644
--- a/examples/helloworld-weld/src/main/resources/META-INF/beans.xml
+++ b/examples/helloworld-weld/src/main/resources/META-INF/beans.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -11,4 +11,9 @@
 
 -->
 
-<beans/>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                           http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="all">
+</beans>
diff --git a/examples/helloworld/pom.xml b/examples/helloworld/pom.xml
index 83d5119..e338c2f 100644
--- a/examples/helloworld/pom.xml
+++ b/examples/helloworld/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>helloworld</artifactId>
diff --git a/examples/http-patch/pom.xml b/examples/http-patch/pom.xml
index 54a2589..829748b 100644
--- a/examples/http-patch/pom.xml
+++ b/examples/http-patch/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>http-patch</artifactId>
diff --git a/examples/http-trace/pom.xml b/examples/http-trace/pom.xml
index f9eef9f..e034290 100644
--- a/examples/http-trace/pom.xml
+++ b/examples/http-trace/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>http-trace</artifactId>
diff --git a/examples/https-clientserver-grizzly/pom.xml b/examples/https-clientserver-grizzly/pom.xml
index 039a1d3..3ac1f99 100644
--- a/examples/https-clientserver-grizzly/pom.xml
+++ b/examples/https-clientserver-grizzly/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>https-clientserver-grizzly</artifactId>
@@ -58,6 +58,12 @@
             <artifactId>junit-jupiter</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-osgi</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+
     </dependencies>
 
     <build>
@@ -74,23 +80,6 @@
 
     <profiles>
         <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <properties>
-                <!-- https://bugs.openjdk.java.net/browse/JDK-8211426 -->
-                <surefire.security.argline>-Djdk.tls.server.protocols=TLSv1.2</surefire.security.argline>
-            </properties>
-            <dependencies>
-                <dependency>
-                    <groupId>com.sun.xml.bind</groupId>
-                    <artifactId>jaxb-osgi</artifactId>
-                    <scope>runtime</scope>
-                </dependency>
-            </dependencies>
-        </profile>
-        <profile>
             <id>pre-release</id>
             <build>
                 <plugins>
@@ -103,4 +92,9 @@
         </profile>
     </profiles>
 
+    <properties>
+        <!-- https://bugs.openjdk.java.net/browse/JDK-8211426 -->
+        <surefire.security.argline>-Djdk.tls.server.protocols=TLSv1.2</surefire.security.argline>
+    </properties>
+
 </project>
diff --git a/examples/https-server-glassfish/pom.xml b/examples/https-server-glassfish/pom.xml
index 1387dde..3d2cf9c 100644
--- a/examples/https-server-glassfish/pom.xml
+++ b/examples/https-server-glassfish/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>https-server-glassfish</artifactId>
diff --git a/examples/java8-webapp/pom.xml b/examples/java8-webapp/pom.xml
index 65a7f18..4f0576d 100644
--- a/examples/java8-webapp/pom.xml
+++ b/examples/java8-webapp/pom.xml
@@ -18,7 +18,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>java8-webapp</artifactId>
@@ -55,6 +55,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
                 <configuration>
                     <stopWait>5</stopWait>
                     <stopPort>9999</stopPort>
diff --git a/examples/jaxb/pom.xml b/examples/jaxb/pom.xml
index d228f56..24d6051 100644
--- a/examples/jaxb/pom.xml
+++ b/examples/jaxb/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jaxb</artifactId>
diff --git a/examples/jaxrs-types-injection/pom.xml b/examples/jaxrs-types-injection/pom.xml
index 160e299..f9d490d 100644
--- a/examples/jaxrs-types-injection/pom.xml
+++ b/examples/jaxrs-types-injection/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jaxrs-types-injection</artifactId>
diff --git a/examples/jersey-ejb/pom.xml b/examples/jersey-ejb/pom.xml
index ee7fad0..556b3ed 100644
--- a/examples/jersey-ejb/pom.xml
+++ b/examples/jersey-ejb/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-ejb</artifactId>
diff --git a/examples/json-binding-webapp/pom.xml b/examples/json-binding-webapp/pom.xml
index 4796b23..e781925 100644
--- a/examples/json-binding-webapp/pom.xml
+++ b/examples/json-binding-webapp/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>json-binding-webapp</artifactId>
diff --git a/examples/json-jackson/pom.xml b/examples/json-jackson/pom.xml
index b6615f7..3b2f085 100644
--- a/examples/json-jackson/pom.xml
+++ b/examples/json-jackson/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>json-jackson</artifactId>
diff --git a/examples/json-jettison/pom.xml b/examples/json-jettison/pom.xml
index 02197c3..482d735 100644
--- a/examples/json-jettison/pom.xml
+++ b/examples/json-jettison/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>json-jettison</artifactId>
diff --git a/examples/json-moxy/pom.xml b/examples/json-moxy/pom.xml
index bd20e56..42c0c0a 100644
--- a/examples/json-moxy/pom.xml
+++ b/examples/json-moxy/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>json-moxy</artifactId>
diff --git a/examples/json-processing-webapp/pom.xml b/examples/json-processing-webapp/pom.xml
index a4bb02f..45f266c 100644
--- a/examples/json-processing-webapp/pom.xml
+++ b/examples/json-processing-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>json-processing-webapp</artifactId>
@@ -52,6 +52,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
             </plugin>
         </plugins>
     </build>
diff --git a/examples/json-with-padding/pom.xml b/examples/json-with-padding/pom.xml
index ae75a62..ed7452b 100644
--- a/examples/json-with-padding/pom.xml
+++ b/examples/json-with-padding/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>json-with-padding</artifactId>
diff --git a/examples/managed-beans-webapp/pom.xml b/examples/managed-beans-webapp/pom.xml
index 2c85e15..2b9e706 100644
--- a/examples/managed-beans-webapp/pom.xml
+++ b/examples/managed-beans-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>managed-beans-webapp</artifactId>
diff --git a/examples/managed-client-simple-webapp/pom.xml b/examples/managed-client-simple-webapp/pom.xml
index f86f970..70c94ec 100644
--- a/examples/managed-client-simple-webapp/pom.xml
+++ b/examples/managed-client-simple-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>managed-client-simple-webapp</artifactId>
@@ -38,6 +38,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
                 <configuration>
                     <webApp>
                         <contextPath>/managed-client-simple-webapp/</contextPath>
diff --git a/examples/managed-client-webapp/pom.xml b/examples/managed-client-webapp/pom.xml
index 9c9c160..f68dba3 100644
--- a/examples/managed-client-webapp/pom.xml
+++ b/examples/managed-client-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>managed-client-webapp</artifactId>
@@ -50,6 +50,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
                 <configuration>
                     <webApp>
                         <contextPath>/managed-client-webapp/</contextPath>
diff --git a/examples/managed-client/pom.xml b/examples/managed-client/pom.xml
index fcb2a54..5f56e66 100644
--- a/examples/managed-client/pom.xml
+++ b/examples/managed-client/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>managed-client</artifactId>
diff --git a/examples/micrometer/pom.xml b/examples/micrometer/pom.xml
index cca0c0d..c6a6084 100644
--- a/examples/micrometer/pom.xml
+++ b/examples/micrometer/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-micrometer-webapp</artifactId>
diff --git a/examples/multipart-webapp/README.MD b/examples/multipart-webapp/README.MD
index 672fda0..ef421c2 100644
--- a/examples/multipart-webapp/README.MD
+++ b/examples/multipart-webapp/README.MD
@@ -1,4 +1,4 @@
-[//]: # " Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved. "
+[//]: # " Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved. "
 [//]: # " "
 [//]: # " This program and the accompanying materials are made available under the "
 [//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at "
@@ -10,20 +10,23 @@
 =========================
 
 This example demonstrates how to develop RESTful web service with
-demonstrating JAX-RS Integration with MIME MultiPart Message Formats and
-an Jakarta EE 9 compliant Web container.
+demonstrating Jakarta-REST Integration with MIME MultiPart Message Formats and
+a Jakarta EE 9 compliant Web container.
+
+Please see also comparable example demonstrating usage of Jakarta REST 3.1 API for
+MIME MultiPart Message Formats (JERSEY_ROOT/examples/rest31-sebootstrap-multipart)
 
 Contents
 --------
 
 The mapping of the URI path space is presented in the following table:
 
-URI path                     | Description                                    | Sample request using curl
----------------------------- | ---------------------------------------------- | -----------------------------------------------------------------------------------------------
-**_/form/part_**             | POST message returning entire string           | `curl -X POST -F "part=part1"  http://localhost:8080/multipart-webapp/form/part`
-**_/form/part-file-name_**   | POST message returning part filename string.   | Be sure to execute this curl from project directory where pom.xml resides
-                             |                                                | `curl -X POST -F "part=@pom.xml"  http://localhost:8080/multipart-webapp/form/part-file-name`
-**_/form/xml-jaxb-part_**    | POST message returning xml jaxb part string.   | No curl sample available, please check test sources.
+ URI path                   | Description                                  | Sample request using curl
+----------------------------|----------------------------------------------| -----------------------------------------------------------------------------------------------
+ **_/form/part_**           | POST message returning entire string         | `curl -X POST -F "part=part1"  http://localhost:8080/multipart-webapp/form/part`
+ **_/form/part-file-name_** | POST message returning part filename string. | Be sure to execute this curl from project directory where pom.xml resides
+|                           |                                              | `curl -X POST -F "part=@pom.xml"  http://localhost:8080/multipart-webapp/form/part-file-name`
+ **_/form/xml-jaxb-part_**  | POST message returning xml jaxb part string. | No curl sample available, please check test sources.
 
 Running the Example
 -------------------
@@ -32,4 +35,4 @@
 
 > `mvn clean package jetty:run`
 
-Following steps are using [cURL](http://curl.haxx.se/) command line tool:
\ No newline at end of file
+The sample requests are using [cURL](http://curl.haxx.se/) command line tool.
\ No newline at end of file
diff --git a/examples/multipart-webapp/pom.xml b/examples/multipart-webapp/pom.xml
index 9d18c4d..6e81be8 100644
--- a/examples/multipart-webapp/pom.xml
+++ b/examples/multipart-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>multipart-webapp</artifactId>
@@ -52,6 +52,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
             </plugin>
         </plugins>
     </build>
diff --git a/examples/oauth-client-twitter/pom.xml b/examples/oauth-client-twitter/pom.xml
index 9a5726e..30740f7 100644
--- a/examples/oauth-client-twitter/pom.xml
+++ b/examples/oauth-client-twitter/pom.xml
@@ -15,7 +15,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.examples</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/examples/open-tracing/pom.xml b/examples/open-tracing/pom.xml
index a93f84b..d3dc8bf 100644
--- a/examples/open-tracing/pom.xml
+++ b/examples/open-tracing/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>open-tracing</artifactId>
diff --git a/examples/osgi-helloworld-webapp/additional-bundle/pom.xml b/examples/osgi-helloworld-webapp/additional-bundle/pom.xml
index 623d5e8..aafea2d 100644
--- a/examples/osgi-helloworld-webapp/additional-bundle/pom.xml
+++ b/examples/osgi-helloworld-webapp/additional-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>osgi-helloworld-webapp</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.examples.osgi-helloworld-webapp</groupId>
diff --git a/examples/osgi-helloworld-webapp/alternate-version-bundle/pom.xml b/examples/osgi-helloworld-webapp/alternate-version-bundle/pom.xml
index d119f94..7d5fa9d 100644
--- a/examples/osgi-helloworld-webapp/alternate-version-bundle/pom.xml
+++ b/examples/osgi-helloworld-webapp/alternate-version-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>osgi-helloworld-webapp</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.examples.osgi-helloworld-webapp</groupId>
diff --git a/examples/osgi-helloworld-webapp/functional-test/pom.xml b/examples/osgi-helloworld-webapp/functional-test/pom.xml
index 114089d..b5ff14d 100644
--- a/examples/osgi-helloworld-webapp/functional-test/pom.xml
+++ b/examples/osgi-helloworld-webapp/functional-test/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>osgi-helloworld-webapp</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.examples.osgi-helloworld-webapp</groupId>
@@ -145,8 +145,8 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.sun.activation</groupId>
-            <artifactId>jakarta.activation</artifactId>
+            <groupId>org.eclipse.angus</groupId>
+            <artifactId>angus-activation</artifactId>
         </dependency>
          <!-- uncomment the following dependency to get ability
               to run felix console in the test -->
diff --git a/examples/osgi-helloworld-webapp/lib-bundle/pom.xml b/examples/osgi-helloworld-webapp/lib-bundle/pom.xml
index 4f1b827..e9c97ca 100644
--- a/examples/osgi-helloworld-webapp/lib-bundle/pom.xml
+++ b/examples/osgi-helloworld-webapp/lib-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>osgi-helloworld-webapp</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.examples.osgi-helloworld-webapp</groupId>
diff --git a/examples/osgi-helloworld-webapp/pom.xml b/examples/osgi-helloworld-webapp/pom.xml
index 7af4f67..768c4c9 100644
--- a/examples/osgi-helloworld-webapp/pom.xml
+++ b/examples/osgi-helloworld-webapp/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>osgi-helloworld-webapp</artifactId>
diff --git a/examples/osgi-helloworld-webapp/war-bundle/pom.xml b/examples/osgi-helloworld-webapp/war-bundle/pom.xml
index e187cbc..e000eef 100644
--- a/examples/osgi-helloworld-webapp/war-bundle/pom.xml
+++ b/examples/osgi-helloworld-webapp/war-bundle/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>osgi-helloworld-webapp</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.examples.osgi-helloworld-webapp</groupId>
@@ -57,7 +57,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version><!-- the current project's ${servlet2.version} is 2.4 and that's not enough -->
             <scope>provided</scope>
         </dependency>
 
diff --git a/examples/osgi-http-service/bundle/pom.xml b/examples/osgi-http-service/bundle/pom.xml
index 831f191..eed47ac 100644
--- a/examples/osgi-http-service/bundle/pom.xml
+++ b/examples/osgi-http-service/bundle/pom.xml
@@ -36,7 +36,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.containers</groupId>
diff --git a/examples/osgi-http-service/functional-test/pom.xml b/examples/osgi-http-service/functional-test/pom.xml
index 358c870..3cc6981 100644
--- a/examples/osgi-http-service/functional-test/pom.xml
+++ b/examples/osgi-http-service/functional-test/pom.xml
@@ -238,9 +238,8 @@
             </activation>
             <dependencies>
                 <dependency>
-                    <groupId>com.sun.activation</groupId>
-                    <artifactId>jakarta.activation</artifactId>
-                    <version>${jakarta.activation.version}</version>
+                    <groupId>org.eclipse.angus</groupId>
+                    <artifactId>angus-activation</artifactId>
                 </dependency>
             </dependencies>
         </profile>
diff --git a/examples/pom.xml b/examples/pom.xml
index 9883766..18d423c 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <licenses>
@@ -106,6 +106,7 @@
         <module>oauth-client-twitter</module>
         <!--<module>oauth2-client-google-webapp</module>-->
         <module>reload</module>
+        <module>rest31-sebootstrap-multipart</module>
         <module>rx-client-webapp</module>
         <module>server-async</module>
         <module>server-async-managed</module>
@@ -199,7 +200,7 @@
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-resources-plugin</artifactId>
-                    <version>2.6</version>
+                    <version>${resources.mvn.plugin.version}</version>
                     <!-- Add legal information, NOTICE.md and LINCENSE.md to jars -->
                     <executions>
                         <execution>
diff --git a/examples/reload/pom.xml b/examples/reload/pom.xml
index 66c3fa5..5b591a8 100644
--- a/examples/reload/pom.xml
+++ b/examples/reload/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>reload</artifactId>
diff --git a/examples/rest31-sebootstrap-multipart/README.MD b/examples/rest31-sebootstrap-multipart/README.MD
new file mode 100644
index 0000000..804e7b6
--- /dev/null
+++ b/examples/rest31-sebootstrap-multipart/README.MD
@@ -0,0 +1,37 @@
+[//]: # " Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. "
+[//]: # " "
+[//]: # " This program and the accompanying materials are made available under the "
+[//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at "
+[//]: # " http://www.eclipse.org/org/documents/edl-v10.php. "
+[//]: # " "
+[//]: # " SPDX-License-Identifier: BSD-3-Clause "
+
+Multipart Web app Example
+=========================
+
+This example demonstrates how to develop RESTful web service with
+demonstrating Jakarta REST Integration with MIME MultiPart Message Formats and
+Jakarta REST EE 10 SeBootstrap functionality.
+
+Feel free to compare with pre-Jakarta REST 3.1 Jersey Multipart example (JERSEY_ROOT/examples/multipart-webapp).
+
+Contents
+--------
+
+The mapping of the URI path space is presented in the following table:
+
+ URI path                   | Description                                  | Sample request using curl
+----------------------------|----------------------------------------------| -----------------------------------------------------------------------------------------------
+ **_/form/part_**           | POST message returning entire string         | `curl -X POST -F "part=part1"  http://localhost:8080/multipart-webapp/form/part`
+ **_/form/part-file-name_** | POST message returning part filename string. | Be sure to execute this curl from project directory where pom.xml resides
+|                            |                                              | `curl -X POST -F "part=@pom.xml"  http://localhost:8080/multipart-webapp/form/part-file-name`
+ **_/form/xml-jaxb-part_**  | POST message returning xml jaxb part string. | No curl sample available, please check test sources.
+
+Running the Example
+-------------------
+
+You can run the example using Jetty as follows:
+
+> `mvn clean package exec:java`
+
+The sample requests are using [cURL](http://curl.haxx.se/) command line tool.
\ No newline at end of file
diff --git a/examples/rest31-sebootstrap-multipart/pom.xml b/examples/rest31-sebootstrap-multipart/pom.xml
new file mode 100644
index 0000000..9dd995a
--- /dev/null
+++ b/examples/rest31-sebootstrap-multipart/pom.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Distribution License v. 1.0, which is available at
+    http://www.eclipse.org/org/documents/edl-v10.php.
+
+    SPDX-License-Identifier: BSD-3-Clause
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.glassfish.jersey.examples</groupId>
+        <artifactId>project</artifactId>
+        <version>3.1.99-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>rest31-sebootstrap-multipart</artifactId>
+    <name>jersey-examples-multipart-webapp</name>
+    <packaging>jar</packaging>
+
+    <description>Jersey SeBootstrap Multipart example.</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-multipart</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-server</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.inject</groupId>
+            <artifactId>jersey-hk2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-osgi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-jdk-http</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework</groupId>
+            <artifactId>jersey-test-framework-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework</groupId>
+            <artifactId>jersey-test-framework-util</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>org.glassfish.jersey.examples.multipart.webapp.Main</mainClass>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>pre-release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>xml-maven-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
diff --git a/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/Bean.java b/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/Bean.java
new file mode 100644
index 0000000..458222b
--- /dev/null
+++ b/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/Bean.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.multipart.webapp;
+
+import jakarta.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Bean {
+
+    public String value;
+
+    public Bean() {
+    }
+
+    public Bean(String str) {
+        value = str;
+    }
+
+}
diff --git a/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/Main.java b/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/Main.java
new file mode 100644
index 0000000..5dbcfd0
--- /dev/null
+++ b/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/Main.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.multipart.webapp;
+
+import jakarta.ws.rs.SeBootstrap;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+
+public class Main {
+    public static void main(String[] args) throws ExecutionException, InterruptedException {
+        final SeBootstrap.Configuration.Builder bootstrapConfigurationBuilder = SeBootstrap.Configuration.builder();
+        bootstrapConfigurationBuilder.property(SeBootstrap.Configuration.PORT, 8080);
+
+        SeBootstrap.start(new MyApplication(), bootstrapConfigurationBuilder.build())
+            .whenComplete((instance1, throwable) -> {
+                try {
+                    System.out.println("Press enter to exit");
+                    System.in.read();
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }).thenAccept((i) -> i.stop())
+
+            .toCompletableFuture().get();
+
+        System.out.println("Exiting...");
+    }
+}
diff --git a/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/MultiPartResource.java b/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/MultiPartResource.java
new file mode 100644
index 0000000..dec7d0e
--- /dev/null
+++ b/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/MultiPartResource.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.multipart.webapp;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.MediaType;
+
+import java.io.IOException;
+
+@Path("/form")
+public class MultiPartResource {
+
+    @GET
+    @Path("test")
+    public String test() {
+        return "Test successful";
+    }
+
+    @POST
+    @Path("part")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    public String post(@FormParam("part") String s) {
+        return s;
+    }
+
+    @POST
+    @Path("part-file-name")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    public String post(@FormParam("part")EntityPart entityPart) throws IOException {
+        return entityPart.getContent(String.class) + ":" + entityPart.getFileName().get();
+    }
+
+    @POST
+    @Path("xml-jaxb-part")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    public String post(
+            @FormParam("string") EntityPart stringEntityPart,
+            @FormParam("bean") EntityPart beanEntityPart) throws IOException {
+        return stringEntityPart.getContent(String.class) + ":" + stringEntityPart.getFileName().get() + ","
+                + beanEntityPart.getContent(Bean.class).value + ":" + beanEntityPart.getFileName().get();
+    }
+}
diff --git a/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/MyApplication.java b/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/MyApplication.java
new file mode 100644
index 0000000..d9d7f30
--- /dev/null
+++ b/examples/rest31-sebootstrap-multipart/src/main/java/org/glassfish/jersey/examples/multipart/webapp/MyApplication.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.multipart.webapp;
+
+import jakarta.ws.rs.ApplicationPath;
+
+import org.glassfish.jersey.server.ResourceConfig;
+
+@ApplicationPath("/multipart-webapp")
+public class MyApplication extends ResourceConfig {
+
+    public MyApplication() {
+        super(MultiPartResource.class);
+    }
+}
diff --git a/examples/rest31-sebootstrap-multipart/src/test/java/org/glassfish/jersey/examples/multipart/webapp/MultiPartWebAppTest.java b/examples/rest31-sebootstrap-multipart/src/test/java/org/glassfish/jersey/examples/multipart/webapp/MultiPartWebAppTest.java
new file mode 100644
index 0000000..218923f
--- /dev/null
+++ b/examples/rest31-sebootstrap-multipart/src/test/java/org/glassfish/jersey/examples/multipart/webapp/MultiPartWebAppTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.multipart.webapp;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.GenericEntity;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.UriBuilder;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.internal.util.SaxHelper;
+import org.glassfish.jersey.internal.util.SimpleNamespaceResolver;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+import org.w3c.dom.Document;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Tests for {@code MultipartResource} class.
+ *
+ * @author Naresh (Srinivas Bhimisetty)
+ * @author Michal Gajdos
+ */
+public class MultiPartWebAppTest extends JerseyTest {
+
+    public static final String PATH = MyApplication.class.getAnnotation(ApplicationPath.class).value();
+
+    @Override
+    protected URI getBaseUri() {
+        return UriBuilder.fromUri(super.getBaseUri()).path(PATH).build();
+    }
+
+    @Override
+    protected Application configure() {
+        return new MyApplication();
+    }
+
+    @Test
+    public void testApplicationWadl() throws Exception {
+        final WebTarget target = target().path(PATH + "/application.wadl");
+
+        final Response response = target.request().get();
+        assertEquals(200, response.getStatus());
+        final File tmpFile = response.readEntity(File.class);
+
+        final DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
+        bf.setNamespaceAware(true);
+        bf.setValidating(false);
+
+        if (!SaxHelper.isXdkDocumentBuilderFactory(bf)) {
+            bf.setXIncludeAware(false);
+        }
+
+        final DocumentBuilder b = bf.newDocumentBuilder();
+        final Document d = b.parse(tmpFile);
+
+        final XPath xp = XPathFactory.newInstance().newXPath();
+        xp.setNamespaceContext(new SimpleNamespaceResolver("wadl", "http://wadl.dev.java.net/2009/02"));
+        String val = (String) xp.evaluate(
+                "//wadl:resource[@path='part']/wadl:method[@name='POST']/wadl:request/wadl:representation/@mediaType",
+                d, XPathConstants.STRING);
+
+        assertEquals("multipart/form-data", val);
+    }
+
+    @Test
+    public void testPart() throws IOException {
+        final WebTarget target = target().path(PATH + "/form/part");
+
+        final EntityPart entityPart = EntityPart.withName("part").content("CONTENT", String.class).build();
+        final GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(List.of(entityPart)) {};
+
+        final String s = target.request().post(Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE), String.class);
+        assertEquals("CONTENT", s);
+    }
+
+    @Test
+    public void testPartWithFileName() throws IOException {
+        final WebTarget target = target().path(PATH + "/form/part-file-name");
+
+        final EntityPart entityPart = EntityPart.withName("part").fileName("file").content("CONTENT", String.class).build();
+        final GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(List.of(entityPart)) {};
+
+        final String s = target.request().post(Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE), String.class);
+        assertEquals("CONTENT:file", s);
+    }
+
+    @Test
+    public void testXmlJAXBPart() throws IOException {
+        final WebTarget target = target().path(PATH + "/form/xml-jaxb-part");
+
+        final EntityPart entityPart1 = EntityPart.withName("bean").fileName("bean")
+                .content(new Bean("BEAN"), Bean.class)
+                .mediaType(MediaType.APPLICATION_XML_TYPE)
+                .build();
+        final EntityPart entityPart2 = EntityPart.withName("string").fileName("string")
+                .content("STRING", String.class)
+                .build();
+
+        final GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(List.of(entityPart1, entityPart2)) {};
+
+        final String s = target.request().post(Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE), String.class);
+        assertEquals("STRING:string,BEAN:bean", s);
+    }
+}
diff --git a/examples/rx-client-webapp/pom.xml b/examples/rx-client-webapp/pom.xml
index ef72671..cdd9b69 100644
--- a/examples/rx-client-webapp/pom.xml
+++ b/examples/rx-client-webapp/pom.xml
@@ -18,7 +18,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>rx-client-webapp</artifactId>
@@ -68,6 +68,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
             </plugin>
         </plugins>
     </build>
diff --git a/examples/server-async-managed/pom.xml b/examples/server-async-managed/pom.xml
index 10b42b0..96ae7b6 100644
--- a/examples/server-async-managed/pom.xml
+++ b/examples/server-async-managed/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>server-async-managed</artifactId>
diff --git a/examples/server-async-standalone/client/pom.xml b/examples/server-async-standalone/client/pom.xml
index 97cbd43..d86d3ba 100644
--- a/examples/server-async-standalone/client/pom.xml
+++ b/examples/server-async-standalone/client/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>server-async-standalone</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>server-async-standalone-client</artifactId>
diff --git a/examples/server-async-standalone/pom.xml b/examples/server-async-standalone/pom.xml
index 3b895bd..fc85b73 100644
--- a/examples/server-async-standalone/pom.xml
+++ b/examples/server-async-standalone/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>server-async-standalone</artifactId>
diff --git a/examples/server-async-standalone/webapp/pom.xml b/examples/server-async-standalone/webapp/pom.xml
index 2547528..86e5bac 100644
--- a/examples/server-async-standalone/webapp/pom.xml
+++ b/examples/server-async-standalone/webapp/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>server-async-standalone</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>server-async-standalone-webapp</artifactId>
diff --git a/examples/server-async/pom.xml b/examples/server-async/pom.xml
index c3140a2..f2fdf8a 100644
--- a/examples/server-async/pom.xml
+++ b/examples/server-async/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>server-async</artifactId>
diff --git a/examples/server-sent-events-jaxrs/pom.xml b/examples/server-sent-events-jaxrs/pom.xml
index 14ed637..282a0af 100644
--- a/examples/server-sent-events-jaxrs/pom.xml
+++ b/examples/server-sent-events-jaxrs/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>server-sent-events-jaxrs</artifactId>
diff --git a/examples/server-sent-events-jersey/pom.xml b/examples/server-sent-events-jersey/pom.xml
index 17a2a41..a560331 100644
--- a/examples/server-sent-events-jersey/pom.xml
+++ b/examples/server-sent-events-jersey/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>server-sent-events-jersey</artifactId>
diff --git a/examples/servlet3-webapp/pom.xml b/examples/servlet3-webapp/pom.xml
index f798883..371c705 100644
--- a/examples/servlet3-webapp/pom.xml
+++ b/examples/servlet3-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet3-webapp</artifactId>
@@ -37,7 +37,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -64,6 +63,7 @@
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
                 <configuration>
 <!--                    <skip>${skip.tests}</skip>-->
 <!--                    <stopWait>10</stopWait>-->
diff --git a/examples/simple-console/pom.xml b/examples/simple-console/pom.xml
index 1e2fd4c..f2bb047 100644
--- a/examples/simple-console/pom.xml
+++ b/examples/simple-console/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>simple-console</artifactId>
diff --git a/examples/sse-item-store-jaxrs-webapp/pom.xml b/examples/sse-item-store-jaxrs-webapp/pom.xml
index 34155d4..27eb45c 100644
--- a/examples/sse-item-store-jaxrs-webapp/pom.xml
+++ b/examples/sse-item-store-jaxrs-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>sse-item-store-jaxrs-webapp</artifactId>
@@ -59,6 +59,7 @@
                 <!-- TODO unify Jetty in all examples -->
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
                 <configuration>
                     <stopWait>10</stopWait>
                     <stopPort>9999</stopPort>
diff --git a/examples/sse-item-store-jersey-webapp/pom.xml b/examples/sse-item-store-jersey-webapp/pom.xml
index c22a6e8..9576db7 100644
--- a/examples/sse-item-store-jersey-webapp/pom.xml
+++ b/examples/sse-item-store-jersey-webapp/pom.xml
@@ -19,7 +19,7 @@
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>webapp-example-parent</artifactId>
         <relativePath>../webapp-example-parent/pom.xml</relativePath>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>sse-item-store-jersey-webapp</artifactId>
@@ -59,6 +59,7 @@
                 <!-- TODO unify Jetty in all examples -->
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.plugin.version}</version>
                 <configuration>
                     <stopWait>10</stopWait>
                     <stopPort>9999</stopPort>
diff --git a/examples/sse-twitter-aggregator/pom.xml b/examples/sse-twitter-aggregator/pom.xml
index f1ef846..b7e8100 100644
--- a/examples/sse-twitter-aggregator/pom.xml
+++ b/examples/sse-twitter-aggregator/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>sse-twitter-aggregator</artifactId>
diff --git a/examples/system-properties-example/pom.xml b/examples/system-properties-example/pom.xml
index 5922bb9..6dad74a 100644
--- a/examples/system-properties-example/pom.xml
+++ b/examples/system-properties-example/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>system-properties-example</artifactId>
diff --git a/examples/webapp-example-parent/pom.xml b/examples/webapp-example-parent/pom.xml
index 24f2dc5..88f30fd 100644
--- a/examples/webapp-example-parent/pom.xml
+++ b/examples/webapp-example-parent/pom.xml
@@ -18,7 +18,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>webapp-example-parent</artifactId>
diff --git a/examples/xml-moxy/pom.xml b/examples/xml-moxy/pom.xml
index 581fa59..3b2d040 100644
--- a/examples/xml-moxy/pom.xml
+++ b/examples/xml-moxy/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.glassfish.jersey.examples</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>xml-moxy</artifactId>
diff --git a/ext/bean-validation/pom.xml b/ext/bean-validation/pom.xml
index a382b7a..0378140 100644
--- a/ext/bean-validation/pom.xml
+++ b/ext/bean-validation/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-bean-validation</artifactId>
@@ -59,6 +59,7 @@
                             ${jakarta.annotation.osgi.version},
                             ${cdi.osgi.version},
                             jakarta.validation.*;resolution:=optional;version="${range;[==,4);${jakarta.validation.api.version}}",
+                            jakarta.decorator.*;version="[3.0,5)",
                             *
                         </Import-Package>
                     </instructions>
diff --git a/ext/bean-validation/src/main/resources/META-INF/NOTICE.markdown b/ext/bean-validation/src/main/resources/META-INF/NOTICE.markdown
index 0e566a0..07e6ca5 100644
--- a/ext/bean-validation/src/main/resources/META-INF/NOTICE.markdown
+++ b/ext/bean-validation/src/main/resources/META-INF/NOTICE.markdown
@@ -31,7 +31,7 @@
 
 ## Third-party Content
 
-Hibernate Validator CDI, 7.0.5.Final
+Hibernate Validator CDI, 8.0.1.Final
 * License: Apache License, 2.0
 * Project: https://beanvalidation.org/
-* Repackaged in org.glassfish.jersey.server.validation.internal.hibernate
\ No newline at end of file
+* Repackaged in org.glassfish.jersey.server.validation.internal.hibernate
diff --git a/ext/cdi/jersey-cdi-rs-inject/pom.xml b/ext/cdi/jersey-cdi-rs-inject/pom.xml
index 7399a61..139b254 100644
--- a/ext/cdi/jersey-cdi-rs-inject/pom.xml
+++ b/ext/cdi/jersey-cdi-rs-inject/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.ext.cdi</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -48,7 +48,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
             <scope>provided</scope>
             <optional>true</optional>
         </dependency>
@@ -73,7 +73,7 @@
                     <instructions>
                         <Import-Package>
                             ${cdi.osgi.version},
-                            jakarta.servlet.*;version="[5.0, 7.0)";resolution:=optional,
+                            jakarta.servlet.*;version="[6.0, 7.0)";resolution:=optional,
                             *
                         </Import-Package>
                     </instructions>
diff --git a/ext/cdi/jersey-cdi1x-ban-custom-hk2-binding/pom.xml b/ext/cdi/jersey-cdi1x-ban-custom-hk2-binding/pom.xml
index 35b0a82..d17023c 100644
--- a/ext/cdi/jersey-cdi1x-ban-custom-hk2-binding/pom.xml
+++ b/ext/cdi/jersey-cdi1x-ban-custom-hk2-binding/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext.cdi</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-cdi1x-ban-custom-hk2-binding</artifactId>
diff --git a/ext/cdi/jersey-cdi1x-servlet/pom.xml b/ext/cdi/jersey-cdi1x-servlet/pom.xml
index 4f783da..49b30dd 100644
--- a/ext/cdi/jersey-cdi1x-servlet/pom.xml
+++ b/ext/cdi/jersey-cdi1x-servlet/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext.cdi</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-cdi1x-servlet</artifactId>
@@ -88,6 +88,7 @@
                         <Export-Package>org.glassfish.jersey.ext.cdi1x.servlet.internal</Export-Package>
                         <Import-Package>
                             ${cdi.osgi.version},
+                            jakarta.decorator.*;version="[3.0,5)",
                             *
                         </Import-Package>
                     </instructions>
diff --git a/ext/cdi/jersey-cdi1x-servlet/src/main/java/org/glassfish/jersey/ext/cdi1x/servlet/internal/CdiExternalRequestScopeExtension.java b/ext/cdi/jersey-cdi1x-servlet/src/main/java/org/glassfish/jersey/ext/cdi1x/servlet/internal/CdiExternalRequestScopeExtension.java
index 3a17677..ce367f5 100644
--- a/ext/cdi/jersey-cdi1x-servlet/src/main/java/org/glassfish/jersey/ext/cdi1x/servlet/internal/CdiExternalRequestScopeExtension.java
+++ b/ext/cdi/jersey-cdi1x-servlet/src/main/java/org/glassfish/jersey/ext/cdi1x/servlet/internal/CdiExternalRequestScopeExtension.java
@@ -124,7 +124,7 @@
                 return false;
             }
 
-            @Override
+            // @Override - Removed in CDI 4
             public boolean isNullable() {
                 return false;
             }
diff --git a/ext/cdi/jersey-cdi1x-transaction/pom.xml b/ext/cdi/jersey-cdi1x-transaction/pom.xml
index 34d0ce0..7dff641 100644
--- a/ext/cdi/jersey-cdi1x-transaction/pom.xml
+++ b/ext/cdi/jersey-cdi1x-transaction/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext.cdi</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-cdi1x-transaction</artifactId>
@@ -37,7 +37,7 @@
         <dependency>
             <groupId>jakarta.platform</groupId>
             <artifactId>jakarta.jakartaee-api</artifactId>
-            <version>9.0.0</version>
+            <version>9.1.0</version>
             <scope>provided</scope>
         </dependency>
 
@@ -94,6 +94,7 @@
                         <Import-Package>
                             ${jakarta.annotation.osgi.version},
                             ${cdi.osgi.version},
+                            jakarta.decorator.*;version="[3.0,5)",
                             *
                         </Import-Package>
                     </instructions>
diff --git a/ext/cdi/jersey-cdi1x-validation/pom.xml b/ext/cdi/jersey-cdi1x-validation/pom.xml
index c0c92f9..e36b80d 100644
--- a/ext/cdi/jersey-cdi1x-validation/pom.xml
+++ b/ext/cdi/jersey-cdi1x-validation/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext.cdi</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-cdi1x-validation</artifactId>
@@ -106,6 +106,7 @@
                         <Import-Package>
                             ${jakarta.annotation.osgi.version},
                             ${cdi.osgi.version},
+                            jakarta.decorator.*;version="[3.0,5)",
                             *
                         </Import-Package>
                     </instructions>
diff --git a/ext/cdi/jersey-cdi1x-validation/src/main/java/org/glassfish/jersey/ext/cdi1x/validation/internal/CdiInterceptorWrapperExtension.java b/ext/cdi/jersey-cdi1x-validation/src/main/java/org/glassfish/jersey/ext/cdi1x/validation/internal/CdiInterceptorWrapperExtension.java
index 6cced30..875f63c 100644
--- a/ext/cdi/jersey-cdi1x-validation/src/main/java/org/glassfish/jersey/ext/cdi1x/validation/internal/CdiInterceptorWrapperExtension.java
+++ b/ext/cdi/jersey-cdi1x-validation/src/main/java/org/glassfish/jersey/ext/cdi1x/validation/internal/CdiInterceptorWrapperExtension.java
@@ -155,7 +155,7 @@
                 return false;
             }
 
-            @Override
+            // @Override - Removed in CDI 4
             public boolean isNullable() {
                 return false;
             }
diff --git a/ext/cdi/jersey-cdi1x/pom.xml b/ext/cdi/jersey-cdi1x/pom.xml
index ed39bc0..afc33a7 100644
--- a/ext/cdi/jersey-cdi1x/pom.xml
+++ b/ext/cdi/jersey-cdi1x/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext.cdi</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-cdi1x</artifactId>
@@ -94,6 +94,7 @@
                             ${jakarta.annotation.osgi.version},
                             ${hk2.osgi.version},
                             ${cdi.osgi.version},
+                            jakarta.decorator.*;version="[3.0,5)",
                             *
                         </Import-Package>
                     </instructions>
diff --git a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
index e5fd3e8..e41d4c9 100644
--- a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
+++ b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
@@ -727,7 +727,7 @@
             return Collections.emptySet();
         }
 
-        @Override
+        // @Override - Removed in CDI 4
         public boolean isNullable() {
             return true;
         }
diff --git a/ext/cdi/jersey-weld2-se/pom.xml b/ext/cdi/jersey-weld2-se/pom.xml
index 9ffd697..3563038 100644
--- a/ext/cdi/jersey-weld2-se/pom.xml
+++ b/ext/cdi/jersey-weld2-se/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext.cdi</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-weld2-se</artifactId>
diff --git a/ext/cdi/pom.xml b/ext/cdi/pom.xml
index 21686f3..42ec56d 100644
--- a/ext/cdi/pom.xml
+++ b/ext/cdi/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.ext.cdi</groupId>
diff --git a/ext/entity-filtering/pom.xml b/ext/entity-filtering/pom.xml
index 8ebbaac..877624a 100644
--- a/ext/entity-filtering/pom.xml
+++ b/ext/entity-filtering/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-entity-filtering</artifactId>
diff --git a/ext/metainf-services/pom.xml b/ext/metainf-services/pom.xml
index 7330e7d..e3b1a7d 100644
--- a/ext/metainf-services/pom.xml
+++ b/ext/metainf-services/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-metainf-services</artifactId>
diff --git a/ext/micrometer/pom.xml b/ext/micrometer/pom.xml
index 4608efb..036d4e5 100644
--- a/ext/micrometer/pom.xml
+++ b/ext/micrometer/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.ext</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/ext/microprofile/mp-config/pom.xml b/ext/microprofile/mp-config/pom.xml
index cb9a391..7e7aa30 100644
--- a/ext/microprofile/mp-config/pom.xml
+++ b/ext/microprofile/mp-config/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.ext.microprofile</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -95,7 +95,7 @@
         <profile>
             <id>JettyExclude</id>
             <activation>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <build>
                 <plugins>
@@ -112,9 +112,9 @@
             </build>
         </profile>
         <profile>
-            <id>Jetty11</id>
+            <id>Jetty17</id>
             <activation>
-                <jdk>[11,)</jdk>
+                <jdk>[17,)</jdk>
             </activation>
             <dependencies>
                 <dependency>
diff --git a/ext/microprofile/mp-rest-client/pom.xml b/ext/microprofile/mp-rest-client/pom.xml
index 74b46c1..0bf5d0d 100644
--- a/ext/microprofile/mp-rest-client/pom.xml
+++ b/ext/microprofile/mp-rest-client/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.ext.microprofile</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -119,7 +119,6 @@
                         <Import-Package>
                             ${cdi.osgi.version},
                             jakarta.decorator.*;version="[3.0,5)",
-                            org.eclipse.microprofile.rest.client.*;version="[3.0,4)",
                             org.eclipse.microprofile.config.*;version="!",
                             *
                         </Import-Package>
@@ -130,4 +129,4 @@
         </plugins>
     </build>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java
index 48bc397..d583419 100644
--- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java
+++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -123,7 +123,7 @@
         return Collections.emptySet();
     }
 
-    @Override
+    // @Override - Removed in CDI 4
     public boolean isNullable() {
         return false;
     }
diff --git a/ext/microprofile/pom.xml b/ext/microprofile/pom.xml
index fa35af4..45f151f 100644
--- a/ext/microprofile/pom.xml
+++ b/ext/microprofile/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.ext</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/ext/mvc-bean-validation/pom.xml b/ext/mvc-bean-validation/pom.xml
index d9bde4d..6a9a724 100644
--- a/ext/mvc-bean-validation/pom.xml
+++ b/ext/mvc-bean-validation/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-mvc-bean-validation</artifactId>
diff --git a/ext/mvc-freemarker/pom.xml b/ext/mvc-freemarker/pom.xml
index 954901d..2441198 100644
--- a/ext/mvc-freemarker/pom.xml
+++ b/ext/mvc-freemarker/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-mvc-freemarker</artifactId>
@@ -42,6 +42,7 @@
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
+                        <Import-Package>jakarta.servlet.*;version="[5.0,7.0)",*</Import-Package>
                         <Export-Package>org.glassfish.jersey.server.mvc.freemarker.*;version=${project.version}</Export-Package>
                     </instructions>
                     <unpackBundle>true</unpackBundle>
@@ -56,11 +57,9 @@
     </build>
 
     <dependencies>
-
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
diff --git a/ext/mvc-jsp/pom.xml b/ext/mvc-jsp/pom.xml
index 262e8af..a98dfa7 100644
--- a/ext/mvc-jsp/pom.xml
+++ b/ext/mvc-jsp/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-mvc-jsp</artifactId>
@@ -54,7 +54,7 @@
                     <instructions>
                         <Import-Package>
                             jakarta.servlet.jsp.*;version="[3.0,4.0)",
-                            jakarta.servlet.*;version="!",
+                            jakarta.servlet.*;version="[5.0,7.0)",
                             *
                         </Import-Package>
                         <Export-Package>org.glassfish.jersey.server.mvc.jsp.*;version=${project.version}</Export-Package>
@@ -84,7 +84,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/ext/mvc-mustache/pom.xml b/ext/mvc-mustache/pom.xml
index 42ec227..1a40389 100644
--- a/ext/mvc-mustache/pom.xml
+++ b/ext/mvc-mustache/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-mvc-mustache</artifactId>
diff --git a/ext/mvc/pom.xml b/ext/mvc/pom.xml
index 4d9d722..5b5e64c 100644
--- a/ext/mvc/pom.xml
+++ b/ext/mvc/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-mvc</artifactId>
@@ -37,7 +37,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
         </dependency>
 
         <dependency>
@@ -67,7 +66,7 @@
                 <configuration>
                     <instructions>
                         <Export-Package>org.glassfish.jersey.server.mvc.*;version=${project.version}</Export-Package>
-                        <Import-Package>${jakarta.annotation.osgi.version},*</Import-Package>
+                        <Import-Package> jakarta.servlet.*;version="[5.0,7.0)",${jakarta.annotation.osgi.version},*</Import-Package>
                     </instructions>
                     <unpackBundle>true</unpackBundle>
                 </configuration>
diff --git a/ext/pom.xml b/ext/pom.xml
index c3076f5..8710a21 100644
--- a/ext/pom.xml
+++ b/ext/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.ext</groupId>
diff --git a/ext/proxy-client/pom.xml b/ext/proxy-client/pom.xml
index b0f1cf3..b822028 100644
--- a/ext/proxy-client/pom.xml
+++ b/ext/proxy-client/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-proxy-client</artifactId>
diff --git a/ext/rx/pom.xml b/ext/rx/pom.xml
index 2c49255..5131f94 100644
--- a/ext/rx/pom.xml
+++ b/ext/rx/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.ext.rx</groupId>
diff --git a/ext/rx/rx-client-guava/pom.xml b/ext/rx/rx-client-guava/pom.xml
index 62d82a4..50a6d64 100644
--- a/ext/rx/rx-client-guava/pom.xml
+++ b/ext/rx/rx-client-guava/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext.rx</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-rx-client-guava</artifactId>
diff --git a/ext/rx/rx-client-rxjava/pom.xml b/ext/rx/rx-client-rxjava/pom.xml
index 7087998..0a0bfeb 100644
--- a/ext/rx/rx-client-rxjava/pom.xml
+++ b/ext/rx/rx-client-rxjava/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext.rx</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-rx-client-rxjava</artifactId>
diff --git a/ext/rx/rx-client-rxjava2/pom.xml b/ext/rx/rx-client-rxjava2/pom.xml
index 021619c..2756981 100644
--- a/ext/rx/rx-client-rxjava2/pom.xml
+++ b/ext/rx/rx-client-rxjava2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext.rx</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-rx-client-rxjava2</artifactId>
diff --git a/ext/spring6/pom.xml b/ext/spring6/pom.xml
index e364dec..6e871bf 100644
--- a/ext/spring6/pom.xml
+++ b/ext/spring6/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.ext</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-spring6</artifactId>
@@ -167,7 +167,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
             <scope>provided</scope>
         </dependency>
 
diff --git a/ext/wadl-doclet/pom.xml b/ext/wadl-doclet/pom.xml
index 41aaf54..3851c3f 100644
--- a/ext/wadl-doclet/pom.xml
+++ b/ext/wadl-doclet/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.ext</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>jersey-wadl-doclet</artifactId>
diff --git a/incubator/cdi-inject-weld/pom.xml b/incubator/cdi-inject-weld/pom.xml
index 647f36e..28f5404 100644
--- a/incubator/cdi-inject-weld/pom.xml
+++ b/incubator/cdi-inject-weld/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.incubator</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-cdi-inject-weld</artifactId>
@@ -59,7 +59,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -127,8 +126,11 @@
                             org.glassfish.jersey.inject.weld.managed.*;version=${project.version}
                         </Export-Package>
                         <Import-Package>
+                            jakarta.servlet.*;version="[5.0,7.0)",
                             sun.misc.*;resolution:=optional,
+                            ${jakarta.annotation.osgi.version},
                             ${cdi.osgi.version},
+                            jakarta.decorator.*;version="[3.0,5)",
                             ${jakarta.annotation.osgi.version},
                             *
                         </Import-Package>
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/BeanHelper.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/BeanHelper.java
index c5c4cfe..b653b54 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/BeanHelper.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/BeanHelper.java
@@ -157,7 +157,8 @@
 
         Class<Supplier<T>> supplierClass = (Class<Supplier<T>>) binding.getSupplierClass();
         AnnotatedType<Supplier<T>> annotatedType = beanManager.createAnnotatedType(supplierClass);
-        InjectionTarget<Supplier<T>> injectionTarget = beanManager.createInjectionTarget(annotatedType);
+        final InjectionTargetFactory<Supplier<T>> injectionTargetFactory = beanManager.getInjectionTargetFactory(annotatedType);
+        final InjectionTarget<Supplier<T>> injectionTarget = injectionTargetFactory.createInjectionTarget(null);
 
         SupplierClassBean<T> supplierBean = new SupplierClassBean<>(runtimeType, binding);
         InjectionTarget<Supplier<T>> jit = getJerseyInjectionTarget(supplierClass, injectionTarget, supplierBean, resolvers);
@@ -218,7 +219,8 @@
 
         final Class<Supplier<T>> bindingClass = (Class<Supplier<T>>) binding.getSupplierClass();
         final AnnotatedType<Supplier<T>> annotatedType = beanManager.createAnnotatedType(bindingClass);
-        final InjectionTarget<Supplier<T>> injectionTarget = beanManager.createInjectionTarget(annotatedType);
+        final InjectionTargetFactory<Supplier<T>> injectionTargetFactory = beanManager.getInjectionTargetFactory(annotatedType);
+        final InjectionTarget<Supplier<T>> injectionTarget = injectionTargetFactory.createInjectionTarget(null);
 
         final CachedConstructorAnalyzer<Supplier<T>> analyzer =
                 new CachedConstructorAnalyzer<>(bindingClass, InjectionUtils.getInjectAnnotations(resolvers));
@@ -239,7 +241,8 @@
 
         final Class<T> bindingClass = binding.getImplementationType();
         final AnnotatedType<T> annotatedType = beanManager.createAnnotatedType(bindingClass);
-        final InjectionTarget<T> injectionTarget = beanManager.createInjectionTarget(annotatedType);
+        final InjectionTargetFactory<T> injectionTargetFactory = beanManager.getInjectionTargetFactory(annotatedType);
+        final InjectionTarget<T> injectionTarget = injectionTargetFactory.createInjectionTarget(null);
 
         final CachedConstructorAnalyzer<T> analyzer =
                 new CachedConstructorAnalyzer<>(bindingClass, InjectionUtils.getInjectAnnotations(resolvers));
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/JerseyBean.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/JerseyBean.java
index 2f4da94..a56f23b 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/JerseyBean.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/bean/JerseyBean.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -142,7 +142,7 @@
         return false;
     }
 
-    @Override
+    // @Override - Removed in CDI 4
     public boolean isNullable() {
         return false;
     }
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ServerBootstrapPreinitialization.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ServerBootstrapPreinitialization.java
index c995f48..826c52f 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ServerBootstrapPreinitialization.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/managed/ServerBootstrapPreinitialization.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -46,7 +47,6 @@
 import org.glassfish.jersey.internal.inject.Binding;
 import org.glassfish.jersey.internal.inject.ClassBinding;
 import org.glassfish.jersey.internal.inject.ReferencingFactory;
-import org.glassfish.jersey.internal.spi.AutoDiscoverable;
 import org.glassfish.jersey.internal.util.collection.Ref;
 import org.glassfish.jersey.model.internal.CommonConfig;
 import org.glassfish.jersey.model.internal.ComponentBag;
@@ -231,31 +231,11 @@
                 }
 
                 @Override
-                public Servlet getServlet(String name) throws ServletException {
-                    return null;
-                }
-
-                @Override
-                public Enumeration<Servlet> getServlets() {
-                    return null;
-                }
-
-                @Override
-                public Enumeration<String> getServletNames() {
-                    return null;
-                }
-
-                @Override
                 public void log(String msg) {
 
                 }
 
                 @Override
-                public void log(Exception exception, String msg) {
-
-                }
-
-                @Override
                 public void log(String message, Throwable throwable) {
 
                 }
diff --git a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/scope/RequestScopeBean.java b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/scope/RequestScopeBean.java
index eff570f..7dd99c8 100644
--- a/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/scope/RequestScopeBean.java
+++ b/incubator/cdi-inject-weld/src/main/java/org/glassfish/jersey/inject/weld/internal/scope/RequestScopeBean.java
@@ -54,7 +54,7 @@
         this.injectionTarget = injectionTargetFactory.createInjectionTarget(null);
     }
 
-    @Override
+    // @Override - Removed in CDI 4
     public boolean isNullable() {
         return false;
     }
diff --git a/incubator/declarative-linking/pom.xml b/incubator/declarative-linking/pom.xml
index b433372..da98b15 100644
--- a/incubator/declarative-linking/pom.xml
+++ b/incubator/declarative-linking/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.incubator</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.ext</groupId>
@@ -74,12 +74,12 @@
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
-<!--        <dependency>-->
-<!--            <groupId>org.glassfish.jersey.media</groupId>-->
-<!--            <artifactId>jersey-media-json-jackson</artifactId>-->
-<!--            <version>${jersey.version}</version>-->
-<!--            <scope>test</scope>-->
-<!--        </dependency>-->
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-json-jackson</artifactId>
+            <version>${jersey.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
@@ -175,22 +175,6 @@
                 </executions>
             </plugin>
             <plugin>
-                <!-- TODO remove after jakartification -->
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>default-test</id> <!-- jakartification-excluded-tests -->
-                        <configuration>
-                            <excludes>
-                                <exclude>org/glassfish/jersey/linking/integration/LinkingTest.java</exclude>
-                                <exclude>org/glassfish/jersey/linking/integration/LinkingManualTest.java</exclude>
-                            </excludes>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                 <inherited>true</inherited>
diff --git a/incubator/gae-integration/pom.xml b/incubator/gae-integration/pom.xml
index 0275167..5a8c869 100644
--- a/incubator/gae-integration/pom.xml
+++ b/incubator/gae-integration/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.incubator</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-gae-integration</artifactId>
diff --git a/incubator/html-json/pom.xml b/incubator/html-json/pom.xml
index 226e827..51ce232 100644
--- a/incubator/html-json/pom.xml
+++ b/incubator/html-json/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.incubator</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.media</groupId>
diff --git a/incubator/injectless-client/pom.xml b/incubator/injectless-client/pom.xml
index d1a31cf..b69d79a 100644
--- a/incubator/injectless-client/pom.xml
+++ b/incubator/injectless-client/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.incubator</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-injectless-client</artifactId>
diff --git a/incubator/kryo/pom.xml b/incubator/kryo/pom.xml
index 3a7576d..9778d5c 100644
--- a/incubator/kryo/pom.xml
+++ b/incubator/kryo/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.incubator</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.media</groupId>
diff --git a/incubator/open-tracing/pom.xml b/incubator/open-tracing/pom.xml
index f58c8a5..9d927e2 100644
--- a/incubator/open-tracing/pom.xml
+++ b/incubator/open-tracing/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.incubator</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.incubator</groupId>
diff --git a/incubator/pom.xml b/incubator/pom.xml
index 65f0a44..c494637 100644
--- a/incubator/pom.xml
+++ b/incubator/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.incubator</groupId>
diff --git a/inject/cdi2-se/pom.xml b/inject/cdi2-se/pom.xml
index 17943cd..46029a1 100644
--- a/inject/cdi2-se/pom.xml
+++ b/inject/cdi2-se/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.inject</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-cdi2-se</artifactId>
@@ -109,6 +109,7 @@
                         <Import-Package>
                             sun.misc.*;resolution:=optional,
                             ${cdi.osgi.version},
+                            jakarta.decorator.*;version="[3.0,5)",
                             ${jakarta.annotation.osgi.version},
                             *
                         </Import-Package>
diff --git a/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/RequestScopeBean.java b/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/RequestScopeBean.java
index 4bf816f..86e97ab 100644
--- a/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/RequestScopeBean.java
+++ b/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/RequestScopeBean.java
@@ -54,7 +54,7 @@
         this.injectionTarget = injectionTargetFactory.createInjectionTarget(null);
     }
 
-    @Override
+    // @Override - Removed in CDI 4
     public boolean isNullable() {
         return false;
     }
diff --git a/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/bean/BeanHelper.java b/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/bean/BeanHelper.java
index 2ae0ebc..584193f 100644
--- a/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/bean/BeanHelper.java
+++ b/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/bean/BeanHelper.java
@@ -147,9 +147,10 @@
     public static <T> void registerSupplier(SupplierClassBinding<T> binding, AfterBeanDiscovery abd,
             Collection<InjectionResolver> resolvers, BeanManager beanManager) {
 
-        Class<Supplier<T>> supplierClass = (Class<Supplier<T>>) binding.getSupplierClass();
-        AnnotatedType<Supplier<T>> annotatedType = beanManager.createAnnotatedType(supplierClass);
-        InjectionTarget<Supplier<T>> injectionTarget = beanManager.createInjectionTarget(annotatedType);
+        final Class<Supplier<T>> supplierClass = (Class<Supplier<T>>) binding.getSupplierClass();
+        final AnnotatedType<Supplier<T>> annotatedType = beanManager.createAnnotatedType(supplierClass);
+        final InjectionTargetFactory<Supplier<T>> injectionTargetFactory = beanManager.getInjectionTargetFactory(annotatedType);
+        final InjectionTarget<Supplier<T>> injectionTarget = injectionTargetFactory.createInjectionTarget(null);
 
         SupplierClassBean<T> supplierBean = new SupplierClassBean<>(binding);
         InjectionTarget<Supplier<T>> jit = getJerseyInjectionTarget(supplierClass, injectionTarget, supplierBean, resolvers);
diff --git a/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/bean/JerseyBean.java b/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/bean/JerseyBean.java
index 9b94750..c6bd602 100644
--- a/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/bean/JerseyBean.java
+++ b/inject/cdi2-se/src/main/java/org/glassfish/jersey/inject/cdi/se/bean/JerseyBean.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -133,7 +133,7 @@
         return false;
     }
 
-    @Override
+    // @Override - Removed in CDI 4
     public boolean isNullable() {
         return false;
     }
diff --git a/inject/hk2/pom.xml b/inject/hk2/pom.xml
index 538aaa6..bc9787e 100644
--- a/inject/hk2/pom.xml
+++ b/inject/hk2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.inject</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-hk2</artifactId>
diff --git a/inject/pom.xml b/inject/pom.xml
index ef42a16..b59717d 100644
--- a/inject/pom.xml
+++ b/inject/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.inject</groupId>
diff --git a/media/jaxb/pom.xml b/media/jaxb/pom.xml
index 26e1282..57bdbbb 100644
--- a/media/jaxb/pom.xml
+++ b/media/jaxb/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-media-jaxb</artifactId>
diff --git a/media/json-binding/pom.xml b/media/json-binding/pom.xml
index 8e67358..80bf389 100644
--- a/media/json-binding/pom.xml
+++ b/media/json-binding/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-media-json-binding</artifactId>
diff --git a/media/json-gson/pom.xml b/media/json-gson/pom.xml
index a1efa74..bcad47d 100644
--- a/media/json-gson/pom.xml
+++ b/media/json-gson/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-media-json-gson</artifactId>
diff --git a/media/json-jackson/pom.xml b/media/json-jackson/pom.xml
index ac5f90b..f056729 100644
--- a/media/json-jackson/pom.xml
+++ b/media/json-jackson/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-media-json-jackson</artifactId>
diff --git a/media/json-jettison/pom.xml b/media/json-jettison/pom.xml
index 695b7c3..93c6b79 100644
--- a/media/json-jettison/pom.xml
+++ b/media/json-jettison/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-media-json-jettison</artifactId>
@@ -53,7 +53,14 @@
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
+                        <!-- Explicitly set versions for packages from GlassFish to allow future uptake of GlassFish 7.x-->
+                        <Import-Package>
+                            jakarta.xml.bind.*;version="[3.0,5)",
+                            *
+                        </Import-Package>
+                    
                         <Export-Package>org.glassfish.jersey.jettison.*</Export-Package>
+                        
                         <!--<Import-Package>
                             com.sun.xml.bind.annotation;resolution:=optional,com.sun.xml.bind.v2.*;resolution:=optional, *
                         </Import-Package>-->
diff --git a/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/JettisonJaxbContext.java b/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/JettisonJaxbContext.java
index f76ab53..6d6b039 100644
--- a/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/JettisonJaxbContext.java
+++ b/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/JettisonJaxbContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,7 +22,6 @@
 import jakarta.xml.bind.JAXBException;
 import jakarta.xml.bind.Marshaller;
 import jakarta.xml.bind.Unmarshaller;
-import jakarta.xml.bind.Validator;
 
 import org.glassfish.jersey.jettison.internal.BaseJsonMarshaller;
 import org.glassfish.jersey.jettison.internal.BaseJsonUnmarshaller;
@@ -300,15 +299,4 @@
     public Marshaller createMarshaller() throws JAXBException {
         return new JettisonJaxbMarshaller(jaxbContext, getJSONConfiguration());
     }
-
-    /**
-     * Simply delegates to underlying JAXBContext implementation.
-     *
-     * @return what underlying JAXBContext returns
-     * @throws jakarta.xml.bind.JAXBException
-     */
-    @Override
-    public Validator createValidator() throws JAXBException {
-        return jaxbContext.createValidator();
-    }
 }
diff --git a/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/internal/JettisonJaxbMarshaller.java b/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/internal/JettisonJaxbMarshaller.java
index cd78fc9..4603572 100644
--- a/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/internal/JettisonJaxbMarshaller.java
+++ b/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/internal/JettisonJaxbMarshaller.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -128,17 +128,17 @@
     }
 
     @Override
-    public void setAdapter(XmlAdapter adapter) {
+    public <A extends XmlAdapter<?, ?>> void setAdapter(A adapter) {
         jaxbMarshaller.setAdapter(adapter);
     }
 
     @Override
-    public <A extends XmlAdapter> void setAdapter(Class<A> type, A adapter) {
+    public <A extends XmlAdapter<?, ?>> void setAdapter(Class<A> type, A adapter) {
         jaxbMarshaller.setAdapter(type, adapter);
     }
 
     @Override
-    public <A extends XmlAdapter> A getAdapter(Class<A> type) {
+    public <A extends XmlAdapter<?, ?>> A getAdapter(Class<A> type) {
         return jaxbMarshaller.getAdapter(type);
     }
 
diff --git a/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/internal/JettisonJaxbUnmarshaller.java b/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/internal/JettisonJaxbUnmarshaller.java
index 3d24d50..377e37a 100644
--- a/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/internal/JettisonJaxbUnmarshaller.java
+++ b/media/json-jettison/src/main/java/org/glassfish/jersey/jettison/internal/JettisonJaxbUnmarshaller.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -123,16 +123,6 @@
     }
 
     @Override
-    public void setValidating(boolean validating) throws JAXBException {
-        this.jaxbUnmarshaller.setValidating(validating);
-    }
-
-    @Override
-    public boolean isValidating() throws JAXBException {
-        return this.jaxbUnmarshaller.isValidating();
-    }
-
-    @Override
     public void setEventHandler(ValidationEventHandler validationEventHandler) throws JAXBException {
         this.jaxbUnmarshaller.setEventHandler(validationEventHandler);
     }
@@ -163,17 +153,17 @@
     }
 
     @Override
-    public void setAdapter(XmlAdapter xmlAdapter) {
+    public <A extends XmlAdapter<?, ?>> void setAdapter(A xmlAdapter) {
         this.jaxbUnmarshaller.setAdapter(xmlAdapter);
     }
 
     @Override
-    public <A extends XmlAdapter> void setAdapter(Class<A> type, A adapter) {
+    public <A extends XmlAdapter<?, ?>> void setAdapter(Class<A> type, A adapter) {
         this.jaxbUnmarshaller.setAdapter(type, adapter);
     }
 
     @Override
-    public <A extends XmlAdapter> A getAdapter(Class<A> type) {
+    public <A extends XmlAdapter<?, ?>> A getAdapter(Class<A> type) {
         return this.jaxbUnmarshaller.getAdapter(type);
     }
 
diff --git a/media/json-processing/pom.xml b/media/json-processing/pom.xml
index 8ad6dc3..a57ab6d 100644
--- a/media/json-processing/pom.xml
+++ b/media/json-processing/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-media-json-processing</artifactId>
diff --git a/media/json-processing/src/main/java/org/glassfish/jersey/jsonp/JsonProcessingFeature.java b/media/json-processing/src/main/java/org/glassfish/jersey/jsonp/JsonProcessingFeature.java
index aa3e96c..f25f8b6 100644
--- a/media/json-processing/src/main/java/org/glassfish/jersey/jsonp/JsonProcessingFeature.java
+++ b/media/json-processing/src/main/java/org/glassfish/jersey/jsonp/JsonProcessingFeature.java
@@ -25,6 +25,7 @@
 
 import org.glassfish.jersey.CommonProperties;
 
+
 /**
  * {@link Feature} used to register JSON-P providers.
  *
diff --git a/media/moxy/pom.xml b/media/moxy/pom.xml
index 0fe17a6..461e510 100644
--- a/media/moxy/pom.xml
+++ b/media/moxy/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-media-moxy</artifactId>
@@ -104,6 +104,11 @@
             <groupId>org.eclipse.parsson</groupId>
             <artifactId>parsson</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.ow2.asm</groupId>
+            <artifactId>asm</artifactId>
+            <version>${asm.version}</version>
+        </dependency>
 
         <dependency>
             <groupId>org.eclipse.persistence</groupId>
@@ -113,6 +118,10 @@
                     <groupId>jakarta.json.bind</groupId>
                     <artifactId>jakarta.json.bind-api</artifactId>
                 </exclusion>
+                <exclusion>
+                    <groupId>org.eclipse.angus</groupId>
+                    <artifactId>angus-activation</artifactId>
+                </exclusion>
             </exclusions>
         </dependency>
 
diff --git a/media/multipart/pom.xml b/media/multipart/pom.xml
index 4051a01..79d4d86 100644
--- a/media/multipart/pom.xml
+++ b/media/multipart/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-media-multipart</artifactId>
@@ -104,7 +104,7 @@
         <profile>
             <id>JettyExclude</id>
             <activation>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <build>
                 <plugins>
@@ -123,7 +123,7 @@
         <profile>
             <id>Jetty11</id>
             <activation>
-                <jdk>[11,)</jdk>
+                <jdk>[17,)</jdk>
             </activation>
             <dependencies>
                 <dependency>
@@ -135,5 +135,4 @@
             </dependencies>
         </profile>
     </profiles>
-
 </project>
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/BodyPart.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/BodyPart.java
index 0e20e25..7287759 100644
--- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/BodyPart.java
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/BodyPart.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,9 +18,11 @@
 
 import java.io.IOException;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 import java.text.ParseException;
 
 import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.GenericType;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.MultivaluedMap;
 import jakarta.ws.rs.ext.MessageBodyReader;
@@ -263,21 +265,42 @@
      * entity instance is not the unconverted content of the body part entity.
      */
     public <T> T getEntityAs(final Class<T> clazz) {
+        return getEntityAs(clazz, clazz);
+    }
+
+    /**
+     * Returns the entity after appropriate conversion to the requested type. This is useful only when the containing
+     * {@link MultiPart} instance has been received, which causes the {@code providers} property to have been set.
+     *
+     * @param genericEntity desired entity type into which the entity should be converted.
+     * @return entity after appropriate conversion to the requested type.
+     *
+     * @throws ProcessingException if an IO error arises during reading an entity.
+     * @throws IllegalArgumentException if no {@link MessageBodyReader} can be found to perform the requested conversion.
+     * @throws IllegalStateException if this method is called when the {@code providers} property has not been set or when the
+     * entity instance is not the unconverted content of the body part entity.
+     */
+    <T> T getEntityAs(final GenericType<T> genericEntity) {
+        return (T) getEntityAs(genericEntity.getRawType(), genericEntity.getType());
+    }
+
+    <T> T getEntityAs(final Class<T> type, Type genericType) {
         if (entity == null || !(entity instanceof BodyPartEntity)) {
             throw new IllegalStateException(LocalizationMessages.ENTITY_HAS_WRONG_TYPE());
         }
-        if (clazz == BodyPartEntity.class) {
-            return clazz.cast(entity);
+        if (type == BodyPartEntity.class) {
+            return type.cast(entity);
         }
 
         final Annotation[] annotations = new Annotation[0];
-        final MessageBodyReader<T> reader = messageBodyWorkers.getMessageBodyReader(clazz, clazz, annotations, mediaType);
+        final MessageBodyReader<T> reader = messageBodyWorkers.getMessageBodyReader(type, genericType, annotations, mediaType);
         if (reader == null) {
-            throw new IllegalArgumentException(LocalizationMessages.NO_AVAILABLE_MBR(clazz, mediaType));
+            throw new IllegalArgumentException(LocalizationMessages.NO_AVAILABLE_MBR(type, mediaType));
         }
 
         try {
-            return reader.readFrom(clazz, clazz, annotations, mediaType, headers, ((BodyPartEntity) entity).getInputStream());
+            return reader.readFrom(type, genericType, annotations, mediaType, headers,
+                    ((BodyPartEntity) entity).getInputStream());
         } catch (final IOException ioe) {
             throw new ProcessingException(LocalizationMessages.ERROR_READING_ENTITY(String.class), ioe);
         }
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/FormDataBodyPart.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/FormDataBodyPart.java
index 2380c44..802cc02 100644
--- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/FormDataBodyPart.java
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/FormDataBodyPart.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,9 +16,14 @@
 
 package org.glassfish.jersey.media.multipart;
 
+import java.io.InputStream;
 import java.text.ParseException;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.GenericType;
 import jakarta.ws.rs.core.MediaType;
 
 import org.glassfish.jersey.media.multipart.internal.LocalizationMessages;
@@ -59,9 +64,10 @@
  * @author Paul Sandoz
  * @author Michal Gajdos
  */
-public class FormDataBodyPart extends BodyPart {
+public class FormDataBodyPart extends BodyPart implements EntityPart {
 
     private final boolean fileNameFix;
+    protected final AtomicBoolean contentRead = new AtomicBoolean(false);
 
     /**
      * Instantiates an unnamed new {@link FormDataBodyPart} with a
@@ -231,6 +237,34 @@
         return formDataContentDisposition.getName();
     }
 
+    @Override
+    public Optional<String> getFileName() {
+        return Optional.ofNullable(getFormDataContentDisposition().getFileName());
+    }
+
+    @Override
+    public InputStream getContent() {
+        return getContent(InputStream.class);
+    }
+
+    @Override
+    public <T> T getContent(Class<T> type) {
+        if (contentRead.compareAndExchange(false, true)) {
+            throw new IllegalStateException(LocalizationMessages.CONTENT_HAS_BEEN_ALREADY_READ());
+        }
+        final Object entity = getEntity();
+        return type.isInstance(entity) ? type.cast(entity) : getEntityAs(type);
+    }
+
+    @Override
+    public <T> T getContent(GenericType<T> type) {
+        if (contentRead.compareAndExchange(false, true)) {
+            throw new IllegalStateException(LocalizationMessages.CONTENT_HAS_BEEN_ALREADY_READ());
+        }
+        final Object entity = getEntity();
+        return type.getRawType().isInstance(entity) ? (T) entity : getEntityAs(type);
+    }
+
     /**
      * Sets the control name.
      *
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/JerseyEntityPartBuilderProvider.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/JerseyEntityPartBuilderProvider.java
new file mode 100644
index 0000000..307eb97
--- /dev/null
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/JerseyEntityPartBuilderProvider.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.media.multipart;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.GenericEntity;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedHashMap;
+import jakarta.ws.rs.core.MultivaluedMap;
+import org.glassfish.jersey.innate.spi.EntityPartBuilderProvider;
+import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
+import org.glassfish.jersey.media.multipart.file.StreamDataBodyPart;
+import org.glassfish.jersey.media.multipart.internal.LocalizationMessages;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Jersey implementation of {@link EntityPart.Builder}.
+ * @since 3.1.0
+ */
+public class JerseyEntityPartBuilderProvider implements EntityPartBuilderProvider {
+
+    @Override
+    public EntityPart.Builder withName(String partName) {
+        return new EnityPartBuilder().withName(partName);
+    }
+
+    private static class EnityPartBuilder implements EntityPart.Builder {
+
+        private String partName;
+        private String fileName = null;
+        private MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
+        private MediaType mediaType = null;
+        private MethodData methodData;
+
+        private EntityPart.Builder withName(String partName) {
+            this.partName = partName;
+            return this;
+        }
+
+        @Override
+        public EntityPart.Builder mediaType(MediaType mediaType) throws IllegalArgumentException {
+            this.mediaType = mediaType;
+            return this;
+        }
+
+        @Override
+        public EntityPart.Builder mediaType(String mediaTypeString) throws IllegalArgumentException {
+            this.mediaType = MediaType.valueOf(mediaTypeString);
+            return this;
+        }
+
+        @Override
+        public EntityPart.Builder header(String headerName, String... headerValues) throws IllegalArgumentException {
+            this.headers.addAll(headerName, headerValues);
+            return this;
+        }
+
+        @Override
+        public EntityPart.Builder headers(MultivaluedMap<String, String> newHeaders) throws IllegalArgumentException {
+            for (Map.Entry<String, List<String>> entry : newHeaders.entrySet()) {
+                header(entry.getKey(), entry.getValue().toArray(new String[0]));
+            }
+            return this;
+        }
+
+        @Override
+        public EntityPart.Builder fileName(String fileName) throws IllegalArgumentException {
+            this.fileName = fileName;
+            return this;
+        }
+
+        @Override
+        public EntityPart.Builder content(InputStream content) throws IllegalArgumentException {
+            methodData = new InputStreamMethodData(content);
+            return this;
+        }
+
+        @Override
+        public <T> EntityPart.Builder content(T content, Class<? extends T> type) throws IllegalArgumentException {
+            if (File.class.equals(type)) {
+                methodData = new FileMethodData((File) content);
+            } else if (InputStream.class.equals(type)) {
+                methodData = new InputStreamMethodData((InputStream) content);
+            } else {
+                methodData = new GenericData(content, null);
+            }
+            return this;
+        }
+
+        @Override
+        public <T> EntityPart.Builder content(T content, GenericType<T> type) throws IllegalArgumentException {
+            if (File.class.equals(type.getRawType())) {
+                methodData = new FileMethodData((File) content);
+            } else if (InputStream.class.equals(type.getRawType())) {
+                methodData = new InputStreamMethodData((InputStream) content);
+            } else {
+                methodData = new GenericData(content, type);
+            }
+            return this;
+        }
+
+        @Override
+        public EntityPart build() throws IllegalStateException, IOException, WebApplicationException {
+            if (methodData == null) {
+                throw new IllegalStateException(LocalizationMessages.ENTITY_CONTENT_NOT_SET());
+            }
+            final FormDataBodyPart bodyPart = methodData.build();
+            return bodyPart;
+        }
+
+
+        private abstract class MethodData<T> {
+            protected MethodData(T content) {
+                this.content = content;
+            }
+            protected final T content;
+            protected abstract FormDataBodyPart build();
+            protected void fillFormData(FormDataBodyPart bodyPart) {
+                FormDataContentDisposition contentDisposition =
+                        FormDataContentDisposition.name(partName).fileName(fileName).build();
+                bodyPart.setContentDisposition(contentDisposition);
+                if (mediaType != null) {
+                    bodyPart.setMediaType(mediaType);
+                }
+                for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
+                    bodyPart.getHeaders().addAll(entry.getKey(), entry.getValue().toArray(new String[0]));
+                }
+            }
+        }
+
+        private class InputStreamMethodData extends MethodData<InputStream> {
+            protected InputStreamMethodData(InputStream content) {
+                super(content);
+            }
+
+            @Override
+            protected FormDataBodyPart build() {
+                final StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart();
+                streamDataBodyPart.setFilename(fileName);
+                fillFormData(streamDataBodyPart);
+                streamDataBodyPart.setStreamEntity(content, mediaType);
+                return streamDataBodyPart;
+            }
+        }
+
+        private class FileMethodData extends MethodData<File> {
+            protected FileMethodData(File content) {
+                super(content);
+            }
+
+            @Override
+            protected FormDataBodyPart build() {
+                final FileDataBodyPart fileDataBodyPart = new FileDataBodyPart();
+                fillFormData(fileDataBodyPart);
+                if (mediaType != null) {
+                    fileDataBodyPart.setFileEntity(content, mediaType);
+                } else {
+                    fileDataBodyPart.setFileEntity(content);
+                }
+                return fileDataBodyPart;
+            }
+        }
+
+        private class GenericData extends MethodData<Object> {
+            private final GenericType<?> genericEntity;
+
+            protected GenericData(Object content, GenericType<?> genericEntity) {
+                super(content);
+                this.genericEntity = genericEntity;
+            }
+
+            @Override
+            protected FormDataBodyPart build() {
+                final FormDataBodyPart formDataBodyPart = new FormDataBodyPart();
+                fillFormData(formDataBodyPart);
+                if (genericEntity != null && !GenericEntity.class.isInstance(content)) {
+                    GenericEntity entity = new GenericEntity(content, genericEntity.getType());
+                    formDataBodyPart.setEntity(entity);
+                } else {
+                    formDataBodyPart.setEntity(content);
+                }
+
+                return formDataBodyPart;
+            }
+        }
+    }
+}
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/MultiPartFeature.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/MultiPartFeature.java
index 3224ec5..c49be99 100644
--- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/MultiPartFeature.java
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/MultiPartFeature.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -20,10 +20,14 @@
 import jakarta.ws.rs.core.Feature;
 import jakarta.ws.rs.core.FeatureContext;
 
+import org.glassfish.jersey.media.multipart.internal.EntityPartReader;
+import org.glassfish.jersey.media.multipart.internal.EntityPartWriter;
 import org.glassfish.jersey.media.multipart.internal.FormDataParamInjectionFeature;
 import org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide;
 import org.glassfish.jersey.media.multipart.internal.MultiPartReaderServerSide;
 import org.glassfish.jersey.media.multipart.internal.MultiPartWriter;
+import org.glassfish.jersey.media.multipart.internal.SingleEntityPartReader;
+import org.glassfish.jersey.media.multipart.internal.SingleEntityPartWriter;
 
 /**
  * Feature used to register Multipart providers.
@@ -45,6 +49,11 @@
 
         context.register(MultiPartWriter.class);
 
+        context.register(EntityPartReader.class);
+        context.register(EntityPartWriter.class);
+        context.register(SingleEntityPartReader.class);
+        context.register(SingleEntityPartWriter.class);
+
         return true;
     }
 }
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/MultiPartFeatureAutodiscoverable.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/MultiPartFeatureAutodiscoverable.java
new file mode 100644
index 0000000..f9cfb9d
--- /dev/null
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/MultiPartFeatureAutodiscoverable.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.media.multipart;
+
+import jakarta.ws.rs.core.FeatureContext;
+import org.glassfish.jersey.internal.spi.AutoDiscoverable;
+
+/**
+ * Automatic registration of {@link MultiPartFeature}.
+ * @since 3.1.0
+ */
+public class MultiPartFeatureAutodiscoverable implements AutoDiscoverable {
+    @Override
+    public void configure(FeatureContext context) {
+        context.register(MultiPartFeature.class);
+    }
+}
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/file/DefaultMediaTypePredictor.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/file/DefaultMediaTypePredictor.java
index f91c723..1493e8f 100644
--- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/file/DefaultMediaTypePredictor.java
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/file/DefaultMediaTypePredictor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -38,6 +38,7 @@
      * Currently supported file extension and MIME Types are -
      * <ul>
      *   <li>".xml" - application/xml</li>
+     *   <li>".json - application/json</li>
      *   <li>".txt" - text/plain</li>
      *   <li>".pdf" - application/pdf</li>
      *   <li>".htm" - text/html</li>
@@ -59,6 +60,7 @@
     public enum CommonMediaTypes {
 
         XML(".xml", MediaType.APPLICATION_XML_TYPE),
+        JSON(".json", MediaType.APPLICATION_JSON_TYPE),
         TXT(".txt", MediaType.TEXT_PLAIN_TYPE),
         HTM(".htm", MediaType.TEXT_HTML_TYPE),
         HTML(".html", MediaType.TEXT_HTML_TYPE),
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/file/StreamDataBodyPart.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/file/StreamDataBodyPart.java
index 3ddedf2..707bedf 100644
--- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/file/StreamDataBodyPart.java
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/file/StreamDataBodyPart.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,6 +18,7 @@
 
 import java.io.InputStream;
 import java.text.MessageFormat;
+import java.util.Optional;
 
 import jakarta.ws.rs.core.MediaType;
 
@@ -275,4 +276,8 @@
         return filename;
     }
 
+    @Override
+    public Optional<String> getFileName() {
+        return Optional.ofNullable(getFilename());
+    }
 }
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/EntityPartReader.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/EntityPartReader.java
new file mode 100644
index 0000000..fb83486
--- /dev/null
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/EntityPartReader.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.media.multipart.internal;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.Providers;
+import org.glassfish.jersey.internal.util.ReflectionHelper;
+import org.glassfish.jersey.media.multipart.BodyPart;
+import org.glassfish.jersey.media.multipart.FormDataBodyPart;
+import org.glassfish.jersey.media.multipart.JerseyEntityPartBuilderProvider;
+import org.glassfish.jersey.media.multipart.MultiPart;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Reader supporting List&lt;EntityPart&gt; Make sure {@code GenericEntity} class is used when reading the
+ * {@link EntityPart}s.
+ * @since 3.1.0
+ */
+@Consumes(MediaType.MULTIPART_FORM_DATA)
+@Singleton
+public class EntityPartReader implements MessageBodyReader<List<EntityPart>> {
+
+    private MultiPartReaderClientSide multiPartReaderClientSide;
+
+    private final Providers providers;
+
+    @Inject
+    public EntityPartReader(@Context Providers providers) {
+        this.providers = providers;
+    }
+
+    @Override
+    public boolean isReadable(Class<?> type, Type generic, Annotation[] annotations, MediaType mediaType) {
+        return List.class.isAssignableFrom(type)
+                && ParameterizedType.class.isInstance(generic)
+                && EntityPart.class.isAssignableFrom(ReflectionHelper.getGenericTypeArgumentClasses(generic).get(0));
+    }
+
+    @Override
+    public List<EntityPart> readFrom(Class<List<EntityPart>> type, Type genericType, Annotation[] annotations,
+                                     MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
+                                     InputStream entityStream) throws IOException, WebApplicationException {
+
+        if (multiPartReaderClientSide == null) {
+            multiPartReaderClientSide = (MultiPartReaderClientSide) providers.getMessageBodyReader(
+                    MultiPart.class, MultiPart.class, new Annotation[0], MediaType.MULTIPART_FORM_DATA_TYPE);
+        }
+
+        final MultiPart multiPart = multiPartReaderClientSide.readFrom(
+                MultiPart.class, MultiPart.class, annotations, mediaType, httpHeaders, entityStream);
+        final List<BodyPart> bodyParts = multiPart.getBodyParts();
+        final List<EntityPart> entityParts = new LinkedList<>();
+
+        for (BodyPart bp : bodyParts) {
+            if (FormDataBodyPart.class.isInstance(bp)) {
+                entityParts.add((EntityPart) bp);
+            } else {
+                final EntityPart ep = new JerseyEntityPartBuilderProvider().withName("")
+                        .mediaType(bp.getMediaType()).content(bp.getEntity()).headers(bp.getHeaders()).build();
+                entityParts.add(ep);
+            }
+        }
+
+        return entityParts;
+    }
+}
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/EntityPartWriter.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/EntityPartWriter.java
new file mode 100644
index 0000000..3b9a301
--- /dev/null
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/EntityPartWriter.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.media.multipart.internal;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Providers;
+import org.glassfish.jersey.internal.util.ReflectionHelper;
+import org.glassfish.jersey.media.multipart.BodyPart;
+import org.glassfish.jersey.media.multipart.MultiPart;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+
+/**
+ * Writer supporting List&lt;EntityPart&gt; Make sure {@code GenericEntity} class is used when sending the
+ * {@link EntityPart}s.
+ * @since 3.1.0
+ */
+@Produces(MediaType.MULTIPART_FORM_DATA)
+@Singleton
+public class EntityPartWriter implements MessageBodyWriter<List<EntityPart>> {
+
+    private MultiPartWriter multiPartWriter;
+
+    private final Providers providers;
+
+    @Inject
+    public EntityPartWriter(@Context Providers providers) {
+        this.providers = providers;
+    }
+
+    @Override
+    public boolean isWriteable(Class<?> type, Type generic, Annotation[] annotations, MediaType mediaType) {
+        return List.class.isAssignableFrom(type)
+                && ParameterizedType.class.isInstance(generic)
+                && EntityPart.class.isAssignableFrom(ReflectionHelper.getGenericTypeArgumentClasses(generic).get(0));
+    }
+
+    @Override
+    public void writeTo(List<EntityPart> entityParts, Class<?> type, Type genericType, Annotation[] annotations,
+                        MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+            throws IOException, WebApplicationException {
+        final MultiPart multiPart = new MultiPart();
+        multiPart.setMediaType(mediaType);
+        for (EntityPart ep : entityParts) {
+            multiPart.bodyPart((BodyPart) ep);
+        }
+
+        if (multiPartWriter == null) {
+            multiPartWriter = (MultiPartWriter) providers.getMessageBodyWriter(
+                    MultiPart.class, MultiPart.class, new Annotation[0], MediaType.MULTIPART_FORM_DATA_TYPE);
+        }
+
+        multiPartWriter.writeTo(multiPart, MultiPart.class, MultiPart.class,
+                annotations, multiPart.getMediaType(), httpHeaders, entityStream);
+    }
+}
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java
index d95b320..6c834d9 100644
--- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -31,6 +31,8 @@
 import java.util.stream.Collectors;
 
 import jakarta.ws.rs.BadRequestException;
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.core.EntityPart;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.MultivaluedMap;
 import jakarta.ws.rs.ext.MessageBodyReader;
@@ -59,7 +61,7 @@
 
 /**
  * Value supplier provider supporting the {@link FormDataParam} injection annotation and entity ({@link FormDataMultiPart})
- * injection.
+ * injection. Also supports {@link FormParam} {@code EntityPart} annotation injection.
  *
  * @author Craig McClanahan
  * @author Paul Sandoz
@@ -311,6 +313,43 @@
         }
     }
 
+    /**
+     * Provider supplier for list of {@link EntityPart} types injected via
+     * {@link jakarta.ws.rs.FormParam} annotation.
+     */
+    private final class ListEntityPartValueProvider extends ValueProvider<List<EntityPart>> {
+
+        private final String name;
+
+        public ListEntityPartValueProvider(final String name) {
+            this.name = name;
+        }
+
+        @Override
+        public List<EntityPart> apply(ContainerRequest request) {
+            return (List<EntityPart>) (List<?>) getEntity(request).getFields(name);
+        }
+    }
+
+    /**
+     * Provider supplier for list of {@link EntityPart} types injected via
+     * {@link jakarta.ws.rs.FormParam} annotation.
+     */
+    private final class EntityPartValueProvider extends ValueProvider<EntityPart> {
+
+        private final String name;
+
+        public EntityPartValueProvider(final String name) {
+            this.name = name;
+        }
+
+        @Override
+        public EntityPart apply(ContainerRequest request) {
+            List<FormDataBodyPart> bodyParts = getEntity(request).getFields(name);
+            return bodyParts.size() != 0 ? bodyParts.get(0) : null;
+        }
+    }
+
     private static final Set<Class<?>> TYPES = initializeTypes();
 
     private static Set<Class<?>> initializeTypes() {
@@ -344,7 +383,7 @@
      * @param extractorProvider multi-valued map parameter extractor provider.
      */
     public FormDataParamValueParamProvider(Provider<MultivaluedParameterExtractorProvider> extractorProvider) {
-        super(extractorProvider, Parameter.Source.ENTITY, Parameter.Source.UNKNOWN);
+        super(extractorProvider, Parameter.Source.ENTITY, Parameter.Source.FORM, Parameter.Source.UNKNOWN);
     }
 
     @Override
@@ -386,6 +425,16 @@
             } else {
                 return new FormDataParamValueProvider(parameter, get(parameter));
             }
+        } else if (FormParam.class.equals(parameter.getSourceAnnotation().annotationType())) {
+            final String paramName = parameter.getSourceName();
+            if (Collection.class == rawType || List.class == rawType) {
+                final Class clazz = ReflectionHelper.getGenericTypeArgumentClasses(parameter.getType()).get(0);
+                if (EntityPart.class.equals(clazz)) {
+                    return new ListEntityPartValueProvider(paramName);
+                }
+            } else if (EntityPart.class.equals(rawType)) {
+                return new EntityPartValueProvider(paramName);
+            }
         }
 
         return null;
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/MultiPartWriter.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/MultiPartWriter.java
index 7873872..db5fbc7 100644
--- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/MultiPartWriter.java
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/MultiPartWriter.java
@@ -31,6 +31,7 @@
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.WebApplicationException;
 import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.GenericEntity;
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.MultivaluedMap;
@@ -197,14 +198,21 @@
                 bodyEntity = ((BodyPartEntity) bodyEntity).getInputStream();
             }
 
+            Type bodyType = bodyClass;
+            if (GenericEntity.class.isInstance(bodyEntity)) {
+                bodyClass = ((GenericEntity<?>) bodyEntity).getRawType();
+                bodyType = ((GenericEntity) bodyEntity).getType();
+                bodyEntity = ((GenericEntity<?>) bodyEntity).getEntity();
+            }
+
             final MessageBodyWriter bodyWriter = providers.getMessageBodyWriter(
                     bodyClass,
-                    bodyClass,
+                    bodyType,
                     EMPTY_ANNOTATIONS,
                     bodyMediaType);
 
             if (bodyWriter == null) {
-                throw new IllegalArgumentException(LocalizationMessages.NO_AVAILABLE_MBW(bodyClass, mediaType));
+                throw new IllegalArgumentException(LocalizationMessages.NO_AVAILABLE_MBW(bodyClass, bodyMediaType));
             }
 
             bodyWriter.writeTo(
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/SingleEntityPartReader.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/SingleEntityPartReader.java
new file mode 100644
index 0000000..9b7589e
--- /dev/null
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/SingleEntityPartReader.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.media.multipart.internal;
+
+import jakarta.inject.Inject;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.Providers;
+import org.glassfish.jersey.media.multipart.BodyPart;
+import org.glassfish.jersey.media.multipart.FormDataBodyPart;
+import org.glassfish.jersey.media.multipart.JerseyEntityPartBuilderProvider;
+import org.glassfish.jersey.media.multipart.MultiPart;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.LinkedList;
+import java.util.List;
+
+public class SingleEntityPartReader implements MessageBodyReader<EntityPart> {
+
+    private MultiPartReaderClientSide multiPartReaderClientSide;
+
+    private final Providers providers;
+
+    @Inject
+    public SingleEntityPartReader(@Context Providers providers) {
+        this.providers = providers;
+    }
+
+    @Override
+    public boolean isReadable(Class<?> type, Type generic, Annotation[] annotations, MediaType mediaType) {
+        return EntityPart.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public EntityPart readFrom(Class<EntityPart> type, Type genericType, Annotation[] annotations,
+                                     MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
+                                     InputStream entityStream) throws IOException, WebApplicationException {
+
+        if (multiPartReaderClientSide == null) {
+            multiPartReaderClientSide = (MultiPartReaderClientSide) providers.getMessageBodyReader(
+                    MultiPart.class, MultiPart.class, new Annotation[0], MediaType.MULTIPART_FORM_DATA_TYPE);
+        }
+
+        final MultiPart multiPart = multiPartReaderClientSide.readFrom(
+                MultiPart.class, MultiPart.class, annotations, mediaType, httpHeaders, entityStream);
+        final List<BodyPart> bodyParts = multiPart.getBodyParts();
+        final List<EntityPart> entityParts = new LinkedList<>();
+
+        for (BodyPart bp : bodyParts) {
+            if (FormDataBodyPart.class.isInstance(bp)) {
+                entityParts.add((EntityPart) bp);
+            } else {
+                final EntityPart ep = new JerseyEntityPartBuilderProvider().withName("")
+                        .mediaType(bp.getMediaType()).content(bp.getEntity()).headers(bp.getHeaders()).build();
+                entityParts.add(ep);
+            }
+            // consume all bodyParts
+        }
+
+        return entityParts.get(0);
+    }
+}
diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/SingleEntityPartWriter.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/SingleEntityPartWriter.java
new file mode 100644
index 0000000..9150dc6
--- /dev/null
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/SingleEntityPartWriter.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.media.multipart.internal;
+
+import jakarta.inject.Inject;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Providers;
+import org.glassfish.jersey.media.multipart.BodyPart;
+import org.glassfish.jersey.media.multipart.MultiPart;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+public class SingleEntityPartWriter implements MessageBodyWriter<EntityPart> {
+
+    private MultiPartWriter multiPartWriter;
+
+    private final Providers providers;
+
+    @Inject
+    public SingleEntityPartWriter(@Context Providers providers) {
+        this.providers = providers;
+    }
+
+    @Override
+    public boolean isWriteable(Class<?> type, Type generic, Annotation[] annotations, MediaType mediaType) {
+        return EntityPart.class.isAssignableFrom(type);
+    }
+
+    @Override
+    public void writeTo(EntityPart entityParts, Class<?> type, Type genericType, Annotation[] annotations,
+                        MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+            throws IOException, WebApplicationException {
+        final MultiPart multiPart = new MultiPart();
+        multiPart.setMediaType(mediaType);
+        multiPart.bodyPart((BodyPart) entityParts);
+
+        if (multiPartWriter == null) {
+            multiPartWriter = (MultiPartWriter) providers.getMessageBodyWriter(
+                    MultiPart.class, MultiPart.class, new Annotation[0], MediaType.MULTIPART_FORM_DATA_TYPE);
+        }
+
+        multiPartWriter.writeTo(multiPart, MultiPart.class, MultiPart.class,
+                annotations, multiPart.getMediaType(), httpHeaders, entityStream);
+    }
+}
diff --git a/media/multipart/src/main/resources/META-INF/services/org.glassfish.jersey.innate.spi.EntityPartBuilderProvider b/media/multipart/src/main/resources/META-INF/services/org.glassfish.jersey.innate.spi.EntityPartBuilderProvider
new file mode 100644
index 0000000..32738ac
--- /dev/null
+++ b/media/multipart/src/main/resources/META-INF/services/org.glassfish.jersey.innate.spi.EntityPartBuilderProvider
@@ -0,0 +1 @@
+org.glassfish.jersey.media.multipart.JerseyEntityPartBuilderProvider
\ No newline at end of file
diff --git a/media/multipart/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable b/media/multipart/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable
new file mode 100644
index 0000000..04a6776
--- /dev/null
+++ b/media/multipart/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable
@@ -0,0 +1 @@
+org.glassfish.jersey.media.multipart.MultiPartFeatureAutodiscoverable
\ No newline at end of file
diff --git a/media/multipart/src/main/resources/org/glassfish/jersey/media/multipart/internal/localization.properties b/media/multipart/src/main/resources/org/glassfish/jersey/media/multipart/internal/localization.properties
index 8a7b4ba..13e7136 100644
--- a/media/multipart/src/main/resources/org/glassfish/jersey/media/multipart/internal/localization.properties
+++ b/media/multipart/src/main/resources/org/glassfish/jersey/media/multipart/internal/localization.properties
@@ -15,6 +15,8 @@
 #
 
 cannot.inject.file=Cannot provide file for an entity body part.
+content.has.been.already.read=Content method has already been invoked.
+entity.content.not.set=EntityPart content is not set.
 entity.has.wrong.type=Entity instance does not contain the unconverted content.
 error.charset.unsupported={0} charset is not supported.
 error.filename.unsupported=Unsupported filename parameter {0}. 
diff --git a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/MediaTypeTest.java b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/MediaTypeTest.java
new file mode 100644
index 0000000..cd3d884
--- /dev/null
+++ b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/MediaTypeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.media.multipart;
+
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.MediaType;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class MediaTypeTest {
+    @Test
+    public void testInputStreamDataMediaType() throws IOException {
+        ByteArrayInputStream bais = new ByteArrayInputStream("test".getBytes());
+        EntityPart entityPart = EntityPart.withName("textFile").fileName("test.txt")
+                .content(bais)
+                .mediaType(MediaType.TEXT_PLAIN_TYPE)
+                .build();
+        assertEquals(MediaType.TEXT_PLAIN_TYPE, entityPart.getMediaType());
+    }
+
+    @Test
+    public void testFileDataMediaType() throws IOException {
+        EntityPart entityPart = EntityPart.withName("textFile")
+                .content(new File("anyname"), File.class)
+                .mediaType(MediaType.TEXT_PLAIN_TYPE)
+                .build();
+        assertEquals(MediaType.TEXT_PLAIN_TYPE, entityPart.getMediaType());
+    }
+
+    @Test
+    public void testGenericDataMediaType() throws IOException {
+        EntityPart entityPart = EntityPart.withName("textFile")
+                .content("Hello", String.class)
+                .mediaType(MediaType.TEXT_PLAIN_TYPE)
+                .build();
+        assertEquals(MediaType.TEXT_PLAIN_TYPE, entityPart.getMediaType());
+    }
+
+    @Test
+    public void testInputStreamDataNullMediaType() throws IOException {
+        ByteArrayInputStream bais = new ByteArrayInputStream("test".getBytes());
+        EntityPart entityPart = EntityPart.withName("textFile").fileName("test.txt")
+                .content(bais)
+                .build();
+        assertEquals(MediaType.APPLICATION_OCTET_STREAM_TYPE, entityPart.getMediaType());
+    }
+
+    @Test
+    public void testGenericDataNullMediaType() throws IOException {
+        EntityPart entityPart = EntityPart.withName("textFile")
+                .content("Hello", String.class)
+                .build();
+        assertEquals(MediaType.TEXT_PLAIN_TYPE, entityPart.getMediaType());
+    }
+}
diff --git a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/file/FileDataBodyPartTest.java b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/file/FileDataBodyPartTest.java
index c35f468..70dc2df 100644
--- a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/file/FileDataBodyPartTest.java
+++ b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/file/FileDataBodyPartTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -86,6 +86,12 @@
         fdbp.setFileEntity(file, expectedType);
         checkEntityAttributes(name, fdbp, file, expectedType);
 
+        file = new File("pom.json");
+        name = "json";
+        fdbp = new FileDataBodyPart(name, file);
+        expectedType = DefaultMediaTypePredictor.CommonMediaTypes.JSON.getMediaType();
+        checkEntityAttributes(name, fdbp, file, expectedType);
+
         file = new File("pom.png");
         name = "png";
         fdbp = new FileDataBodyPart("png", file);
diff --git a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/EntityPartBeansTest.java b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/EntityPartBeansTest.java
new file mode 100644
index 0000000..effb565
--- /dev/null
+++ b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/EntityPartBeansTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.media.multipart.internal;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.GenericEntity;
+import jakarta.ws.rs.core.MediaType;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class EntityPartBeansTest extends JerseyTest {
+
+    @Path("/form-field-injected")
+    public static class MultiPartFieldInjectedResource {
+        @FormParam("string")
+        EntityPart stringEntityPart;
+
+        @POST
+        @Path("xml-jaxb-part")
+        @Consumes(MediaType.MULTIPART_FORM_DATA)
+        public String post() throws IOException {
+            return stringEntityPart.getContent(String.class) + ":" + stringEntityPart.getFileName().get();
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(MultiPartFieldInjectedResource.class);
+    }
+
+    @Test
+    public void testInjectedEntityPartBeans() throws IOException {
+        final WebTarget target = target().path("/form-field-injected/xml-jaxb-part");
+
+        final EntityPart entityPart = EntityPart.withName("string").fileName("string")
+                .content("STRING", String.class)
+                .build();
+
+        final GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(List.of(entityPart)) {};
+
+        final String s = target.request().post(Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE), String.class);
+        assertEquals("STRING:string", s);
+    }
+}
diff --git a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/EntityPartTest.java b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/EntityPartTest.java
new file mode 100644
index 0000000..e6bd4e6
--- /dev/null
+++ b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/EntityPartTest.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.media.multipart.internal;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.GenericEntity;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.internal.util.ReflectionHelper;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class EntityPartTest extends JerseyTest {
+
+    private static final GenericType<List<EntityPart>> LIST_ENTITY_PART_TYPE = new GenericType<List<EntityPart>>(){};
+    private static final GenericType<AtomicReference<String>> ATOMIC_REFERENCE_GENERIC_TYPE = new GenericType<>(){};
+
+    @Path("/")
+    public static class EntityPartTestResource {
+        @GET
+        public Response getResponse() throws IOException {
+            List<EntityPart> list = new LinkedList<>();
+            list.add(EntityPart.withName("part-01").content("TEST1").build());
+            list.add(EntityPart.withName("part-02").content("TEST2").build());
+            GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+            return Response.ok(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE).build();
+        }
+
+        @POST
+        @Path("/postList")
+        public String postEntityPartList(List<EntityPart> list) throws IOException {
+            String entity = list.get(0).getContent(String.class) + list.get(1).getContent(String.class);
+            return entity;
+        }
+
+        @POST
+        @Path("/postForm")
+        public String postEntityPartForm(@FormParam("part-01") EntityPart part1, @FormParam("part-02") EntityPart part2)
+                throws IOException {
+            String entity = part1.getContent(String.class) + part2.getContent(String.class);
+            return entity;
+        }
+
+        @POST
+        @Path("/postListForm")
+        public String postEntityPartForm(@FormParam("part-0x") List<EntityPart> part)
+                throws IOException {
+            String entity = part.get(0).getContent(String.class) + part.get(1).getContent(String.class);
+            return entity;
+        }
+
+        @POST
+        @Path("/postStreams")
+        public Response postEntityStreams(@FormParam("name1") EntityPart part1,
+                                        @FormParam("name2") EntityPart part2,
+                                        @FormParam("name3") EntityPart part3) throws IOException {
+            List<EntityPart> list = new LinkedList<>();
+            list.add(EntityPart.withName(part1.getName()).fileName(part1.getFileName().get()).content(
+                    new ByteArrayInputStream(part1.getContent(String.class).getBytes(StandardCharsets.UTF_8))).build());
+            list.add(EntityPart.withName(part2.getName()).fileName(part2.getFileName().get()).content(
+                    new ByteArrayInputStream(part2.getContent(String.class).getBytes(StandardCharsets.UTF_8))).build());
+            list.add(EntityPart.withName(part3.getName()).fileName(part3.getFileName().get())
+                    .content(part3.getContent(StringHolder.class), StringHolder.class)
+                    .mediaType(part3.getMediaType()).build());
+            GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+            return Response.ok(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE).build();
+        }
+
+        @POST
+        @Path("/postHeaders")
+        public Response postEntityStreams(@FormParam("name1") EntityPart part1) throws IOException {
+            List<EntityPart> list = new LinkedList<>();
+            list.add(EntityPart.withName(part1.getName()).content(part1.getContent(String.class))
+                    .headers(part1.getHeaders()).build());
+            GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+            return Response.ok(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE).build();
+        }
+
+        @POST
+        @Path("/postGeneric")
+        public Response postGeneric(@FormParam("name1") EntityPart part1) throws IOException {
+            List<EntityPart> list = new LinkedList<>();
+            list.add(EntityPart.withName(part1.getName())
+                    .content(part1.getContent(ATOMIC_REFERENCE_GENERIC_TYPE), ATOMIC_REFERENCE_GENERIC_TYPE)
+                    .mediaType(MediaType.TEXT_PLAIN_TYPE)
+                    .build());
+            GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+            return Response.ok(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE).build();
+        }
+
+        @POST
+        @Path("/postFormVarious")
+        public Response postFormVarious(@FormParam("name1") EntityPart part1,
+                                        @FormParam("name2") InputStream part2,
+                                        @FormParam("name3") String part3) throws IOException {
+            List<EntityPart> list = new LinkedList<>();
+            list.add(EntityPart.withName(part1.getName())
+                    .content(part1.getContent(String.class) + new String(part2.readAllBytes()) + part3)
+                    .mediaType(MediaType.TEXT_PLAIN_TYPE)
+                    .build());
+            GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+            return Response.ok(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE).build();
+        }
+
+        @GET
+        @Produces(MediaType.MULTIPART_FORM_DATA)
+        @Path("/getList")
+        public List<EntityPart> getList() throws IOException {
+            List<EntityPart> list = new LinkedList<>();
+            list.add(EntityPart.withName("name1").content("data1").build());
+            return list;
+        }
+    }
+
+    public static class StringHolder extends AtomicReference<String> {
+        StringHolder(String name) {
+            set(name);
+        }
+    }
+
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public static class StringHolderWorker implements MessageBodyReader<StringHolder>, MessageBodyWriter<StringHolder> {
+
+        @Override
+        public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+            return type == StringHolder.class;
+        }
+
+        @Override
+        public StringHolder readFrom(Class<StringHolder> type, Type genericType, Annotation[] annotations,
+                                     MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
+                                     InputStream entityStream) throws IOException, WebApplicationException {
+            final StringHolder holder = new StringHolder(new String(entityStream.readAllBytes()));
+            return holder;
+        }
+
+        @Override
+        public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+            return type == StringHolder.class;
+        }
+
+        @Override
+        public void writeTo(StringHolder s, Class<?> type, Type genericType, Annotation[] annotations,
+                            MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
+                            OutputStream entityStream) throws IOException, WebApplicationException {
+            entityStream.write(s.get().getBytes(StandardCharsets.UTF_8));
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(EntityPartTestResource.class,
+                StringHolderWorker.class, AtomicReferenceProvider.class)
+                .property(ServerProperties.WADL_FEATURE_DISABLE, true);
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.register(StringHolderWorker.class).register(AtomicReferenceProvider.class);
+    }
+
+    @Test
+    public void getEntityPartListTest() throws IOException {
+        try (Response response = target().request().get()) {
+            List<EntityPart> list = response.readEntity(LIST_ENTITY_PART_TYPE);
+            assertEquals("TEST1", list.get(0).getContent(String.class));
+            assertEquals("TEST2", list.get(1).getContent(String.class));
+        }
+    }
+
+    @Test
+    public void postEntityPartListTest() throws IOException {
+        List<EntityPart> list = new LinkedList<>();
+        list.add(EntityPart.withName("part-01").content("TEST").build());
+        list.add(EntityPart.withName("part-02").content("1").build());
+        GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+        Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+        try (Response response = target("/postList").request().post(entity)) {
+            assertEquals("TEST1", response.readEntity(String.class));
+        }
+    }
+
+    @Test
+    public void postEntityPartFormParamTest() throws IOException {
+        List<EntityPart> list = new LinkedList<>();
+        list.add(EntityPart.withName("part-01").content("TEST").build());
+        list.add(EntityPart.withName("part-02").content("1").build());
+        GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+        Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+        try (Response response = target("/postForm").request().post(entity)) {
+            assertEquals("TEST1", response.readEntity(String.class));
+        }
+    }
+
+    @Test
+    public void postListEntityPartFormParamTest() throws IOException {
+        List<EntityPart> list = new LinkedList<>();
+        list.add(EntityPart.withName("part-0x").content("TEST").build());
+        list.add(EntityPart.withName("part-0x").content("1").build());
+        GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+        Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+        try (Response response = target("/postListForm").request().post(entity)) {
+            assertEquals("TEST1", response.readEntity(String.class));
+        }
+    }
+
+    @Test
+    public void postEntityPartStreamsTest() throws IOException {
+        List<EntityPart> list = new LinkedList<>();
+        list.add(EntityPart.withName("name1").fileName("file1.doc").content(
+                new ByteArrayInputStream("data1".getBytes(StandardCharsets.UTF_8))).build());
+        list.add(EntityPart.withName("name2").fileName("file2.doc").content(
+                new ByteArrayInputStream("data2".getBytes(StandardCharsets.UTF_8))).build());
+        list.add(EntityPart.withName("name3").fileName("file3.xml")
+                .content(new StringHolder("data3"), StringHolder.class)
+                .mediaType(MediaType.TEXT_PLAIN_TYPE).build());
+        GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {
+        };
+        Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+
+        try (Response response = target("/postStreams").request().post(entity)) {
+            List<EntityPart> result = response.readEntity(LIST_ENTITY_PART_TYPE);
+
+            EntityPart part1 = result.get(0);
+            assertEquals("name1", part1.getName());
+            assertEquals("file1.doc", part1.getFileName().get());
+            assertEquals("data1", part1.getContent(String.class));
+
+            EntityPart part2 = result.get(1);
+            assertEquals("name2", part2.getName());
+            assertEquals("file2.doc", part2.getFileName().get());
+            assertEquals("data2", part2.getContent(String.class));
+
+            EntityPart part3 = result.get(2);
+            assertEquals("name3", part3.getName());
+            assertEquals("file3.xml", part3.getFileName().get());
+            assertEquals("data3", part3.getContent(String.class));
+            assertEquals(MediaType.TEXT_PLAIN_TYPE, part3.getMediaType());
+        }
+    }
+
+    @Test
+    public void postHeaderTest() throws IOException {
+        List<EntityPart> list = new LinkedList<>();
+        list.add(EntityPart.withName("name1").content("data1")
+                .header("header-01", "value-01").build());
+        GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+        Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+        try (Response response = target("/postHeaders").request().post(entity)) {
+            List<EntityPart> result = response.readEntity(LIST_ENTITY_PART_TYPE);
+            assertEquals("value-01", result.get(0).getHeaders().getFirst("header-01"));
+            assertEquals("data1", result.get(0).getContent(String.class));
+        }
+    }
+
+    @Test
+    public void postHeaderNoListTest() throws IOException {
+        EntityPart entityPart = EntityPart.withName("name1").content("data1").header("header-01", "value-01").build();
+        Entity entity = Entity.entity(entityPart, MediaType.MULTIPART_FORM_DATA_TYPE);
+        try (Response response = target("/postHeaders").request().post(entity)) {
+            response.bufferEntity();
+            List<EntityPart> result = response.readEntity(LIST_ENTITY_PART_TYPE);
+            assertEquals("value-01", result.get(0).getHeaders().getFirst("header-01"));
+            assertEquals("data1", result.get(0).getContent(String.class));
+
+            EntityPart firstEntity = response.readEntity(EntityPart.class);
+            assertEquals("value-01", result.get(0).getHeaders().getFirst("header-01"));
+        }
+    }
+
+    @Consumes(MediaType.TEXT_PLAIN)
+    @Produces(MediaType.TEXT_PLAIN)
+    public static class AtomicReferenceProvider implements
+            MessageBodyReader<AtomicReference<String>>,
+            MessageBodyWriter<AtomicReference<String>> {
+
+        @Override
+        public boolean isReadable(Class<?> type, Type generic, Annotation[] annotations, MediaType mediaType) {
+            return type == AtomicReference.class
+                    && ParameterizedType.class.isInstance(generic)
+                    && String.class.isAssignableFrom(ReflectionHelper.getGenericTypeArgumentClasses(generic).get(0));
+        }
+
+        @Override
+        public AtomicReference<String> readFrom(Class<AtomicReference<String>> type, Type genericType,
+                                                Annotation[] annotations, MediaType mediaType,
+                                                MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+                throws IOException, WebApplicationException {
+            return new AtomicReference<String>(new String(entityStream.readAllBytes(), StandardCharsets.UTF_8));
+        }
+
+        @Override
+        public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+            return isReadable(type, genericType, annotations, mediaType);
+        }
+
+        @Override
+        public void writeTo(AtomicReference<String> stringAtomicReference, Class<?> type, Type genericType,
+                            Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
+                            OutputStream entityStream) throws IOException, WebApplicationException {
+            entityStream.write(stringAtomicReference.get().getBytes(StandardCharsets.UTF_8));
+        }
+    }
+
+    @Test
+    public void genericEntityTest() throws IOException {
+        List<EntityPart> list = new LinkedList<>();
+        list.add(EntityPart.withName("name1")
+                .content(new AtomicReference<String>("data1"), ATOMIC_REFERENCE_GENERIC_TYPE)
+                .mediaType(MediaType.TEXT_PLAIN_TYPE)
+                .build());
+        GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+        Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+        try (Response response = target("/postGeneric").request().post(entity)) {
+            List<EntityPart> result = response.readEntity(LIST_ENTITY_PART_TYPE);
+            assertEquals("data1", result.get(0).getContent(String.class));
+        }
+    }
+
+    @Test
+    public void postVariousTest() throws IOException {
+        List<EntityPart> list = new LinkedList<>();
+        list.add(EntityPart.withName("name1").content("Hello ").build());
+        list.add(EntityPart.withName("name2").content("world").build());
+        list.add(EntityPart.withName("name3").content("!").build());
+        GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {
+        };
+        Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+
+        try (Response response = target("/postFormVarious").request().post(entity)) {
+            List<EntityPart> result = response.readEntity(LIST_ENTITY_PART_TYPE);
+            assertEquals("Hello world!", result.get(0).getContent(String.class));
+        }
+    }
+
+    @Test
+    public void getListTest() throws IOException {
+        try (Response response = target("/getList").request().get()) {
+            List<EntityPart> result = response.readEntity(LIST_ENTITY_PART_TYPE);
+            assertEquals("data1", result.get(0).getContent(String.class));
+        }
+    }
+}
diff --git a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/MultiPartHeaderModificationTest.java b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/MultiPartHeaderModificationTest.java
index 4a7ff89..e6ff2ed 100644
--- a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/MultiPartHeaderModificationTest.java
+++ b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/MultiPartHeaderModificationTest.java
@@ -64,7 +64,7 @@
         return Arrays.asList(new Object[][] {
                 {new HttpUrlConnectorProvider(), false},
                 {new GrizzlyConnectorProvider(), true},
-                {new JettyConnectorProvider(), false},
+//                {new JettyConnectorProvider(), true},
                 {new ApacheConnectorProvider(), true},
         });
     }
diff --git a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/MultiPartJerseyTest.java b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/MultiPartJerseyTest.java
index c7487c9..d8e298d 100644
--- a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/MultiPartJerseyTest.java
+++ b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/MultiPartJerseyTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/media/pom.xml b/media/pom.xml
index ef6cf27..52205e4 100644
--- a/media/pom.xml
+++ b/media/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.media</groupId>
diff --git a/media/sse/pom.xml b/media/sse/pom.xml
index cdf1fc4..190b837 100644
--- a/media/sse/pom.xml
+++ b/media/sse/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.media</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-media-sse</artifactId>
diff --git a/mvnw b/mvnw
new file mode 100755
index 0000000..8d937f4
--- /dev/null
+++ b/mvnw
@@ -0,0 +1,308 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.2.0
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /usr/local/etc/mavenrc ] ; then
+    . /usr/local/etc/mavenrc
+  fi
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "$(uname)" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
+      else
+        JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=$(java-config --jre-home)
+  fi
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
+    JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="$(which javac)"
+  if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=$(which readlink)
+    if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
+      if $darwin ; then
+        javaHome="$(dirname "\"$javaExecutable\"")"
+        javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
+      else
+        javaExecutable="$(readlink -f "\"$javaExecutable\"")"
+      fi
+      javaHome="$(dirname "\"$javaExecutable\"")"
+      javaHome=$(expr "$javaHome" : '\(.*\)/bin')
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=$(cd "$wdir/.." || exit 1; pwd)
+    fi
+    # end of workaround
+  done
+  printf '%s' "$(cd "$basedir" || exit 1; pwd)"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    # Remove \r in case we run on Windows within Git Bash
+    # and check out the repository with auto CRLF management
+    # enabled. Otherwise, we may read lines that are delimited with
+    # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
+    # splitting rules.
+    tr -s '\r\n' ' ' < "$1"
+  fi
+}
+
+log() {
+  if [ "$MVNW_VERBOSE" = true ]; then
+    printf '%s\n' "$1"
+  fi
+}
+
+BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
+log "$MAVEN_PROJECTBASEDIR"
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
+if [ -r "$wrapperJarPath" ]; then
+    log "Found $wrapperJarPath"
+else
+    log "Couldn't find $wrapperJarPath, downloading it ..."
+
+    if [ -n "$MVNW_REPOURL" ]; then
+      wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+    else
+      wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+    fi
+    while IFS="=" read -r key value; do
+      # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
+      safeValue=$(echo "$value" | tr -d '\r')
+      case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
+      esac
+    done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+    log "Downloading from: $wrapperUrl"
+
+    if $cygwin; then
+      wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
+    fi
+
+    if command -v wget > /dev/null; then
+        log "Found wget ... using wget"
+        [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        else
+            wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        log "Found curl ... using curl"
+        [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+        else
+            curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+        fi
+    else
+        log "Falling back to using Java to download"
+        javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaSource=$(cygpath --path --windows "$javaSource")
+          javaClass=$(cygpath --path --windows "$javaClass")
+        fi
+        if [ -e "$javaSource" ]; then
+            if [ ! -e "$javaClass" ]; then
+                log " - Compiling MavenWrapperDownloader.java ..."
+                ("$JAVA_HOME/bin/javac" "$javaSource")
+            fi
+            if [ -e "$javaClass" ]; then
+                log " - Running MavenWrapperDownloader.java ..."
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+# If specified, validate the SHA-256 sum of the Maven wrapper jar file
+wrapperSha256Sum=""
+while IFS="=" read -r key value; do
+  case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
+  esac
+done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+if [ -n "$wrapperSha256Sum" ]; then
+  wrapperSha256Result=false
+  if command -v sha256sum > /dev/null; then
+    if echo "$wrapperSha256Sum  $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
+      wrapperSha256Result=true
+    fi
+  elif command -v shasum > /dev/null; then
+    if echo "$wrapperSha256Sum  $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
+      wrapperSha256Result=true
+    fi
+  else
+    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
+    echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
+    exit 1
+  fi
+  if [ $wrapperSha256Result = false ]; then
+    echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
+    echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
+    echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
+    exit 1
+  fi
+fi
+
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+# shellcheck disable=SC2086 # safe args
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  $MAVEN_DEBUG_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
new file mode 100644
index 0000000..c4586b5
--- /dev/null
+++ b/mvnw.cmd
@@ -0,0 +1,205 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements.  See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership.  The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License.  You may obtain a copy of the License at
+@REM
+@REM    http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied.  See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.2.0
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM     e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM set title of command window
+title %0
+@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on"  echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
+)
+
+@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
+if exist %WRAPPER_JAR% (
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Found %WRAPPER_JAR%
+    )
+) else (
+    if not "%MVNW_REPOURL%" == "" (
+        SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+    )
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Couldn't find %WRAPPER_JAR%, downloading it ...
+        echo Downloading from: %WRAPPER_URL%
+    )
+
+    powershell -Command "&{"^
+		"$webclient = new-object System.Net.WebClient;"^
+		"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+		"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+		"}"^
+		"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
+		"}"
+    if "%MVNW_VERBOSE%" == "true" (
+        echo Finished downloading %WRAPPER_JAR%
+    )
+)
+@REM End of extension
+
+@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
+SET WRAPPER_SHA_256_SUM=""
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+    IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
+)
+IF NOT %WRAPPER_SHA_256_SUM%=="" (
+    powershell -Command "&{"^
+       "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
+       "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
+       "  Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
+       "  Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
+       "  Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
+       "  exit 1;"^
+       "}"^
+       "}"
+    if ERRORLEVEL 1 goto error
+)
+
+@REM Provide a "standardized" way to retrieve the CLI args that will
+@REM work with both Windows and non-Windows executions.
+set MAVEN_CMD_LINE_ARGS=%*
+
+%MAVEN_JAVA_EXE% ^
+  %JVM_CONFIG_MAVEN_PROPS% ^
+  %MAVEN_OPTS% ^
+  %MAVEN_DEBUG_OPTS% ^
+  -classpath %WRAPPER_JAR% ^
+  "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+  %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
+
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
index 2d6016c..b916f12 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
     <groupId>org.glassfish.jersey</groupId>
     <artifactId>project</artifactId>
     <packaging>pom</packaging>
-    <version>3.0.99-SNAPSHOT</version>
+    <version>3.1.99-SNAPSHOT</version>
     <name>jersey</name>
     <description>
         Eclipse Jersey is the open source (under dual EPL+GPL license) Jakarta RESTful WebServices 3.0
@@ -739,8 +739,8 @@
                     <version>8.1.8.v20121106</version>
                 </plugin>
                 <plugin>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-maven-plugin</artifactId>
+                    <groupId>org.eclipse.jetty.ee10</groupId>
+                    <artifactId>jetty-ee10-maven-plugin</artifactId>
                     <version>${jetty.plugin.version}</version>
                 </plugin>
                 <plugin>
@@ -1487,7 +1487,7 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
-                <version>3.2.0</version>
+                <version>3.4.1</version>
                 <!-- Run this plugin report sets only in the main Jersey pom -->
                 <inherited>false</inherited>
                 <configuration>
@@ -1622,10 +1622,15 @@
                 <artifactId>jakarta.activation-api</artifactId>
                 <version>${jakarta.activation-api.version}</version>
             </dependency>
+            <dependency>
+                <groupId>jakarta.servlet</groupId>
+                <artifactId>jakarta.servlet-api</artifactId>
+                <version>${servlet6.version}</version>
+            </dependency>
 
             <dependency>
-                <groupId>com.sun.activation</groupId>
-                <artifactId>jakarta.activation</artifactId>
+                <groupId>org.eclipse.angus</groupId>
+                <artifactId>angus-activation</artifactId>
                 <version>${jakarta.activation.version}</version>
             </dependency>
 
@@ -1763,7 +1768,7 @@
             </dependency>
             <dependency>
                 <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-webapp</artifactId>
+                <artifactId>jetty-security</artifactId>
                 <version>${jetty.version}</version>
             </dependency>
             <dependency>
@@ -1776,6 +1781,11 @@
                 <artifactId>jetty-alpn-conscrypt-server</artifactId>
                 <version>${jetty.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-webapp</artifactId>
+                <version>${jetty.version}</version>
+            </dependency>
 
             <dependency>
                 <groupId>org.simpleframework</groupId>
@@ -2071,13 +2081,6 @@
             </dependency>
 
             <dependency>
-                <groupId>org.mortbay.jetty</groupId>
-                <artifactId>servlet-api-2.5</artifactId>
-                <version>${jetty.servlet.api.25.version}</version>
-                <scope>test</scope>
-            </dependency>
-
-            <dependency>
                 <groupId>org.junit</groupId>
                 <artifactId>junit-bom</artifactId>
                 <version>${junit5.version}</version>
@@ -2090,6 +2093,19 @@
                 <version>${testng.version}</version>
                 <scope>test</scope>
             </dependency>
+            <dependency>
+                <groupId>org.assertj</groupId>
+                <artifactId>assertj-core</artifactId>
+                <version>3.21.0</version>
+                <scope>test</scope>
+            </dependency>
+
+            <dependency>
+                <groupId>org.awaitility</groupId>
+                <artifactId>awaitility</artifactId>
+                <version>4.1.1</version>
+                <scope>test</scope>
+            </dependency>
 
             <dependency>
                 <groupId>org.hamcrest</groupId>
@@ -2193,7 +2209,7 @@
         <findbugs.glassfish.logging.validLoggerPrefixes>
             jakarta.enterprise
         </findbugs.glassfish.logging.validLoggerPrefixes>
-        <java.version>1.8</java.version>
+        <java.version>11</java.version>
 <!--        <jersey.repackaged.prefix>jersey.repackaged</jersey.repackaged.prefix>-->
 <!--        <netbeans.hint.license>gf-cddl-gpl</netbeans.hint.license>-->
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -2294,17 +2310,12 @@
         <guava.version>31.1-jre</guava.version>
         <hamcrest.version>2.2</hamcrest.version>
         <helidon.jersey.connector.version>3.0.2</helidon.jersey.connector.version>
-        <xmlunit.version>2.9.1</xmlunit.version>
-        <hk2.osgi.version>org.glassfish.hk2.*;version="[2.5,4)"</hk2.osgi.version>
-        <hk2.jvnet.osgi.version>org.jvnet.hk2.*;version="[2.5,4)"</hk2.jvnet.osgi.version>
+        <xmlunit.version>2.9.0</xmlunit.version>
         <httpclient.version>4.5.14</httpclient.version>
         <httpclient5.version>5.2.1</httpclient5.version>
         <jackson.version>2.15.3</jackson.version>
         <javassist.version>3.29.2-GA</javassist.version>
         <jboss.logging.version>3.5.3.Final</jboss.logging.version>
-        <jboss.logging.8.version>3.4.3.Final</jboss.logging.8.version>
-        <jersey1.version>1.19.3</jersey1.version>
-        <jersey1.last.final.version>${jersey1.version}</jersey1.last.final.version>
         <jettison.version>1.3.7</jettison.version> <!-- TODO: 1.3.8 doesn't work; AbstractJsonTest complexBeanWithAttributes -->
         <jmh.version>1.37</jmh.version>
         <jmockit.version>1.49</jmockit.version>
@@ -2325,15 +2336,19 @@
         <reactive.streams.version>1.0.4</reactive.streams.version>
         <rxjava.version>1.3.8</rxjava.version>
         <rxjava2.version>2.2.21</rxjava2.version>
+
+        <servlet4.version>4.0.3</servlet4.version>
+        <servlet6.version>6.0.0</servlet6.version>
+
         <simple.version>6.0.1</simple.version>
         <slf4j.version>2.0.9</slf4j.version>
         <spring6.version>6.0.13</spring6.version>
         <testng.version>7.8.0</testng.version>
         <testng6.version>6.9.13.6</testng6.version>
         <!-- Jakartified, eligible for CQ -->
-        <weld.version>4.0.3.Final</weld.version>
+        <weld.version>5.1.1.Final</weld.version>
         <weld3.version>3.1.9.Final</weld3.version>
-        <validation.impl.version>7.0.5.Final</validation.impl.version>
+        <validation.impl.version>8.0.1.Final</validation.impl.version>
         <!-- END of Jakartified, eligible for CQ -->
         <wiremock.version>2.27.2</wiremock.version>
         <xerces.version>2.12.2</xerces.version>
@@ -2342,48 +2357,47 @@
         <graalvm.version>20.3.12</graalvm.version>
 
         <!-- do not need CQs (below this line till the end of version properties)-->
-        <gf.impl.version>6.2.5</gf.impl.version>
-        <hk2.config.version>6.2.5</hk2.config.version>
+        <gf.impl.version>7.0.6</gf.impl.version>
         <!-- Jakartified -->
-        <cdi.api.version>3.0.0</cdi.api.version> <!-- 3.0.1 contains incompatible changes
-                                                    which fails microprofile TCK -->
+        <cdi.api.version>4.0.1</cdi.api.version>
         <cdi.osgi.version>jakarta.enterprise.*;version="[3.0,5)"</cdi.osgi.version>
         <ejb.version>4.0.1</ejb.version>
-        <grizzly2.version>3.0.1</grizzly2.version>
+        <grizzly2.version>4.0.1</grizzly2.version>
         <grizzly.client.version>1.16</grizzly.client.version>
         <grizzly.npn.version>2.0.0</grizzly.npn.version>
-        <hk2.version>3.0.3</hk2.version> <!-- 3.0.4 fails osgi tests, 3.0.5 is for JDK 11+ -->
-        <jsp.version>3.0.0</jsp.version>
-        <jstl.version>2.0.0</jstl.version>
+        <hk2.version>3.0.5</hk2.version>
+        <hk2.osgi.version>org.glassfish.hk2.*;version="[3.0,4)"</hk2.osgi.version>
+        <hk2.jvnet.osgi.version>org.jvnet.hk2.*;version="[3.0,4)"</hk2.jvnet.osgi.version>
+        <hk2.config.version>7.0.3</hk2.config.version>
+        <jsp.version>3.1.1</jsp.version>
+        <jstl.version>3.0.0</jstl.version>
         <jta.api.version>2.0.1</jta.api.version>
-        <servlet5.version>5.0.0</servlet5.version>
-        <istack.commons.runtime.version>4.0.1</istack.commons.runtime.version>
-        <jakarta.activation-api.version>2.0.1</jakarta.activation-api.version>
-        <jakarta.activation.version>2.0.1</jakarta.activation.version>
-        <jakarta.el.version>4.0.0</jakarta.el.version>
-        <jakarta.el.impl.version>4.0.2</jakarta.el.impl.version>
+        <istack.commons.runtime.version>4.1.1</istack.commons.runtime.version>
+        <jakarta.activation-api.version>2.1.1</jakarta.activation-api.version>
+        <jakarta.activation.version>2.0.0</jakarta.activation.version>
+        <jakarta.el.version>5.0.1</jakarta.el.version>
+        <jakarta.el.impl.version>5.0.0-M1</jakarta.el.impl.version>
         <jakarta.annotation.osgi.version>jakarta.annotation.*;version="[2.0,3)"</jakarta.annotation.osgi.version>
-        <jakarta.annotation.version>2.0.0</jakarta.annotation.version>
+        <jakarta.annotation.version>2.1.1</jakarta.annotation.version>
         <jakarta.inject.version>2.0.1</jakarta.inject.version>
-        <jakarta.interceptor.version>2.0.1</jakarta.interceptor.version>
-        <jakarta.jsonp.version>2.0.2</jakarta.jsonp.version>
-        <jakarta.persistence.version>3.0.0</jakarta.persistence.version>
-        <jakarta.validation.api.version>3.0.2</jakarta.validation.api.version> <!--Can't be updated to 3.0.1 /OSGi incompatibility with JDK 1.8 -->
-        <jakarta.jaxb.api.version>3.0.1</jakarta.jaxb.api.version>
-        <jaxb.ri.version>3.0.2</jaxb.ri.version>
-        <jaxrs.api.spec.version>3.0</jaxrs.api.spec.version>
-        <jaxrs.api.impl.version>3.0.0</jaxrs.api.impl.version>
+        <jakarta.interceptor.version>2.1.0</jakarta.interceptor.version>
+        <jakarta.jsonp.version>2.1.2</jakarta.jsonp.version>
+        <jakarta.persistence.version>3.1.0</jakarta.persistence.version>
+        <jakarta.validation.api.version>3.0.2</jakarta.validation.api.version>
+        <jakarta.jaxb.api.version>4.0.0</jakarta.jaxb.api.version>
+        <jaxb.ri.version>4.0.2</jaxb.ri.version>
+        <jaxrs.api.spec.version>3.1</jaxrs.api.spec.version>
+        <jaxrs.api.impl.version>3.1.0</jaxrs.api.impl.version>
         <jetty.osgi.version>org.eclipse.jetty.*;version="[11,15)"</jetty.osgi.version>
-        <jetty.version>11.0.18</jetty.version>
-        <jetty.tracing.version>11.0.15</jetty.tracing.version> <!-- special version for tracing support tests-->
+        <jetty.version>12.0.3</jetty.version>
         <jetty9.version>9.4.53.v20231009</jetty9.version>
-        <jetty.plugin.version>11.0.18</jetty.plugin.version>
-        <jetty.servlet.api.25.version>6.1.14</jetty.servlet.api.25.version>
-        <jsonb.api.version>2.0.0</jsonb.api.version>
-        <jsonp.ri.version>1.0.5</jsonp.ri.version>
-        <jsonp.jaxrs.version>1.0.5</jsonp.jaxrs.version>
-        <moxy.version>3.0.4</moxy.version>
-        <yasson.version>2.0.4</yasson.version>
+        <jetty11.version>11.0.18</jetty11.version>
+        <jetty.plugin.version>12.0.3</jetty.plugin.version>
+        <jsonb.api.version>3.0.0</jsonb.api.version>
+        <jsonp.ri.version>1.1.1</jsonp.ri.version>
+        <jsonp.jaxrs.version>1.1.1</jsonp.jaxrs.version>
+        <moxy.version>4.0.2</moxy.version>
+        <yasson.version>3.0.3</yasson.version>
         <!-- END of Jakartified -->
 
         <javax.annotation.version>1.3.2</javax.annotation.version> <!--Deprecated, used only for @generated annotation in perf tests -->
diff --git a/security/oauth1-client/pom.xml b/security/oauth1-client/pom.xml
index d88b75e..ac7726c 100644
--- a/security/oauth1-client/pom.xml
+++ b/security/oauth1-client/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.security</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>oauth1-client</artifactId>
diff --git a/security/oauth1-server/pom.xml b/security/oauth1-server/pom.xml
index 86c287f..06f7d4c 100644
--- a/security/oauth1-server/pom.xml
+++ b/security/oauth1-server/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.security</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>oauth1-server</artifactId>
diff --git a/security/oauth1-signature/pom.xml b/security/oauth1-signature/pom.xml
index 0216d6d..f934001 100644
--- a/security/oauth1-signature/pom.xml
+++ b/security/oauth1-signature/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.glassfish.jersey.security</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/security/oauth2-client/pom.xml b/security/oauth2-client/pom.xml
index 801f5c7..6c9a5c1 100644
--- a/security/oauth2-client/pom.xml
+++ b/security/oauth2-client/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.glassfish.jersey.security</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/security/pom.xml b/security/pom.xml
index 79d65c7..754c37e 100644
--- a/security/pom.xml
+++ b/security/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.security</groupId>
diff --git a/test-framework/core/pom.xml b/test-framework/core/pom.xml
index 24f8361..6dae286 100644
--- a/test-framework/core/pom.xml
+++ b/test-framework/core/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-test-framework-core</artifactId>
@@ -40,7 +40,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.core</groupId>
diff --git a/test-framework/maven/container-runner-maven-plugin/pom.xml b/test-framework/maven/container-runner-maven-plugin/pom.xml
index 3cbd0d8..b4efb10 100644
--- a/test-framework/maven/container-runner-maven-plugin/pom.xml
+++ b/test-framework/maven/container-runner-maven-plugin/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework.maven</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>container-runner-maven-plugin</artifactId>
diff --git a/test-framework/maven/custom-enforcer-rules/pom.xml b/test-framework/maven/custom-enforcer-rules/pom.xml
index 53c80b6..8ae03ce 100644
--- a/test-framework/maven/custom-enforcer-rules/pom.xml
+++ b/test-framework/maven/custom-enforcer-rules/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework.maven</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>custom-enforcer-rules</artifactId>
diff --git a/test-framework/maven/pom.xml b/test-framework/maven/pom.xml
index 5d57910..5f24096 100644
--- a/test-framework/maven/pom.xml
+++ b/test-framework/maven/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.test-framework.maven</groupId>
diff --git a/test-framework/memleak-test-common/pom.xml b/test-framework/memleak-test-common/pom.xml
index fc0f67f..9b477f0 100644
--- a/test-framework/memleak-test-common/pom.xml
+++ b/test-framework/memleak-test-common/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>memleak-test-common</artifactId>
diff --git a/test-framework/pom.xml b/test-framework/pom.xml
index 926c06f..00b44f2 100644
--- a/test-framework/pom.xml
+++ b/test-framework/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.test-framework</groupId>
diff --git a/test-framework/providers/bundle/pom.xml b/test-framework/providers/bundle/pom.xml
index db774b5..7b8e332 100644
--- a/test-framework/providers/bundle/pom.xml
+++ b/test-framework/providers/bundle/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework.providers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-test-framework-provider-bundle</artifactId>
diff --git a/test-framework/providers/external/pom.xml b/test-framework/providers/external/pom.xml
index ce3211c..af69bdf 100644
--- a/test-framework/providers/external/pom.xml
+++ b/test-framework/providers/external/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework.providers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-test-framework-provider-external</artifactId>
diff --git a/test-framework/providers/grizzly2/pom.xml b/test-framework/providers/grizzly2/pom.xml
index bd3afb4..84de880 100644
--- a/test-framework/providers/grizzly2/pom.xml
+++ b/test-framework/providers/grizzly2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework.providers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
@@ -36,7 +36,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
         </dependency>
 
         <dependency>
diff --git a/test-framework/providers/inmemory/pom.xml b/test-framework/providers/inmemory/pom.xml
index 1d67869..05a4096 100644
--- a/test-framework/providers/inmemory/pom.xml
+++ b/test-framework/providers/inmemory/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework.providers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-test-framework-provider-inmemory</artifactId>
diff --git a/test-framework/providers/jdk-http/pom.xml b/test-framework/providers/jdk-http/pom.xml
index 1a9b19e..d2d34db 100644
--- a/test-framework/providers/jdk-http/pom.xml
+++ b/test-framework/providers/jdk-http/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework.providers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-test-framework-provider-jdk-http</artifactId>
diff --git a/test-framework/providers/jetty-http2/pom.xml b/test-framework/providers/jetty-http2/pom.xml
deleted file mode 100644
index 7dddf54..0000000
--- a/test-framework/providers/jetty-http2/pom.xml
+++ /dev/null
@@ -1,191 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
-
-    This program and the accompanying materials are made available under the
-    terms of the Eclipse Public License v. 2.0, which is available at
-    http://www.eclipse.org/legal/epl-2.0.
-
-    This Source Code may also be made available under the following Secondary
-    Licenses when the conditions for such availability set forth in the
-    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
-    version 2 with the GNU Classpath Exception, which is available at
-    https://www.gnu.org/software/classpath/license.html.
-
-    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
-
--->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>project</artifactId>
-        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
-        <version>3.0.99-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>jersey-test-framework-provider-jetty-http2</artifactId>
-    <packaging>jar</packaging>
-    <name>jersey-test-framework-provider-jetty-http2</name>
-
-    <description>Jersey Test Framework - Jetty HTTP2 container</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.glassfish.jersey.test-framework</groupId>
-            <artifactId>jersey-test-framework-core</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.glassfish.jersey.containers</groupId>
-            <artifactId>jersey-container-jetty-http2</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-    </dependencies>
-
-    <properties>
-        <java8.build.outputDirectory>${project.basedir}/target</java8.build.outputDirectory>
-        <java8.sourceDirectory>${project.basedir}/src/main/java8</java8.sourceDirectory>
-        <java11.build.outputDirectory>${project.basedir}/target11</java11.build.outputDirectory>
-        <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
-    </properties>
-
-    <profiles>
-        <profile>
-            <id>JettyExclude</id>
-            <activation>
-                <jdk>1.8</jdk>
-            </activation>
-            <build>
-                <directory>${java8.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java8.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <configuration>
-                            <testExcludes>
-                                <testExclude>org/glassfish/jersey/test/jetty/http2/*.java</testExclude>
-                            </testExcludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>Jetty11</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <build>
-                <directory>${java11.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java11.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>copyJDK11FilesToMultiReleaseJar</id>
-            <activation>
-                <file>
-                    <!-- ${java11.build.outputDirectory} does not work here -->
-                    <exists>target11/classes/org/glassfish/jersey/test/jetty/JettyHttp2TestContainerFactory.class</exists>
-                </file>
-                <jdk>1.8</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.felix</groupId>
-                        <artifactId>maven-bundle-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <extensions>true</extensions>
-                        <configuration>
-                            <instructions>
-                                <Multi-Release>true</Multi-Release>
-                            </instructions>
-                        </configuration>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-resources-plugin</artifactId>
-                        <inherited>true</inherited>
-                        <executions>
-                            <execution>
-                                <id>copy-jdk11-classes</id>
-                                <phase>prepare-package</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${java8.build.outputDirectory}/classes/META-INF/versions/11</outputDirectory>
-                                    <resources>
-                                        <resource>
-                                            <directory>${java11.build.outputDirectory}/classes</directory>
-                                        </resource>
-                                    </resources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-antrun-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <id>copy-jdk11-sources</id>
-                                <phase>package</phase>
-                                <configuration>
-                                    <target>
-                                        <property name="sources-jar" value="${java8.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
-                                        <echo>sources-jar: ${sources-jar}</echo>
-                                        <zip destfile="${sources-jar}" update="true">
-                                            <zipfileset dir="${java11.sourceDirectory}" prefix="META-INF/versions/11"/>
-                                        </zip>
-                                    </target>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-
-</project>
diff --git a/test-framework/providers/jetty-http2/src/main/java8/org/glassfish/jersey/test/jetty/http2/JettyHttp2TestContainerFactory.java b/test-framework/providers/jetty-http2/src/main/java8/org/glassfish/jersey/test/jetty/http2/JettyHttp2TestContainerFactory.java
deleted file mode 100644
index 44fa02a..0000000
--- a/test-framework/providers/jetty-http2/src/main/java8/org/glassfish/jersey/test/jetty/http2/JettyHttp2TestContainerFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.test.jetty.http2;
-
-import jakarta.ws.rs.ProcessingException;
-import org.glassfish.jersey.jetty.http2.LocalizationMessages;
-import org.glassfish.jersey.test.DeploymentContext;
-import org.glassfish.jersey.test.spi.TestContainer;
-import org.glassfish.jersey.test.spi.TestContainerFactory;
-
-import java.net.URI;
-/**
- * Factory for testing {@link JettyHttp2ContainerFactory}.
- *
- */
-public final class JettyHttp2TestContainerFactory implements TestContainerFactory {
-
-    @Override
-    public TestContainer create(final URI baseUri, final DeploymentContext context) throws IllegalArgumentException {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-}
diff --git a/test-framework/providers/jetty-http2/src/main/resources/META-INF/services/org.glassfish.jersey.test.spi.TestContainerFactory b/test-framework/providers/jetty-http2/src/main/resources/META-INF/services/org.glassfish.jersey.test.spi.TestContainerFactory
deleted file mode 100644
index 42b7847..0000000
--- a/test-framework/providers/jetty-http2/src/main/resources/META-INF/services/org.glassfish.jersey.test.spi.TestContainerFactory
+++ /dev/null
@@ -1 +0,0 @@
-org.glassfish.jersey.test.jetty.http2.JettyHttp2TestContainerFactory
\ No newline at end of file
diff --git a/test-framework/providers/jetty/pom.xml b/test-framework/providers/jetty/pom.xml
index 968e499..ea1bb3a 100644
--- a/test-framework/providers/jetty/pom.xml
+++ b/test-framework/providers/jetty/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.test-framework.providers</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -42,58 +42,29 @@
             <artifactId>jersey-container-jetty-http</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>${slf4j.version}</version>
+        </dependency>
     </dependencies>
 
     <properties>
-        <java8.build.outputDirectory>${project.basedir}/target</java8.build.outputDirectory>
-        <java8.sourceDirectory>${project.basedir}/src/main/java8</java8.sourceDirectory>
-        <java11.build.outputDirectory>${project.basedir}/target11</java11.build.outputDirectory>
+        <java11.build.outputDirectory>${project.basedir}/target</java11.build.outputDirectory>
         <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
+        <java17.build.outputDirectory>${project.basedir}/target17</java17.build.outputDirectory>
+        <java17.sourceDirectory>${project.basedir}/src/main/java17</java17.sourceDirectory>
     </properties>
 
     <profiles>
         <profile>
             <id>JettyExclude</id>
             <activation>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
-            <build>
-                <directory>${java8.build.outputDirectory}</directory>
-                <plugins>
-                    <plugin>
-                        <groupId>org.codehaus.mojo</groupId>
-                        <artifactId>build-helper-maven-plugin</artifactId>
-                        <executions>
-                            <execution>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>add-source</goal>
-                                </goals>
-                                <configuration>
-                                    <sources>
-                                        <source>${java8.sourceDirectory}</source>
-                                    </sources>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <configuration>
-                            <testExcludes>
-                                <testExclude>org/glassfish/jersey/test/jetty/*.java</testExclude>
-                            </testExcludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>Jetty11</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
+            <properties>
+                <jetty.version>${jetty11.version}</jetty.version>
+            </properties>
             <build>
                 <directory>${java11.build.outputDirectory}</directory>
                 <plugins>
@@ -114,17 +85,54 @@
                             </execution>
                         </executions>
                     </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <configuration>
+                            <testExcludes>
+                                <testExclude>org/glassfish/jersey/test/jetty/*.java</testExclude>
+                            </testExcludes>
+                        </configuration>
+                    </plugin>
                 </plugins>
             </build>
         </profile>
         <profile>
-            <id>copyJDK11FilesToMultiReleaseJar</id>
+            <id>Jetty17</id>
+            <activation>
+                <jdk>[17,)</jdk>
+            </activation>
+            <build>
+                <directory>${java17.build.outputDirectory}</directory>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>add-source</goal>
+                                </goals>
+                                <configuration>
+                                    <sources>
+                                        <source>${java17.sourceDirectory}</source>
+                                    </sources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>copyJDK17FilesToMultiReleaseJar</id>
             <activation>
                 <file>
                     <!-- ${java11.build.outputDirectory} does not work here -->
-                    <exists>target11/classes/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.class</exists>
+                    <exists>target17/classes/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.class</exists>
                 </file>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <build>
                 <plugins>
@@ -145,16 +153,16 @@
                         <inherited>true</inherited>
                         <executions>
                             <execution>
-                                <id>copy-jdk11-classes</id>
+                                <id>copy-jdk17-classes</id>
                                 <phase>prepare-package</phase>
                                 <goals>
                                     <goal>copy-resources</goal>
                                 </goals>
                                 <configuration>
-                                    <outputDirectory>${java8.build.outputDirectory}/classes/META-INF/versions/11</outputDirectory>
+                                    <outputDirectory>${java11.build.outputDirectory}/classes/META-INF/versions/17</outputDirectory>
                                     <resources>
                                         <resource>
-                                            <directory>${java11.build.outputDirectory}/classes</directory>
+                                            <directory>${java17.build.outputDirectory}/classes</directory>
                                         </resource>
                                     </resources>
                                 </configuration>
@@ -166,14 +174,14 @@
                         <artifactId>maven-antrun-plugin</artifactId>
                         <executions>
                             <execution>
-                                <id>copy-jdk11-sources</id>
+                                <id>copy-jdk17-sources</id>
                                 <phase>package</phase>
                                 <configuration>
                                     <target>
-                                        <property name="sources-jar" value="${java8.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+                                        <property name="sources-jar" value="${java11.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
                                         <echo>sources-jar: ${sources-jar}</echo>
                                         <zip destfile="${sources-jar}" update="true">
-                                            <zipfileset dir="${java11.sourceDirectory}" prefix="META-INF/versions/11"/>
+                                            <zipfileset dir="${java17.sourceDirectory}" prefix="META-INF/versions/17"/>
                                         </zip>
                                     </target>
                                 </configuration>
diff --git a/test-framework/providers/jetty/src/main/java11/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java b/test-framework/providers/jetty/src/main/java11/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
index e5dba36..1632869 100644
--- a/test-framework/providers/jetty/src/main/java11/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
+++ b/test-framework/providers/jetty/src/main/java11/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,113 +16,18 @@
 
 package org.glassfish.jersey.test.jetty;
 
-import java.net.URI;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import jakarta.ws.rs.core.UriBuilder;
-
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.jetty.JettyHttpContainerFactory;
+import jakarta.ws.rs.ProcessingException;
+import org.glassfish.jersey.jetty.internal.LocalizationMessages;
 import org.glassfish.jersey.test.DeploymentContext;
 import org.glassfish.jersey.test.spi.TestContainer;
-import org.glassfish.jersey.test.spi.TestContainerException;
 import org.glassfish.jersey.test.spi.TestContainerFactory;
-import org.glassfish.jersey.test.spi.TestHelper;
 
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
+import java.net.URI;
 
-/**
- * Factory for testing {@link org.glassfish.jersey.jetty.JettyHttpContainer}.
- *
- * @author Arul Dhesiaseelan (aruld@acm.org)
- * @author Marek Potociar
- */
 public class JettyTestContainerFactory implements TestContainerFactory {
 
-    private static class JettyTestContainer implements TestContainer {
-
-        private static final Logger LOGGER = Logger.getLogger(JettyTestContainer.class.getName());
-
-        private URI baseUri;
-        private final Server server;
-
-        private JettyTestContainer(final URI baseUri, final DeploymentContext context) {
-            final URI base = UriBuilder.fromUri(baseUri).path(context.getContextPath()).build();
-
-            if (!"/".equals(base.getRawPath())) {
-                throw new TestContainerException(String.format(
-                        "Cannot deploy on %s. Jetty HTTP container only supports deployment on root path.",
-                        base.getRawPath()));
-            }
-
-            this.baseUri = base;
-
-            if (LOGGER.isLoggable(Level.INFO)) {
-                LOGGER.info("Creating JettyTestContainer configured at the base URI "
-                        + TestHelper.zeroPortToAvailablePort(baseUri));
-            }
-
-            this.server = JettyHttpContainerFactory.createServer(this.baseUri, context.getResourceConfig(), false);
-        }
-
-        @Override
-        public ClientConfig getClientConfig() {
-            return null;
-        }
-
-        @Override
-        public URI getBaseUri() {
-            return baseUri;
-        }
-
-        @Override
-        public void start() {
-            if (server.isStarted()) {
-                LOGGER.log(Level.WARNING, "Ignoring start request - JettyTestContainer is already started.");
-            } else {
-                LOGGER.log(Level.FINE, "Starting JettyTestContainer...");
-                try {
-                    server.start();
-
-                    if (baseUri.getPort() == 0) {
-                        int port = 0;
-                        for (final Connector connector : server.getConnectors()) {
-                            if (connector instanceof ServerConnector) {
-                                port = ((ServerConnector) connector).getLocalPort();
-                                break;
-                            }
-                        }
-
-                        baseUri = UriBuilder.fromUri(baseUri).port(port).build();
-
-                        LOGGER.log(Level.INFO, "Started JettyTestContainer at the base URI " + baseUri);
-                    }
-                } catch (Exception e) {
-                    throw new TestContainerException(e);
-                }
-            }
-        }
-
-        @Override
-        public void stop() {
-            if (server.isStarted()) {
-                LOGGER.log(Level.FINE, "Stopping JettyTestContainer...");
-                try {
-                    this.server.stop();
-                } catch (Exception ex) {
-                    LOGGER.log(Level.WARNING, "Error Stopping JettyTestContainer...", ex);
-                }
-            } else {
-                LOGGER.log(Level.WARNING, "Ignoring stop request - JettyTestContainer is already stopped.");
-            }
-        }
-    }
-
     @Override
     public TestContainer create(final URI baseUri, final DeploymentContext context) throws IllegalArgumentException {
-        return new JettyTestContainer(baseUri, context);
+        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
     }
 }
diff --git a/test-framework/providers/jetty-http2/src/main/java11/org/glassfish/jersey/test/jetty/http2/JettyHttp2TestContainerFactory.java b/test-framework/providers/jetty/src/main/java17/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
similarity index 71%
copy from test-framework/providers/jetty-http2/src/main/java11/org/glassfish/jersey/test/jetty/http2/JettyHttp2TestContainerFactory.java
copy to test-framework/providers/jetty/src/main/java17/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
index e63f057..de1ba2c 100644
--- a/test-framework/providers/jetty-http2/src/main/java11/org/glassfish/jersey/test/jetty/http2/JettyHttp2TestContainerFactory.java
+++ b/test-framework/providers/jetty/src/main/java17/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.test.jetty.http2;
+package org.glassfish.jersey.test.jetty;
 
 import java.net.URI;
 import java.util.logging.Level;
@@ -23,7 +23,7 @@
 import jakarta.ws.rs.core.UriBuilder;
 
 import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.jetty.http2.JettyHttp2ContainerFactory;
+import org.glassfish.jersey.jetty.JettyHttpContainerFactory;
 import org.glassfish.jersey.test.DeploymentContext;
 import org.glassfish.jersey.test.spi.TestContainer;
 import org.glassfish.jersey.test.spi.TestContainerException;
@@ -35,35 +35,37 @@
 import org.eclipse.jetty.server.ServerConnector;
 
 /**
- * Factory for testing {@link JettyHttp2ContainerFactory}.
+ * Factory for testing {@link org.glassfish.jersey.jetty.JettyHttpContainer}.
  *
+ * @author Arul Dhesiaseelan (aruld@acm.org)
+ * @author Marek Potociar
  */
-public final class JettyHttp2TestContainerFactory implements TestContainerFactory {
+public class JettyTestContainerFactory implements TestContainerFactory {
 
-    private static class JettyHttp2TestContainer implements TestContainer {
+    private static class JettyTestContainer implements TestContainer {
 
-        private static final Logger LOGGER = Logger.getLogger(JettyHttp2TestContainer.class.getName());
+        private static final Logger LOGGER = Logger.getLogger(JettyTestContainer.class.getName());
 
         private URI baseUri;
         private final Server server;
 
-        private JettyHttp2TestContainer(final URI baseUri, final DeploymentContext context) {
+        private JettyTestContainer(final URI baseUri, final DeploymentContext context) {
             final URI base = UriBuilder.fromUri(baseUri).path(context.getContextPath()).build();
 
             if (!"/".equals(base.getRawPath())) {
                 throw new TestContainerException(String.format(
-                        "Cannot deploy on %s. Jetty HTTP2 container only supports deployment on root path.",
+                        "Cannot deploy on %s. Jetty HTTP container only supports deployment on root path.",
                         base.getRawPath()));
             }
 
             this.baseUri = base;
 
             if (LOGGER.isLoggable(Level.INFO)) {
-                LOGGER.info("Creating JettyHttp2TestContainer configured at the base URI "
+                LOGGER.info("Creating JettyTestContainer configured at the base URI "
                         + TestHelper.zeroPortToAvailablePort(baseUri));
             }
 
-            this.server = JettyHttp2ContainerFactory.createHttp2Server(this.baseUri, context.getResourceConfig(), false);
+            this.server = JettyHttpContainerFactory.createServer(this.baseUri, context.getResourceConfig(), false);
         }
 
         @Override
@@ -79,9 +81,9 @@
         @Override
         public void start() {
             if (server.isStarted()) {
-                LOGGER.log(Level.WARNING, "Ignoring start request - JettyHttp2TestContainer is already started.");
+                LOGGER.log(Level.WARNING, "Ignoring start request - JettyTestContainer is already started.");
             } else {
-                LOGGER.log(Level.FINE, "Starting JettyHttp2TestContainer...");
+                LOGGER.log(Level.FINE, "Starting JettyTestContainer...");
                 try {
                     server.start();
 
@@ -96,7 +98,7 @@
 
                         baseUri = UriBuilder.fromUri(baseUri).port(port).build();
 
-                        LOGGER.log(Level.INFO, "Started JettyHttp2TestContainer at the base URI " + baseUri);
+                        LOGGER.log(Level.INFO, "Started JettyTestContainer at the base URI " + baseUri);
                     }
                 } catch (Exception e) {
                     throw new TestContainerException(e);
@@ -107,20 +109,20 @@
         @Override
         public void stop() {
             if (server.isStarted()) {
-                LOGGER.log(Level.FINE, "Stopping JettyHttp2TestContainer...");
+                LOGGER.log(Level.FINE, "Stopping JettyTestContainer...");
                 try {
                     this.server.stop();
                 } catch (Exception ex) {
-                    LOGGER.log(Level.WARNING, "Error Stopping JettyHttp2TestContainer...", ex);
+                    LOGGER.log(Level.WARNING, "Error Stopping JettyTestContainer...", ex);
                 }
             } else {
-                LOGGER.log(Level.WARNING, "Ignoring stop request - JettyHttp2TestContainer is already stopped.");
+                LOGGER.log(Level.WARNING, "Ignoring stop request - JettyTestContainer is already stopped.");
             }
         }
     }
 
     @Override
     public TestContainer create(final URI baseUri, final DeploymentContext context) throws IllegalArgumentException {
-        return new JettyHttp2TestContainer(baseUri, context);
+        return new JettyTestContainer(baseUri, context);
     }
 }
diff --git a/test-framework/providers/jetty/src/main/java8/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java b/test-framework/providers/jetty/src/main/java8/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
deleted file mode 100644
index cd2e332..0000000
--- a/test-framework/providers/jetty/src/main/java8/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.test.jetty;
-
-import jakarta.ws.rs.ProcessingException;
-import org.glassfish.jersey.jetty.internal.LocalizationMessages;
-import org.glassfish.jersey.test.DeploymentContext;
-import org.glassfish.jersey.test.spi.TestContainer;
-import org.glassfish.jersey.test.spi.TestContainerFactory;
-
-import java.net.URI;
-
-/**
- * Jetty test factory stub for JDK 1.8 only
- *
- * since Jetty 11+ does not support JDKs below 11
- */
-public class JettyTestContainerFactory implements TestContainerFactory {
-
-    @Override
-    public TestContainer create(final URI baseUri, final DeploymentContext context) throws IllegalArgumentException {
-        throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
-    }
-}
diff --git a/test-framework/providers/jetty/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties b/test-framework/providers/jetty/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
index c362bf0..6504f0e 100644
--- a/test-framework/providers/jetty/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
+++ b/test-framework/providers/jetty/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2020, 2023 Oracle and/or its affiliates. All rights reserved.
 #
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,4 +15,4 @@
 #
 
 # {0} - status code; {1} - status reason message
-not.supported=Jetty container is not supported on JDK version less than 11.
+not.supported=Jetty container is not supported on JDK version less than 17.
diff --git a/test-framework/providers/jetty11-http2/pom.xml b/test-framework/providers/jetty11-http2/pom.xml
new file mode 100644
index 0000000..4cf3f49
--- /dev/null
+++ b/test-framework/providers/jetty11-http2/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>project</artifactId>
+        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+        <version>3.1.99-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>jersey-test-framework-provider-jetty11-http2</artifactId>
+    <packaging>jar</packaging>
+    <name>jersey-test-framework-provider-jetty11-http2</name>
+
+    <description>Jersey Test Framework - Jetty HTTP2 container</description>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-util</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty.http2</groupId>
+                <artifactId>http2-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-alpn-conscrypt-server</artifactId>
+                <version>${jetty11.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework</groupId>
+            <artifactId>jersey-test-framework-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-jetty11-http2</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>http2-server</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/test-framework/providers/jetty-http2/src/main/java11/org/glassfish/jersey/test/jetty/http2/JettyHttp2TestContainerFactory.java b/test-framework/providers/jetty11-http2/src/main/java/org/glassfish/jersey/test/jetty11/http2/Jetty11Http2TestContainerFactory.java
similarity index 91%
rename from test-framework/providers/jetty-http2/src/main/java11/org/glassfish/jersey/test/jetty/http2/JettyHttp2TestContainerFactory.java
rename to test-framework/providers/jetty11-http2/src/main/java/org/glassfish/jersey/test/jetty11/http2/Jetty11Http2TestContainerFactory.java
index e63f057..9b347f9 100644
--- a/test-framework/providers/jetty-http2/src/main/java11/org/glassfish/jersey/test/jetty/http2/JettyHttp2TestContainerFactory.java
+++ b/test-framework/providers/jetty11-http2/src/main/java/org/glassfish/jersey/test/jetty11/http2/Jetty11Http2TestContainerFactory.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.test.jetty.http2;
+package org.glassfish.jersey.test.jetty11.http2;
 
 import java.net.URI;
 import java.util.logging.Level;
@@ -23,7 +23,7 @@
 import jakarta.ws.rs.core.UriBuilder;
 
 import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.jetty.http2.JettyHttp2ContainerFactory;
+import org.glassfish.jersey.jetty11.http2.Jetty11Http2ContainerFactory;
 import org.glassfish.jersey.test.DeploymentContext;
 import org.glassfish.jersey.test.spi.TestContainer;
 import org.glassfish.jersey.test.spi.TestContainerException;
@@ -35,10 +35,10 @@
 import org.eclipse.jetty.server.ServerConnector;
 
 /**
- * Factory for testing {@link JettyHttp2ContainerFactory}.
+ * Factory for testing {@link Jetty11Http2ContainerFactory}.
  *
  */
-public final class JettyHttp2TestContainerFactory implements TestContainerFactory {
+public final class Jetty11Http2TestContainerFactory implements TestContainerFactory {
 
     private static class JettyHttp2TestContainer implements TestContainer {
 
@@ -63,7 +63,7 @@
                         + TestHelper.zeroPortToAvailablePort(baseUri));
             }
 
-            this.server = JettyHttp2ContainerFactory.createHttp2Server(this.baseUri, context.getResourceConfig(), false);
+            this.server = Jetty11Http2ContainerFactory.createHttp2Server(this.baseUri, context.getResourceConfig(), false);
         }
 
         @Override
diff --git a/test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java b/test-framework/providers/jetty11-http2/src/main/java/org/glassfish/jersey/test/jetty11/http2/package-info.java
similarity index 86%
rename from test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java
rename to test-framework/providers/jetty11-http2/src/main/java/org/glassfish/jersey/test/jetty11/http2/package-info.java
index cd4980f..0fdbe9d 100644
--- a/test-framework/providers/jetty-http2/src/main/java/org/glassfish/jersey/test/jetty/http2/package-info.java
+++ b/test-framework/providers/jetty11-http2/src/main/java/org/glassfish/jersey/test/jetty11/http2/package-info.java
@@ -15,6 +15,6 @@
  */
 
 /**
- * Jersey test framework for Jetty HTTP/2 Container.
+ * Jersey test framework for Jetty 11 HTTP/2 Container.
  */
-package org.glassfish.jersey.test.jetty.http2;
+package org.glassfish.jersey.test.jetty11.http2;
diff --git a/test-framework/providers/jetty11-http2/src/main/resources/META-INF/services/org.glassfish.jersey.test.spi.TestContainerFactory b/test-framework/providers/jetty11-http2/src/main/resources/META-INF/services/org.glassfish.jersey.test.spi.TestContainerFactory
new file mode 100644
index 0000000..0edcf72
--- /dev/null
+++ b/test-framework/providers/jetty11-http2/src/main/resources/META-INF/services/org.glassfish.jersey.test.spi.TestContainerFactory
@@ -0,0 +1 @@
+org.glassfish.jersey.test.jetty11.http2.Jetty11Http2TestContainerFactory
diff --git a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties b/test-framework/providers/jetty11-http2/src/main/resources/org/glassfish/jersey/test/jetty11/http2/localization.properties
similarity index 98%
rename from test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
rename to test-framework/providers/jetty11-http2/src/main/resources/org/glassfish/jersey/test/jetty11/http2/localization.properties
index 2886c72..f10b03c 100644
--- a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
+++ b/test-framework/providers/jetty11-http2/src/main/resources/org/glassfish/jersey/test/jetty11/http2/localization.properties
@@ -15,4 +15,4 @@
 #
 
 # {0} - status code; {1} - status reason message
-not.supported=Jetty container is not supported on JDK version less than 11.
+not.supported=Jetty container is not supported on JDK version less than 17.
diff --git a/test-framework/providers/jetty-http2/src/test/java/org/glassfish/jersey/test/jetty/http2/AvailablePortJettyTest.java b/test-framework/providers/jetty11-http2/src/test/java/org/glassfish/jersey/test/jetty11/http2/AvailablePortJetty11Test.java
similarity index 88%
rename from test-framework/providers/jetty-http2/src/test/java/org/glassfish/jersey/test/jetty/http2/AvailablePortJettyTest.java
rename to test-framework/providers/jetty11-http2/src/test/java/org/glassfish/jersey/test/jetty11/http2/AvailablePortJetty11Test.java
index 1964156..ac93ccb 100644
--- a/test-framework/providers/jetty-http2/src/test/java/org/glassfish/jersey/test/jetty/http2/AvailablePortJettyTest.java
+++ b/test-framework/providers/jetty11-http2/src/test/java/org/glassfish/jersey/test/jetty11/http2/AvailablePortJetty11Test.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.test.jetty.http2;
+package org.glassfish.jersey.test.jetty11.http2;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
@@ -23,7 +23,6 @@
 import org.glassfish.jersey.test.DeploymentContext;
 import org.glassfish.jersey.test.JerseyTest;
 import org.glassfish.jersey.test.TestProperties;
-import org.glassfish.jersey.test.jetty.http2.JettyHttp2TestContainerFactory;
 import org.glassfish.jersey.test.spi.TestContainerFactory;
 
 import org.junit.jupiter.api.Test;
@@ -35,11 +34,11 @@
  * Tests finding an available port for container.
  *
  */
-public class AvailablePortJettyTest extends JerseyTest {
+public class AvailablePortJetty11Test extends JerseyTest {
 
     @Override
     protected TestContainerFactory getTestContainerFactory() {
-        return new JettyHttp2TestContainerFactory();
+        return new Jetty11Http2TestContainerFactory();
     }
 
     @Path("AvailablePortJettyTest")
diff --git a/test-framework/providers/jetty-http2/src/test/java/org/glassfish/jersey/test/jetty/http2/JettyContainerTest.java b/test-framework/providers/jetty11-http2/src/test/java/org/glassfish/jersey/test/jetty11/http2/Jetty11ContainerTest.java
similarity index 83%
rename from test-framework/providers/jetty-http2/src/test/java/org/glassfish/jersey/test/jetty/http2/JettyContainerTest.java
rename to test-framework/providers/jetty11-http2/src/test/java/org/glassfish/jersey/test/jetty11/http2/Jetty11ContainerTest.java
index f96c10c..1ce10d0 100644
--- a/test-framework/providers/jetty-http2/src/test/java/org/glassfish/jersey/test/jetty/http2/JettyContainerTest.java
+++ b/test-framework/providers/jetty11-http2/src/test/java/org/glassfish/jersey/test/jetty11/http2/Jetty11ContainerTest.java
@@ -14,7 +14,7 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.test.jetty.http2;
+package org.glassfish.jersey.test.jetty11.http2;
 
 import java.net.URI;
 import java.util.List;
@@ -26,8 +26,8 @@
 import org.glassfish.jersey.inject.hk2.DelayedHk2InjectionManager;
 import org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager;
 import org.glassfish.jersey.internal.inject.InjectionManager;
-import org.glassfish.jersey.jetty.http2.JettyHttp2ContainerFactory;
-import org.glassfish.jersey.jetty.JettyHttpContainer;
+import org.glassfish.jersey.jetty11.http2.Jetty11Http2ContainerFactory;
+import org.glassfish.jersey.jetty11.Jetty11HttpContainer;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 
@@ -41,16 +41,16 @@
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
- * Test class for {@link JettyHttpContainer}.
+ * Test class for {@link Jetty11HttpContainer}.
  *
  */
-public class JettyContainerTest extends JerseyTest {
+public class Jetty11ContainerTest extends JerseyTest {
 
     /**
      * Creates new instance.
      */
-    public JettyContainerTest() {
-        super(new JettyHttp2TestContainerFactory());
+    public Jetty11ContainerTest() {
+        super(new Jetty11Http2TestContainerFactory());
     }
 
     @Override
@@ -92,9 +92,9 @@
     @Test
     public void testParentServiceLocator() {
         final ServiceLocator locator = new ServiceLocatorImpl("MyServiceLocator", null);
-        final Server server = JettyHttp2ContainerFactory.createHttp2Server(URI.create("http://localhost:9876"),
+        final Server server = Jetty11Http2ContainerFactory.createHttp2Server(URI.create("http://localhost:9876"),
                 new ResourceConfig(Resource.class), false, locator);
-        final JettyHttpContainer container = (JettyHttpContainer) server.getHandler();
+        final Jetty11HttpContainer container = (Jetty11HttpContainer) server.getHandler();
         final InjectionManager injectionManager = container.getApplicationHandler().getInjectionManager();
 
         ServiceLocator serviceLocator;
@@ -111,7 +111,7 @@
     @Test
     public void testHttp2Container() {
         final ServiceLocator locator = new ServiceLocatorImpl("MyServiceLocator", null);
-        final Server server = JettyHttp2ContainerFactory.createHttp2Server(URI.create("http://localhost:9876"),
+        final Server server = Jetty11Http2ContainerFactory.createHttp2Server(URI.create("http://localhost:9876"),
                 new ResourceConfig(Resource.class), true, locator);
         final List<String> protocols = server.getConnectors()[0].getProtocols();
         assertTrue(protocols.contains("h2") || protocols.contains("h2c"));
diff --git a/test-framework/providers/netty/pom.xml b/test-framework/providers/netty/pom.xml
index a20773f..d660c25 100644
--- a/test-framework/providers/netty/pom.xml
+++ b/test-framework/providers/netty/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework.providers</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-test-framework-provider-netty</artifactId>
diff --git a/test-framework/providers/pom.xml b/test-framework/providers/pom.xml
index 258ae06..06d2d7a 100644
--- a/test-framework/providers/pom.xml
+++ b/test-framework/providers/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.test-framework.providers</groupId>
@@ -40,7 +40,7 @@
         <module>inmemory</module>
         <module>jdk-http</module>
         <module>jetty</module>
-        <module>jetty-http2</module>
+        <module>jetty11-http2</module>
         <module>netty</module>
         <module>simple</module>
     </modules>
diff --git a/test-framework/providers/simple/pom.xml b/test-framework/providers/simple/pom.xml
index d6b1d92..69d981c 100644
--- a/test-framework/providers/simple/pom.xml
+++ b/test-framework/providers/simple/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.test-framework.providers</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/test-framework/util/pom.xml b/test-framework/util/pom.xml
index 28b1d60..cd8a3db 100644
--- a/test-framework/util/pom.xml
+++ b/test-framework/util/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.test-framework</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-test-framework-util</artifactId>
diff --git a/tests/e2e-client/pom.xml b/tests/e2e-client/pom.xml
index 47d0276..006c84b 100644
--- a/tests/e2e-client/pom.xml
+++ b/tests/e2e-client/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e-client</artifactId>
@@ -148,6 +148,11 @@
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.connectors</groupId>
+            <artifactId>jersey-jnh-connector</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.connectors</groupId>
             <artifactId>jersey-jdk-connector</artifactId>
             <scope>test</scope>
         </dependency>
@@ -224,7 +229,7 @@
         <profile>
             <id>JettyTestExclude</id>
             <activation>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <build>
                 <plugins>
@@ -251,16 +256,6 @@
             </build>
         </profile>
         <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <properties>
-                <!-- https://bugs.openjdk.java.net/browse/JDK-8211426 -->
-                <surefire.security.argline>-Djdk.tls.server.protocols=TLSv1.2</surefire.security.argline>
-            </properties>
-        </profile>
-        <profile>
             <id>xdk</id>
             <properties>
                 <!-- do not use security manager for xdk -->
@@ -287,4 +282,9 @@
         </profile>
     </profiles>
 
+    <properties>
+        <!-- https://bugs.openjdk.java.net/browse/JDK-8211426 -->
+        <surefire.security.argline>-Djdk.tls.server.protocols=TLSv1.2</surefire.security.argline>
+    </properties>
+
 </project>
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java
index 051be02..3bbc161 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -42,6 +42,7 @@
 import org.glassfish.jersey.internal.util.JdkVersion;
 import org.glassfish.jersey.jdk.connector.JdkConnectorProvider;
 import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
+import org.glassfish.jersey.jnh.connector.JavaNetHttpConnectorProvider;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.netty.connector.NettyConnectorProvider;
 import org.glassfish.jersey.server.ResourceConfig;
@@ -62,16 +63,18 @@
     private static final Logger LOGGER = Logger.getLogger(RequestHeaderModificationsTest.class.getName());
 
     public static List<ConnectorProvider> testData() {
-        int size = JdkVersion.getJdkVersion().getMajor() < 11 ? 5 : 6;
+        int size = JdkVersion.getJdkVersion().getMajor() < 17 ? 6 : 7;
         final ConnectorProvider[] providers = new ConnectorProvider[size];
         providers[0] = new JdkConnectorProvider();
         providers[1] = new GrizzlyConnectorProvider();
         providers[2] = new ApacheConnectorProvider();
         providers[3] = new Apache5ConnectorProvider();
         providers[4] = new NettyConnectorProvider();
-        if (size == 6) {
-            providers[5] = new JettyConnectorProvider();
+        providers[5] = new JavaNetHttpConnectorProvider();
+        if (size == 7) {
+            providers[6] = new JettyConnectorProvider();
         }
+
         return Arrays.asList(providers);
     }
 
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/MultiPartTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/MultiPartTest.java
index 3cb45b9..c0e7c49 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/MultiPartTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/MultiPartTest.java
@@ -52,21 +52,22 @@
 import java.util.Collection;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import java.util.stream.Stream;
 
 public class MultiPartTest {
 
     private static final Logger LOGGER = Logger.getLogger(RequestHeaderModificationsTest.class.getName());
 
     public static ConnectorProvider[] testData() {
-        int size = JdkVersion.getJdkVersion().getMajor() < 11 ? 3 : 4;
+        int size = /*JdkVersion.getJdkVersion().getMajor() < 17 ? */3 /*: 4*/;
         final ConnectorProvider[] providers = new ConnectorProvider[size];
         providers[0] = new HttpUrlConnectorProvider();
         providers[1] = new NettyConnectorProvider();
         providers[2] = new JdkConnectorProvider();
-        if (size == 4) {
+        /*if (size == 4) { //It's Jetty11ConnectorProvider in the 3.1,
+                           //and we can not test it here due to incompatibility
+                           //of Jetty 12 and Jetty 11
             providers[3] = new JettyConnectorProvider();
-        }
+        }*/
         return providers;
     }
 
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java
index 4e1b89e..4246421 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java
@@ -59,9 +59,10 @@
 import org.glassfish.jersey.client.HttpUrlConnectorProvider;
 import org.glassfish.jersey.client.spi.ConnectorProvider;
 import org.glassfish.jersey.internal.util.JdkVersion;
+import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
+import org.glassfish.jersey.jnh.connector.JavaNetHttpConnectorProvider;
 import org.glassfish.jersey.logging.LoggingFeature;
 import org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider;
-import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.glassfish.jersey.test.TestProperties;
@@ -107,11 +108,13 @@
                 {new JettyConnectorProvider(), true, false, false, false}, // change to true when JERSEY-2341 fixed
                 {new ApacheConnectorProvider(), false, false, false, false}, // change to true when JERSEY-2341 fixed
                 {new Apache5ConnectorProvider(), false, false, false, false}, // change to true when JERSEY-2341 fixed
+                {new JavaNetHttpConnectorProvider(), true, true, false, false},
                 {new HttpUrlConnectorProvider(), true, true, true, true},
                 {new GrizzlyConnectorProvider(), false, false, true, true}, // change to true when JERSEY-2341 fixed
-                {new JettyConnectorProvider(), true, false, true, false}, // change to true when JERSEY-2341 fixed
+                {new JettyConnectorProvider(), false, false, true, false}, // change to true when JERSEY-2341 fixed
                 {new ApacheConnectorProvider(), false, false, true, true}, // change to true when JERSEY-2341 fixed
                 {new Apache5ConnectorProvider(), false, false, true, true}, // change to true when JERSEY-2341 fixed
+                {new JavaNetHttpConnectorProvider(), true, true, false, false},
         });
     }
 
@@ -119,7 +122,7 @@
     public Collection<DynamicContainer> generateTests() {
         Collection<DynamicContainer> tests = new ArrayList<>();
         testData().forEach(arr -> {
-            if (JdkVersion.getJdkVersion().getMajor() < 11
+            if (JdkVersion.getJdkVersion().getMajor() < 17
                     && arr[0].getClass().getName().contains("Jetty")) {
                 return;
             }
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxySelectorTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxySelectorTest.java
index 030119a..65e64a9 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxySelectorTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxySelectorTest.java
@@ -17,10 +17,11 @@
 
 package org.glassfish.jersey.tests.e2e.client.connector.proxy;
 
+import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.HttpChannel;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.netty.connector.NettyClientProperties;
 import org.glassfish.jersey.netty.connector.NettyConnectorProvider;
@@ -30,8 +31,6 @@
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.client.ClientBuilder;
@@ -113,21 +112,20 @@
         return client().target("http://eclipse.org:9998").path(path);
     }
 
-    static class ProxyHandler extends AbstractHandler {
+    static class ProxyHandler extends Handler.Abstract {
         Set<HttpChannel> httpConnect = new HashSet<>();
+
         @Override
-        public void handle(String target,
-                           Request baseRequest,
-                           HttpServletRequest request,
-                           HttpServletResponse response) {
-            if (request.getHeader(NO_PASS) != null) {
-                response.setStatus(Integer.parseInt(request.getHeader(NO_PASS)));
+        public boolean handle(Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception {
+            if (request.getHeaders().get(NO_PASS) != null) {
+                response.setStatus(Integer.parseInt(request.getHeaders().get(NO_PASS)));
             } else {
                 response.setStatus(407);
-                response.addHeader("Proxy-Authenticate", "Basic");
+                response.getHeaders().add("Proxy-Authenticate", "Basic");
             }
 
-            baseRequest.setHandled(true);
+            callback.succeeded();
+            return true;
         }
     }
 }
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java
index 25368cb..9da5b53 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java
@@ -17,10 +17,12 @@
 
 package org.glassfish.jersey.tests.e2e.client.connector.proxy;
 
+import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.HttpChannel;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.internal.HttpChannelState;
+import org.eclipse.jetty.util.Callback;
 import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
 import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
 import org.glassfish.jersey.client.ClientConfig;
@@ -38,8 +40,6 @@
 import org.junit.platform.suite.api.SelectClasses;
 import org.junit.platform.suite.api.Suite;
 
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.client.ClientBuilder;
@@ -202,17 +202,14 @@
         }
     }
 
-    static class ProxyHandler extends AbstractHandler {
+    static class ProxyHandler extends Handler.Abstract {
         Set<HttpChannel> httpConnect = new HashSet<>();
         @Override
-        public void handle(String target,
-                           Request baseRequest,
-                           HttpServletRequest request,
-                           HttpServletResponse response) {
-            if (request.getHeader(PROXY_NO_PASS) != null) {
-                response.setStatus(Integer.parseInt(request.getHeader(PROXY_NO_PASS)));
-            } else if (request.getHeader("Proxy-Authorization") != null) {
-                String proxyAuthorization = request.getHeader("Proxy-Authorization");
+        public boolean handle(Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception {
+            if (request.getHeaders().get(PROXY_NO_PASS) != null) {
+                response.setStatus(Integer.parseInt(request.getHeaders().get(PROXY_NO_PASS)));
+            } else if (request.getHeaders().get("Proxy-Authorization") != null) {
+                String proxyAuthorization = request.getHeaders().get("Proxy-Authorization");
                 String decoded = new String(Base64.getDecoder().decode(proxyAuthorization.substring(6).getBytes()),
                         CHARACTER_SET);
                 final String[] split = decoded.split(":");
@@ -231,21 +228,36 @@
 
                 if (response.getStatus() != 400) {
                     response.setStatus(200);
-                    if ("CONNECT".equalsIgnoreCase(baseRequest.getMethod())) { // NETTY way of doing proxy
-                        httpConnect.add(baseRequest.getHttpChannel());
+                    if ("CONNECT".equalsIgnoreCase(request.getMethod())) { // NETTY way of doing proxy
+                        if (!(request.getComponents() instanceof HttpChannelState)) {
+                            response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+                            callback.failed(new IllegalStateException(
+                                    "Expecting request.getComponents() to be an instance of HttpChannelState"));
+                            return true;
+                        }
+                        HttpChannel httpChannel = (HttpChannel) request.getComponents();
+                        httpConnect.add(httpChannel);
                     }
                 }
                 //TODO Add redirect to requestURI
             } else {
-                if (httpConnect.contains(baseRequest.getHttpChannel())) {
+                if (!(request.getComponents() instanceof HttpChannelState)) {
+                    response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+                    callback.failed(new IllegalStateException(
+                            "Expecting request.getComponents() to be an instance of HttpChannelState"));
+                    return true;
+                }
+                HttpChannel httpChannel = (HttpChannel) request.getComponents();
+                if (httpConnect.contains(httpChannel)) {
                     response.setStatus(200);
                 } else {
                     response.setStatus(407);
-                    response.addHeader("Proxy-Authenticate", "Basic");
+                    response.getHeaders().add("Proxy-Authenticate", "Basic");
                 }
             }
 
-            baseRequest.setHandled(true);
+            callback.succeeded();
+            return true;
         }
     }
 }
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
index a458eb9..690faa4 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,7 +18,6 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Arrays;
 import java.util.stream.Stream;
 
 import javax.net.ssl.SSLContext;
@@ -31,6 +30,7 @@
 import org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider;
 import org.glassfish.jersey.internal.util.JdkVersion;
 import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
+import org.glassfish.jersey.jnh.connector.JavaNetHttpConnectorProvider;
 
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -55,15 +55,17 @@
      * @return test parameters.
      */
     public static Stream<ConnectorProvider> testData() {
-        int size = JdkVersion.getJdkVersion().getMajor() < 11 ? 4 : 5;
+        int size = JdkVersion.getJdkVersion().getMajor() < 17 ? 5 : 6;
         final ConnectorProvider[] providers = new ConnectorProvider[size];
         providers[0] = new HttpUrlConnectorProvider();
         providers[1] = new GrizzlyConnectorProvider();
         providers[2] = new ApacheConnectorProvider();
         providers[3] = new Apache5ConnectorProvider();
-        if (size == 5) {
-            providers[4] = new JettyConnectorProvider();
+        providers[4] = new JavaNetHttpConnectorProvider();
+        if (size == 6) {
+            providers[5] = new JettyConnectorProvider();
         }
+
         return Stream.of(providers);
     }
 
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslConnectorHostnameVerifierTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslConnectorHostnameVerifierTest.java
index 2034975..544f5d9 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslConnectorHostnameVerifierTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslConnectorHostnameVerifierTest.java
@@ -34,6 +34,8 @@
 import org.glassfish.jersey.jetty.connector.JettyClientProperties;
 
 import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
+import org.glassfish.jersey.jnh.connector.JavaNetHttpConnectorProvider;
+
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -67,8 +69,10 @@
     @ParameterizedTest
     @MethodSource("testData")
     public void testHostnameVerifierApplied(ConnectorProvider connectorProvider) throws Exception {
-        // Grizzly connector does not support Hostname Verification
-        if (isExcluded(Arrays.asList(GrizzlyConnectorProvider.class), connectorProvider)) {
+        // Grizzly and JavaNetHttp connectors do not support Hostname Verification
+        if (isExcluded(Arrays.asList(GrizzlyConnectorProvider.class,
+                JavaNetHttpConnectorProvider.class),
+                connectorProvider)) {
             return;
         }
 
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/httpurlconnector/Expect100ContinueTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/httpurlconnector/Expect100ContinueTest.java
index f057572..e984b72 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/httpurlconnector/Expect100ContinueTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/httpurlconnector/Expect100ContinueTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,9 +16,7 @@
 
 package org.glassfish.jersey.tests.e2e.client.httpurlconnector;
 
-import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.client.HttpUrlConnectorProvider;
 import org.glassfish.jersey.client.RequestEntityProcessing;
 import org.glassfish.jersey.client.http.Expect100ContinueFeature;
 import org.glassfish.jersey.server.ResourceConfig;
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/nettyconnector/Expect100ContinueTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/nettyconnector/Expect100ContinueTest.java
index db08f92..1f18b80 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/nettyconnector/Expect100ContinueTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/nettyconnector/Expect100ContinueTest.java
@@ -16,9 +16,10 @@
 
 package org.glassfish.jersey.tests.e2e.client.nettyconnector;
 
+import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.RequestEntityProcessing;
@@ -40,6 +41,7 @@
 import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.Response;
 import java.io.IOException;
+import java.nio.ByteBuffer;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -202,39 +204,40 @@
                .post(Entity.text(ENTITY_STRING)));
     }
 
-    static class Expect100ContinueTestHandler extends AbstractHandler {
+    static class Expect100ContinueTestHandler extends Handler.Abstract {
         @Override
-        public void handle(String target,
-                           Request baseRequest,
-                           HttpServletRequest request,
-                           HttpServletResponse response) throws IOException {
-            boolean expected = request.getHeader("Expect") != null;
+        public boolean handle(Request request,
+                              org.eclipse.jetty.server.Response response,
+                              Callback callback) throws IOException {
+            boolean expected = request.getHeaders().contains("Expect");
             boolean failed = false;
+            final String target = request.getHttpURI().getCanonicalPath();
             if (target.equals("/" + RESOURCE_PATH_NOT_SUPPORTED)) {
-                response.sendError(417);
+                response.setStatus(417);
                 failed = true;
             }
             if (target.equals("/" + RESOURCE_PATH_UNAUTHORIZED)) {
-                response.sendError(401);
+                response.setStatus(401);
                 failed = true;
             }
             if (target.equals("/" + RESOURCE_PATH_PAYLOAD_TOO_LARGE)) {
-                response.sendError(413);
+                response.setStatus(413);
                 failed = true;
             }
             if (target.equals("/" + RESOURCE_PATH_METHOD_NOT_SUPPORTED)) {
-                response.sendError(405);
+                response.setStatus(405);
                 failed = true;
             }
             if (expected && !failed) {
                 System.out.println("Expect:100-continue found, sending response header");
                 response.setStatus(204);
+                callback.succeeded();
+                return true;
             }
-            response.getWriter().println();
-            response.flushBuffer();
-            baseRequest.setHandled(true);
+            response.write(true, ByteBuffer.wrap("\n\r".getBytes()), callback);
 
-            request.getReader().lines().forEach(System.out::println);
+            callback.failed(new ProcessingException(""));
+            return true;
         }
     }
 }
\ No newline at end of file
diff --git a/tests/e2e-core-common/pom.xml b/tests/e2e-core-common/pom.xml
index 8140ab6..1cf253d 100644
--- a/tests/e2e-core-common/pom.xml
+++ b/tests/e2e-core-common/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e-core-common</artifactId>
diff --git a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/TestRuntimeDelegate.java b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/TestRuntimeDelegate.java
index 491f42b..12b2a54 100644
--- a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/TestRuntimeDelegate.java
+++ b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/TestRuntimeDelegate.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,8 +16,10 @@
 
 package org.glassfish.jersey.tests.e2e.common;
 
+import jakarta.ws.rs.SeBootstrap;
 import jakarta.ws.rs.WebApplicationException;
 import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.EntityPart;
 import jakarta.ws.rs.core.Link;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
@@ -30,6 +32,8 @@
 
 import org.junit.jupiter.api.Assertions;
 
+import java.util.concurrent.CompletionStage;
+
 /**
  * Test runtime delegate.
  *
@@ -47,6 +51,22 @@
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
+    @Override
+    public SeBootstrap.Configuration.Builder createConfigurationBuilder() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public CompletionStage<SeBootstrap.Instance> bootstrap(Application application, SeBootstrap.Configuration configuration) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public CompletionStage<SeBootstrap.Instance> bootstrap(Class<? extends Application> aClass,
+                                                           SeBootstrap.Configuration configuration) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
     public void testMediaType() {
         MediaType m = new MediaType("text", "plain");
         Assertions.assertNotNull(m);
diff --git a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/message/internal/CookiesParserTest.java b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/message/internal/CookiesParserTest.java
index ad4b91a..16e9e0e 100644
--- a/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/message/internal/CookiesParserTest.java
+++ b/tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/message/internal/CookiesParserTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -37,14 +37,18 @@
 
     @Test
     public void testCaseInsensitiveNewCookieParams() throws Exception {
-        _testCaseInsensitiveNewCookieParams("expires", "max-age", "path", "domain", "comment", "version", "secure", "httponly");
-        _testCaseInsensitiveNewCookieParams("Expires", "Max-Age", "Path", "Domain", "Comment", "Version", "Secure", "HttpOnly");
-        _testCaseInsensitiveNewCookieParams("exPires", "max-aGe", "patH", "doMAin", "Comment", "vErsion", "secuRe", "httPonly");
+        _testCaseInsensitiveNewCookieParams("expires", "max-age", "path", "domain",
+                "comment", "version", "secure", "httponly", "samesite");
+        _testCaseInsensitiveNewCookieParams("Expires", "Max-Age", "Path", "Domain",
+                "Comment", "Version", "Secure", "HttpOnly", "SameSite");
+        _testCaseInsensitiveNewCookieParams("exPires", "max-aGe", "patH", "doMAin",
+                "Comment", "vErsion", "secuRe", "httPonly", "samEsite");
     }
 
     private void _testCaseInsensitiveNewCookieParams(final String expires, final String maxAge, final String path,
                                                      final String domain, final String comment, final String version,
-                                                     final String secure, final String httpOnly) throws Exception {
+                                                     final String secure, final String httpOnly, final String sameSite)
+            throws Exception {
 
         final String header = "foo=bar;"
                 + expires + "=Tue, 15 Jan 2013 21:47:38 GMT;"
@@ -54,7 +58,8 @@
                 + comment + "=Testing;"
                 + version + "=1;"
                 + secure + ";"
-                + httpOnly;
+                + httpOnly + ";"
+                + sameSite + "=STRICT";
 
         final NewCookie cookie = CookiesParser.parseNewCookie(header);
 
@@ -69,5 +74,6 @@
         assertThat(cookie.getVersion(), equalTo(1));
         assertThat(cookie.isSecure(), is(true));
         assertThat(cookie.isHttpOnly(), is(true));
+        assertThat(cookie.getSameSite(), equalTo(NewCookie.SameSite.STRICT));
     }
 }
diff --git a/tests/e2e-entity/pom.xml b/tests/e2e-entity/pom.xml
index 06324ed..8cd3251 100644
--- a/tests/e2e-entity/pom.xml
+++ b/tests/e2e-entity/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e-entity</artifactId>
diff --git a/tests/e2e-inject/cdi-inject-weld/pom.xml b/tests/e2e-inject/cdi-inject-weld/pom.xml
index 2fc4fbb..bd496d5 100644
--- a/tests/e2e-inject/cdi-inject-weld/pom.xml
+++ b/tests/e2e-inject/cdi-inject-weld/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>e2e-inject</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e-inject-cdi-inject-weld</artifactId>
diff --git a/tests/e2e-inject/cdi2-se/pom.xml b/tests/e2e-inject/cdi2-se/pom.xml
index 038c279..03552c8 100644
--- a/tests/e2e-inject/cdi2-se/pom.xml
+++ b/tests/e2e-inject/cdi2-se/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>e2e-inject</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e-inject-cdi2-se</artifactId>
diff --git a/tests/e2e-inject/cdi2-se/src/main/resources/META-INF/beans.xml b/tests/e2e-inject/cdi2-se/src/main/resources/META-INF/beans.xml
index ae84224..c2146b4 100644
--- a/tests/e2e-inject/cdi2-se/src/main/resources/META-INF/beans.xml
+++ b/tests/e2e-inject/cdi2-se/src/main/resources/META-INF/beans.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2017, 2022 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,7 +17,11 @@
 
 -->
 
-<beans>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                           http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="all">
     <interceptors>
         <class>org.glassfish.jersey.tests.e2e.inject.cdi.se.SecurityInterceptor</class>
     </interceptors>
diff --git a/tests/e2e-inject/hk2/pom.xml b/tests/e2e-inject/hk2/pom.xml
index 5a5fc92..e8e417d 100644
--- a/tests/e2e-inject/hk2/pom.xml
+++ b/tests/e2e-inject/hk2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>e2e-inject</artifactId>
         <groupId>org.glassfish.jersey.tests</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/e2e-inject/pom.xml b/tests/e2e-inject/pom.xml
index 52a5d22..da6418c 100644
--- a/tests/e2e-inject/pom.xml
+++ b/tests/e2e-inject/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e-inject</artifactId>
diff --git a/tests/e2e-server/pom.xml b/tests/e2e-server/pom.xml
index 57873f4..1f23251 100644
--- a/tests/e2e-server/pom.xml
+++ b/tests/e2e-server/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e-server</artifactId>
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/AsyncResponseTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/AsyncResponseTest.java
index 19db63b..bfb2dcf 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/AsyncResponseTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/AsyncResponseTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -47,6 +47,7 @@
 import org.glassfish.jersey.test.TestProperties;
 
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Disabled;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
@@ -105,6 +106,7 @@
     }
 
     @Test
+    @Disabled("since 3.1 nothing is being thrown")
     public void testResumeRuntimeException() throws Exception {
         testResumeException("resumeRuntimeException", null);
 
@@ -112,6 +114,7 @@
     }
 
     @Test
+    @Disabled("since 3.1 nothing is being thrown")
     public void testResumeCheckedException() throws Exception {
         testResumeException("resumeCheckedException", null);
 
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExceptionLoggingTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExceptionLoggingTest.java
index 8629f03..544df98 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExceptionLoggingTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExceptionLoggingTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -76,14 +76,12 @@
     public void testRuntime() throws Exception {
         final Response response = target().path("runtime").request().get();
         assertEquals(500, response.getStatus());
-        assertEquals(getLastLoggedRecord().getThrown().getClass(), MyRuntimeException.class);
     }
 
     @Test
     public void testChecked() throws Exception {
         final Response response = target().path("checked").request().get();
         assertEquals(500, response.getStatus());
-        assertEquals(getLastLoggedRecord().getThrown().getClass(), MyCheckedException.class);
     }
 
     @Provider
@@ -123,8 +121,6 @@
     public void testReaderFails() throws Exception {
         final Response response = target().path("resource/entity").request().get();
         assertEquals(500, response.getStatus());
-
-        assertEquals(getLastLoggedRecord().getThrown().getMessage(), "test");
     }
 
     static class ExceptionLoggingTestPOJO {
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExceptionMapperTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExceptionMapperTest.java
index f7f4f68..db144cc 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExceptionMapperTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExceptionMapperTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -137,6 +137,13 @@
         assertEquals(500, res.getStatus());
     }
 
+    @Test
+    public void testDefaultExceptionMapper() {
+        Response res = target().path("test/defaultExceptionMapper")
+                .request("test/test").get();
+        assertEquals(200, res.getStatus());
+    }
+
     @Path("test")
     public static class Resource {
 
@@ -174,6 +181,14 @@
                     new RuntimeException("runtime-exception",
                             new ClientErrorException("client-error", 499)));
         }
+
+        @GET
+        @Path("defaultExceptionMapper")
+        public Response isRegisteredDefaultExceptionTest(@Context Providers providers) {
+            ExceptionMapper<Throwable> em = providers
+                    .getExceptionMapper(Throwable.class);
+            return Response.status((em == null) ? 500 : 200).build();
+        }
     }
 
     public static class ClientErrorExceptionMapper implements ExceptionMapper<ClientErrorException> {
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExtendedExceptionMapperTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExtendedExceptionMapperTest.java
index 6934443..65d62f1 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExtendedExceptionMapperTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/ExtendedExceptionMapperTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -278,8 +278,8 @@
                     LocalizationMessages.ERROR_EXCEPTION_MAPPING_ORIGINAL_EXCEPTION(),
                     LocalizationMessages.ERROR_EXCEPTION_MAPPING_THROWN_TO_CONTAINER()}) {
 
-                if (logRecord.getMessage().contains(message) && logRecord.getLevel().intValue() > Level.FINE.intValue()) {
-                    fail("Log message should be logged at lower (FINE) level: " + message);
+                if (logRecord.getMessage().contains(message) && logRecord.getLevel().intValue() > Level.WARNING.intValue()) {
+                    fail("Log message should be logged at lower (WARNING) level: " + message);
                 }
             }
         }
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/sebootstrap/SeBootstrapPropertiesTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/sebootstrap/SeBootstrapPropertiesTest.java
new file mode 100644
index 0000000..0211f37
--- /dev/null
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/sebootstrap/SeBootstrapPropertiesTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.e2e.server.sebootstrap;
+
+import jakarta.ws.rs.SeBootstrap;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.internal.RuntimeDelegateImpl;
+import org.glassfish.jersey.server.spi.Container;
+import org.junit.jupiter.api.Test;
+
+import java.net.URI;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class SeBootstrapPropertiesTest {
+    @Test
+    public void testRandomPortScanning() {
+        JerseySeBootstrapConfiguration configuration = (JerseySeBootstrapConfiguration) RuntimeDelegateImpl.getInstance()
+                .createConfigurationBuilder().port(SeBootstrap.Configuration.FREE_PORT).build();
+
+        URI uri = configuration.uri(true);
+        assertTrue(uri.getPort() > 0);
+    }
+
+    @Test
+    public void testDefaultUnprivilegedPort() {
+        JerseySeBootstrapConfiguration configuration = (JerseySeBootstrapConfiguration) RuntimeDelegateImpl.getInstance()
+                .createConfigurationBuilder().port(SeBootstrap.Configuration.DEFAULT_PORT).build();
+
+        URI uri = configuration.uri(true);
+        assertEquals(Container.DEFAULT_HTTP_PORT + 8000, uri.getPort());
+    }
+
+    @Test
+    public void testDefaultPrivilegedPort() {
+        JerseySeBootstrapConfiguration configuration = (JerseySeBootstrapConfiguration) RuntimeDelegateImpl.getInstance()
+                .createConfigurationBuilder()
+                .property(ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS, Boolean.TRUE)
+                .port(SeBootstrap.Configuration.DEFAULT_PORT).build();
+
+        URI uri = configuration.uri(true);
+        assertEquals(Container.DEFAULT_HTTP_PORT, uri.getPort());
+    }
+
+    @Test
+    public void testDefaultUnprivilegedSecuredPort() {
+        JerseySeBootstrapConfiguration configuration = (JerseySeBootstrapConfiguration) RuntimeDelegateImpl.getInstance()
+                .createConfigurationBuilder().protocol("HTTPS").port(SeBootstrap.Configuration.DEFAULT_PORT).build();
+
+        URI uri = configuration.uri(true);
+        assertEquals(Container.DEFAULT_HTTPS_PORT + 8000, uri.getPort());
+    }
+
+    @Test
+    public void testDefaultPrivilegedSecuredPort() {
+        JerseySeBootstrapConfiguration configuration = (JerseySeBootstrapConfiguration) RuntimeDelegateImpl.getInstance()
+                .createConfigurationBuilder()
+                .protocol("HTTPS")
+                .property(ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS, Boolean.TRUE)
+                .port(SeBootstrap.Configuration.DEFAULT_PORT).build();
+
+        URI uri = configuration.uri(true);
+        assertEquals(Container.DEFAULT_HTTPS_PORT, uri.getPort());
+    }
+}
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/sebootstrap/SeBootstrapSystemPropertiesTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/sebootstrap/SeBootstrapSystemPropertiesTest.java
new file mode 100644
index 0000000..c443b52
--- /dev/null
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/sebootstrap/SeBootstrapSystemPropertiesTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.e2e.server.sebootstrap;
+
+import jakarta.ws.rs.SeBootstrap;
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.server.internal.RuntimeDelegateImpl;
+import org.glassfish.jersey.server.spi.Container;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.net.URI;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class SeBootstrapSystemPropertiesTest {
+
+    @BeforeAll
+    public static void setUp() {
+        System.setProperty(CommonProperties.ALLOW_SYSTEM_PROPERTIES_PROVIDER, Boolean.TRUE.toString());
+        System.getProperties().put(SeBootstrap.Configuration.PORT, "9998");
+        System.getProperties().put(ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS, Boolean.TRUE.toString());
+    }
+
+    @AfterAll
+    public static void tearDown() {
+        System.clearProperty(CommonProperties.ALLOW_SYSTEM_PROPERTIES_PROVIDER);
+        System.clearProperty(SeBootstrap.Configuration.PORT);
+        System.clearProperty(ServerProperties.WEBSERVER_ALLOW_PRIVILEGED_PORTS);
+    }
+
+    @Test
+    public void testDefaultPrivilegedPortSystemProperty() {
+        JerseySeBootstrapConfiguration configuration = (JerseySeBootstrapConfiguration) RuntimeDelegateImpl.getInstance()
+                .createConfigurationBuilder()
+                .port(SeBootstrap.Configuration.DEFAULT_PORT).build();
+
+        URI uri = configuration.uri(true);
+        assertEquals(Container.DEFAULT_HTTP_PORT, uri.getPort());
+    }
+
+    @Test
+    public void testPortSystemProperty() {
+        JerseySeBootstrapConfiguration configuration = (JerseySeBootstrapConfiguration) RuntimeDelegateImpl.getInstance()
+                .createConfigurationBuilder()
+                .build();
+
+        URI uri = configuration.uri(true);
+        assertEquals(9998, uri.getPort());
+    }
+}
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/sebootstrap/SeBootstrapTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/sebootstrap/SeBootstrapTest.java
new file mode 100644
index 0000000..afc676d
--- /dev/null
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/sebootstrap/SeBootstrapTest.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020 Markus Karg. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package org.glassfish.jersey.tests.e2e.server.sebootstrap;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.is;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.UriBuilder;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Compliance Test for Java SE Bootstrap API of Jakarta REST API
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1
+ */
+public class SeBootstrapTest {
+    /**
+     * Verifies that an instance will boot using default configuration.
+     *
+     * @throws ExecutionException   if the instance didn't boot correctly
+     * @throws InterruptedException if the test took much longer than usually
+     *                              expected
+     */
+    @Test
+    public final void shouldBootInstanceUsingDefaults() throws InterruptedException, ExecutionException {
+        // given
+        final int expectedResponse = mockInt();
+        final Application application = new StaticApplication(expectedResponse);
+        final SeBootstrap.Configuration.Builder bootstrapConfigurationBuilder = SeBootstrap.Configuration.builder();
+        final SeBootstrap.Configuration requestedConfiguration = bootstrapConfigurationBuilder.build();
+
+        // when
+        final CompletionStage<SeBootstrap.Instance> completionStage = SeBootstrap.start(application, requestedConfiguration);
+        final SeBootstrap.Instance instance = completionStage.toCompletableFuture().get();
+        final SeBootstrap.Configuration actualConfiguration = instance.configuration();
+        final int actualResponse = client.target(UriBuilder.newInstance().scheme(actualConfiguration.protocol())
+                .host(actualConfiguration.host()).port(actualConfiguration.port()).path(actualConfiguration.rootPath())
+                .path("application/resource")).request().get(int.class);
+
+        // then
+        assertThat(actualResponse, is(expectedResponse));
+        assertThat(actualConfiguration.protocol(), is("HTTP"));
+        assertThat(actualConfiguration.host(), is("localhost"));
+        assertThat(actualConfiguration.port(), is(greaterThan(0)));
+        assertThat(actualConfiguration.rootPath(), is("/"));
+        instance.stop().toCompletableFuture().get();
+    }
+
+    /**
+     * Verifies that an instance will boot using explicit configuration given by
+     * properties.
+     *
+     * @throws ExecutionException   if the instance didn't boot correctly
+     * @throws InterruptedException if the test took much longer than usually
+     *                              expected
+     * @throws IOException          if no IP port was free
+     */
+    @Test
+    public final void shouldBootInstanceUsingProperties() throws InterruptedException, ExecutionException, IOException {
+        // given
+        final int expectedResponse = mockInt();
+        final Application application = new StaticApplication(expectedResponse);
+        final SeBootstrap.Configuration.Builder bootstrapConfigurationBuilder = SeBootstrap.Configuration.builder();
+        final SeBootstrap.Configuration requestedConfiguration = bootstrapConfigurationBuilder
+                .property(SeBootstrap.Configuration.PROTOCOL, "HTTP")
+                .property(SeBootstrap.Configuration.HOST, "localhost")
+                .property(SeBootstrap.Configuration.PORT, someFreeIpPort())
+                .property(SeBootstrap.Configuration.ROOT_PATH, "/root/path").build();
+
+        // when
+        final CompletionStage<SeBootstrap.Instance> completionStage = SeBootstrap.start(application, requestedConfiguration);
+        final SeBootstrap.Instance instance = completionStage.toCompletableFuture().get();
+        final SeBootstrap.Configuration actualConfiguration = instance.configuration();
+        final int actualResponse = client.target(UriBuilder.newInstance().scheme(actualConfiguration.protocol())
+                .host(actualConfiguration.host()).port(actualConfiguration.port()).path(actualConfiguration.rootPath())
+                .path("application/resource")).request().get(int.class);
+
+        // then
+        assertThat(actualResponse, is(expectedResponse));
+        assertThat(actualConfiguration.protocol(), is(requestedConfiguration.protocol()));
+        assertThat(actualConfiguration.host(), is(requestedConfiguration.host()));
+        assertThat(actualConfiguration.port(), is(requestedConfiguration.port()));
+        assertThat(actualConfiguration.rootPath(), is(requestedConfiguration.rootPath()));
+        instance.stop().toCompletableFuture().get();
+    }
+
+    /**
+     * Verifies that an instance will boot using explicit configuration given by
+     * convenience methods.
+     *
+     * @throws ExecutionException   if the instance didn't boot correctly
+     * @throws InterruptedException if the test took much longer than usually
+     *                              expected
+     * @throws IOException          if no IP port was free
+     */
+    @Test
+    public final void shouldBootInstanceUsingConvenienceMethods() throws InterruptedException, ExecutionException, IOException {
+        // given
+        final int expectedResponse = mockInt();
+        final Application application = new StaticApplication(expectedResponse);
+        final SeBootstrap.Configuration.Builder bootstrapConfigurationBuilder = SeBootstrap.Configuration.builder();
+        final SeBootstrap.Configuration requestedConfiguration = bootstrapConfigurationBuilder.protocol("HTTP").host("localhost")
+                .port(someFreeIpPort()).rootPath("/root/path").build();
+
+        // when
+        final CompletionStage<SeBootstrap.Instance> completionStage = SeBootstrap.start(application, requestedConfiguration);
+        final SeBootstrap.Instance instance = completionStage.toCompletableFuture().get();
+        final SeBootstrap.Configuration actualConfiguration = instance.configuration();
+        final int actualResponse = client.target(UriBuilder.newInstance().scheme(actualConfiguration.protocol())
+                .host(actualConfiguration.host()).port(actualConfiguration.port()).path(actualConfiguration.rootPath())
+                .path("application/resource")).request().get(int.class);
+
+        // then
+        assertThat(actualResponse, is(expectedResponse));
+        assertThat(actualConfiguration.protocol(), is(requestedConfiguration.protocol()));
+        assertThat(actualConfiguration.host(), is(requestedConfiguration.host()));
+        assertThat(actualConfiguration.port(), is(requestedConfiguration.port()));
+        assertThat(actualConfiguration.rootPath(), is(requestedConfiguration.rootPath()));
+        instance.stop().toCompletableFuture().get();
+    }
+
+    /**
+     * Verifies that an instance will boot using external configuration.
+     *
+     * @throws ExecutionException   if the instance didn't boot correctly
+     * @throws InterruptedException if the test took much longer than usually
+     *                              expected
+     * @throws IOException          if no IP port was free
+     */
+    @Test
+    public final void shouldBootInstanceUsingExternalConfiguration() throws Exception {
+        // given
+        final int someFreeIpPort = someFreeIpPort();
+        final int expectedResponse = mockInt();
+        final Application application = new StaticApplication(expectedResponse);
+        final SeBootstrap.Configuration.Builder bootstrapConfigurationBuilder = SeBootstrap.Configuration.builder();
+        final SeBootstrap.Configuration requestedConfiguration = bootstrapConfigurationBuilder.from((property, type) -> {
+            switch (property) {
+                case SeBootstrap.Configuration.PROTOCOL:
+                    return Optional.of("HTTP");
+                case SeBootstrap.Configuration.HOST:
+                    return Optional.of("localhost");
+                case SeBootstrap.Configuration.PORT:
+                    return Optional.of(someFreeIpPort);
+                case SeBootstrap.Configuration.ROOT_PATH:
+                    return Optional.of("/root/path");
+                default:
+                    return Optional.empty();
+            }
+        }).build();
+
+        // when
+        final CompletionStage<SeBootstrap.Instance> completionStage = SeBootstrap.start(application, requestedConfiguration);
+        final SeBootstrap.Instance instance = completionStage.toCompletableFuture().get();
+        final SeBootstrap.Configuration actualConfiguration = instance.configuration();
+        final int actualResponse = client.target(UriBuilder.newInstance().scheme(actualConfiguration.protocol())
+                .host(actualConfiguration.host()).port(actualConfiguration.port()).path(actualConfiguration.rootPath())
+                .path("application/resource")).request().get(int.class);
+
+        // then
+        assertThat(actualResponse, is(expectedResponse));
+        assertThat(actualConfiguration.protocol(), is(requestedConfiguration.protocol()));
+        assertThat(actualConfiguration.host(), is(requestedConfiguration.host()));
+        assertThat(actualConfiguration.port(), is(requestedConfiguration.port()));
+        assertThat(actualConfiguration.rootPath(), is(requestedConfiguration.rootPath()));
+        instance.stop().toCompletableFuture().get();
+    }
+
+    /**
+     * Verifies that an instance will ignore unknown configuration parameters.
+     *
+     * @throws ExecutionException   if the instance didn't boot correctly
+     * @throws InterruptedException if the test took much longer than usually
+     *                              expected
+     * @throws IOException          if no IP port was free
+     */
+    @Test
+    public final void shouldBootInstanceDespiteUnknownConfigurationParameters() throws Exception {
+        // given
+        final int expectedResponse = mockInt();
+        final Application application = new StaticApplication(expectedResponse);
+        final SeBootstrap.Configuration.Builder bootstrapConfigurationBuilder = SeBootstrap.Configuration.builder();
+        final SeBootstrap.Configuration requestedConfiguration = bootstrapConfigurationBuilder.protocol("HTTP").host("localhost")
+                .port(someFreeIpPort()).rootPath("/root/path").from((property, type) -> {
+            switch (property) {
+                case "jakarta.ws.rs.tck.sebootstrap.SeBootstrapIT$Unknown_1":
+                    return Optional.of("Silently ignored value A");
+                default:
+                    return Optional.empty();
+            }
+        }).property("jakarta.ws.rs.tck.sebootstrap.SeBootstrapIT$Unknown_2", "Silently ignored value B")
+                .from(new Object()).build();
+
+        // when
+        final CompletionStage<SeBootstrap.Instance> completionStage = SeBootstrap.start(application, requestedConfiguration);
+        final SeBootstrap.Instance instance = completionStage.toCompletableFuture().get();
+        final SeBootstrap.Configuration actualConfiguration = instance.configuration();
+        final int actualResponse = client.target(UriBuilder.newInstance().scheme(actualConfiguration.protocol())
+                .host(actualConfiguration.host()).port(actualConfiguration.port()).path(actualConfiguration.rootPath())
+                .path("application/resource")).request().get(int.class);
+
+        // then
+        assertThat(actualResponse, is(expectedResponse));
+        assertThat(actualConfiguration.protocol(), is(requestedConfiguration.protocol()));
+        assertThat(actualConfiguration.host(), is(requestedConfiguration.host()));
+        assertThat(actualConfiguration.port(), is(requestedConfiguration.port()));
+        assertThat(actualConfiguration.rootPath(), is(requestedConfiguration.rootPath()));
+        instance.stop().toCompletableFuture().get();
+    }
+
+    /**
+     * Verifies that an instance will boot using a self-detected free IP port.
+     *
+     * @throws ExecutionException   if the instance didn't boot correctly
+     * @throws InterruptedException if the test took much longer than usually
+     *                              expected
+     */
+    @Test
+    public final void shouldBootInstanceUsingSelfDetectedFreeIpPort() throws InterruptedException, ExecutionException {
+        // given
+        final int expectedResponse = mockInt();
+        final Application application = new StaticApplication(expectedResponse);
+        final SeBootstrap.Configuration.Builder bootstrapConfigurationBuilder = SeBootstrap.Configuration.builder();
+        final SeBootstrap.Configuration requestedConfiguration = bootstrapConfigurationBuilder.protocol("HTTP").host("localhost")
+                .port(SeBootstrap.Configuration.FREE_PORT).rootPath("/root/path").build();
+
+        // when
+        final CompletionStage<SeBootstrap.Instance> completionStage = SeBootstrap.start(application, requestedConfiguration);
+        final SeBootstrap.Instance instance = completionStage.toCompletableFuture().get();
+        final SeBootstrap.Configuration actualConfiguration = instance.configuration();
+        final int actualResponse = client.target(UriBuilder.newInstance().scheme(actualConfiguration.protocol())
+                .host(actualConfiguration.host()).port(actualConfiguration.port()).path(actualConfiguration.rootPath())
+                .path("application/resource")).request().get(int.class);
+
+        // then
+        assertThat(actualResponse, is(expectedResponse));
+        assertThat(actualConfiguration.protocol(), is(requestedConfiguration.protocol()));
+        assertThat(actualConfiguration.host(), is(requestedConfiguration.host()));
+        assertThat(actualConfiguration.port(), is(greaterThan(0)));
+        assertThat(actualConfiguration.rootPath(), is(requestedConfiguration.rootPath()));
+        instance.stop().toCompletableFuture().get();
+    }
+
+    /**
+     * Verifies that an instance will boot using the implementation's default IP
+     * port.
+     *
+     * @throws ExecutionException   if the instance didn't boot correctly
+     * @throws InterruptedException if the test took much longer than usually
+     *                              expected
+     */
+    @Test
+    public final void shouldBootInstanceUsingImplementationsDefaultIpPort() throws InterruptedException, ExecutionException {
+        // given
+        final int expectedResponse = mockInt();
+        final Application application = new StaticApplication(expectedResponse);
+        final SeBootstrap.Configuration.Builder bootstrapConfigurationBuilder = SeBootstrap.Configuration.builder();
+        final SeBootstrap.Configuration requestedConfiguration = bootstrapConfigurationBuilder.protocol("HTTP").host("localhost")
+                .port(SeBootstrap.Configuration.DEFAULT_PORT).rootPath("/root/path").build();
+
+        // when
+        final CompletionStage<SeBootstrap.Instance> completionStage = SeBootstrap.start(application, requestedConfiguration);
+        final SeBootstrap.Instance instance = completionStage.toCompletableFuture().get();
+        final SeBootstrap.Configuration actualConfiguration = instance.configuration();
+        final int actualResponse = client.target(UriBuilder.newInstance().scheme(actualConfiguration.protocol())
+                .host(actualConfiguration.host()).port(actualConfiguration.port()).path(actualConfiguration.rootPath())
+                .path("application/resource")).request().get(int.class);
+
+        // then
+        assertThat(actualResponse, is(expectedResponse));
+        assertThat(actualConfiguration.protocol(), is(requestedConfiguration.protocol()));
+        assertThat(actualConfiguration.host(), is(requestedConfiguration.host()));
+        assertThat(actualConfiguration.port(), is(greaterThan(0)));
+        assertThat(actualConfiguration.rootPath(), is(requestedConfiguration.rootPath()));
+        instance.stop().toCompletableFuture().get();
+    }
+
+    private static Client client;
+
+    @BeforeAll
+    public static void createClient() {
+        SeBootstrapTest.client = ClientBuilder.newClient();
+    }
+
+    @AfterAll
+    public static void disposeClient() {
+        SeBootstrapTest.client.close();
+    }
+
+    @ApplicationPath("application")
+    public static final class StaticApplication extends Application {
+
+        private final StaticResource staticResource;
+
+        private StaticApplication(final long staticResponse) {
+            this.staticResource = new StaticResource(staticResponse);
+        }
+
+        @Override
+        public final Set<Object> getSingletons() {
+            return Collections.<Object>singleton(staticResource);
+        }
+
+        @Path("resource")
+        public static final class StaticResource {
+
+            private final long staticResponse;
+
+            private StaticResource(final long staticResponse) {
+                this.staticResponse = staticResponse;
+            }
+
+            @GET
+            public final long staticResponse() {
+                return this.staticResponse;
+            }
+        }
+    }
+
+    private static final int someFreeIpPort() throws IOException {
+        int port = 0;
+        int cnt = 0;
+        while (port < 1024 && cnt++ < 1025) {
+            try (final ServerSocket serverSocket = new ServerSocket(0)) {
+                port = serverSocket.getLocalPort();
+            }
+        }
+        return port;
+    }
+
+    private static final int mockInt() {
+        return (int) Math.round(Integer.MAX_VALUE * Math.random());
+    }
+}
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/validation/validateonexecution/ValidateOnExecutionBasicTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/validation/validateonexecution/ValidateOnExecutionBasicTest.java
index 995a6fb..cd39529 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/validation/validateonexecution/ValidateOnExecutionBasicTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/validation/validateonexecution/ValidateOnExecutionBasicTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -32,13 +32,20 @@
 import jakarta.validation.executable.ExecutableType;
 import jakarta.validation.executable.ValidateOnExecution;
 
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.xml.bind.JAXBContext;
+import jakarta.xml.bind.JAXBException;
+import org.eclipse.persistence.jaxb.BeanValidationMode;
+import org.eclipse.persistence.jaxb.MarshallerProperties;
+import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.server.ServerProperties;
 import org.glassfish.jersey.test.TestProperties;
 
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.parallel.Execution;
-import org.junit.jupiter.api.parallel.ExecutionMode;
+
+import java.util.HashMap;
+import java.util.Map;
 
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -290,6 +297,28 @@
         }
     }
 
+    /**
+     * Do not validate the bean by Moxy, validate just by Jersey
+     */
+    public static class MoxyNotValidateContextResolver implements ContextResolver<JAXBContext> {
+        @Override
+        public JAXBContext getContext(Class<?> type) {
+            Map<String, Object> properties = new HashMap<>();
+            properties.put(MarshallerProperties.BEAN_VALIDATION_MODE, BeanValidationMode.NONE);
+            try {
+                return JAXBContext.newInstance(new Class[]{type}, properties);
+            } catch (JAXBException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.register(MoxyNotValidateContextResolver.class);
+        super.configureClient(config);
+    }
+
     @Override
     protected Application configure() {
         enable(TestProperties.LOG_TRAFFIC);
@@ -310,7 +339,8 @@
                 ValidateGetterExecutableOnTypeMatch.class,
                 ValidateGetterExecutableOnBeans.class,
                 ValidateGetterResourceMethod.class,
-                ValidateExecutableResource.class)
+                ValidateExecutableResource.class,
+                MoxyNotValidateContextResolver.class)
                 .property(ServerProperties.BV_DISABLE_VALIDATE_ON_EXECUTABLE_OVERRIDE_CHECK, true);
     }
 
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlBeanParamTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlBeanParamTest.java
index 8790628..17b3124 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlBeanParamTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlBeanParamTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -39,9 +39,13 @@
 import jakarta.ws.rs.core.Request;
 import jakarta.ws.rs.core.Response;
 
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.xpath.XPath;
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlResourceTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlResourceTest.java
index 6c4907f..749eb22 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlResourceTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlResourceTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -1006,7 +1006,12 @@
                     final String document = response.readEntity(String.class);
 
                     // check that the resulting document contains a method element with id="fooX"
-                    assertTrue(document.replaceAll("\n", " ").matches(".*<method[^>]+id=\"foo" + i + "\"[^>]*>.*"));
+                    assertTrue(document
+                            .replaceAll("\n", " ")
+                            .replaceAll("\r", "")
+                            .replaceAll("ns0:", "")
+                            .matches(".*<method[^>]+id=\"foo" + i + "\"[^>]*>.*")
+                    );
                 }
             }
         }
diff --git a/tests/e2e-testng/pom.xml b/tests/e2e-testng/pom.xml
index 47e4cf5..66087ed 100644
--- a/tests/e2e-testng/pom.xml
+++ b/tests/e2e-testng/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e-testng</artifactId>
diff --git a/tests/e2e-tls/pom.xml b/tests/e2e-tls/pom.xml
index 1ae746c..eaa7198 100644
--- a/tests/e2e-tls/pom.xml
+++ b/tests/e2e-tls/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e-tls</artifactId>
@@ -44,6 +44,7 @@
                     <skipTests>${skip.e2e}</skipTests>
                     <systemPropertyVariables>
                         <sun.net.http.allowRestrictedHeaders>true</sun.net.http.allowRestrictedHeaders>
+                        <jdk.httpclient.allowRestrictedHeaders>Host</jdk.httpclient.allowRestrictedHeaders>
                         <property>
                             <name>ssl.debug</name>
                             <value>true</value>
@@ -110,6 +111,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.glassfish.jersey.connectors</groupId>
+            <artifactId>jersey-jnh-connector</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.glassfish.jersey.security</groupId>
             <artifactId>oauth1-signature</artifactId>
             <version>${project.version}</version>
diff --git a/tests/e2e-tls/src/test/java/org/glassfish/jersey/tests/e2e/tls/SniTest.java b/tests/e2e-tls/src/test/java/org/glassfish/jersey/tests/e2e/tls/SniTest.java
index 1e8d893..3964fce 100644
--- a/tests/e2e-tls/src/test/java/org/glassfish/jersey/tests/e2e/tls/SniTest.java
+++ b/tests/e2e-tls/src/test/java/org/glassfish/jersey/tests/e2e/tls/SniTest.java
@@ -16,6 +16,7 @@
 
 package org.glassfish.jersey.tests.e2e.tls;
 
+import jakarta.ws.rs.client.Invocation;
 import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
 import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
 import org.glassfish.jersey.client.ClientConfig;
@@ -23,9 +24,9 @@
 import org.glassfish.jersey.client.HttpUrlConnectorProvider;
 import org.glassfish.jersey.client.spi.ConnectorProvider;
 import org.glassfish.jersey.jdk.connector.JdkConnectorProvider;
+import org.glassfish.jersey.jnh.connector.JavaNetHttpConnectorProvider;
 import org.glassfish.jersey.netty.connector.NettyConnectorProvider;
 import org.glassfish.jersey.tests.e2e.tls.explorer.SSLCapabilities;
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
 
@@ -39,21 +40,19 @@
 import java.net.InetAddress;
 import java.net.Socket;
 import java.net.SocketTimeoutException;
-import java.net.URI;
 import java.net.UnknownHostException;
-import java.nio.charset.StandardCharsets;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
 public class SniTest {
     private static final int PORT = 8443;
     private static final String LOCALHOST = "127.0.0.1";
 
-
     static {
+// Debug
+//        System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
+//        System.setProperty("jdk.httpclient.allowRestrictedHeaders", "Host");
         // JDK specific settings
         System.setProperty("jdk.net.hosts.file", SniTest.class.getResource("/hosts").getPath());
     }
@@ -64,7 +63,8 @@
                 new ApacheConnectorProvider(),
                 new Apache5ConnectorProvider(),
                 new JdkConnectorProvider(),
-                new HttpUrlConnectorProvider()
+                new HttpUrlConnectorProvider(),
+                new JavaNetHttpConnectorProvider()
         };
     }
 
@@ -73,10 +73,11 @@
     public void server1Test(ConnectorProvider provider) {
         ClientConfig clientConfig = new ClientConfig();
         clientConfig.connectorProvider(provider);
-        serverTest(clientConfig, "www.host1.com");
+        clientConfig.property(ClientProperties.SNI_HOST_NAME, "www.host1.com");
+        serverTest(clientConfig, provider, "www.host1.com");
     }
 
-    public void serverTest(ClientConfig clientConfig, String hostName) {
+    public void serverTest(ClientConfig clientConfig, ConnectorProvider provider, String hostName) {
         String newHostName = replaceWhenHostNotKnown(hostName);
         final List<SNIServerName> serverNames = new LinkedList<>();
         final String[] requestHostName = new String[1];
@@ -91,7 +92,7 @@
 
         clientConfig.property(ClientProperties.READ_TIMEOUT, 2000);
         clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 2000);
-        try (Response r = ClientBuilder.newClient(clientConfig)
+        Invocation.Builder builder = ClientBuilder.newClient(clientConfig)
                 .register(new ClientRequestFilter() {
                     @Override
                     public void filter(ClientRequestContext requestContext) throws IOException {
@@ -100,9 +101,11 @@
                 })
                 .target("https://" + (newHostName.equals(LOCALHOST) ? LOCALHOST : "www.host0.com") + ":" + PORT)
                 .path("host")
-                .request()
-                .header(HttpHeaders.HOST, hostName + ":8080")
-                .get()) {
+                .request();
+        if (!JavaNetHttpConnectorProvider.class.isInstance(provider)) {
+            builder = builder.header(HttpHeaders.HOST, hostName + ":8080");
+        }
+        try (Response r = builder.get()) {
             // empty
         } catch (Exception e) {
             Throwable cause = e;
@@ -111,7 +114,7 @@
                     && TimeoutException.class.isInstance(cause)) {
                 cause = cause.getCause();
             }
-            if (cause == null && /*IOE*/ !e.getMessage().contains("Stream closed")) {
+            if ((!e.getMessage().contains("Stream closed")) && !e.getMessage().contains("timed out")) {
                 throw e;
             }
         }
diff --git a/tests/e2e/pom.xml b/tests/e2e/pom.xml
index 6f7c8be..e6368cc 100644
--- a/tests/e2e/pom.xml
+++ b/tests/e2e/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>e2e</artifactId>
@@ -200,7 +200,7 @@
         <profile>
             <id>JettyExclude</id>
             <activation>
-                <jdk>1.8</jdk>
+                <jdk>[11,17)</jdk>
             </activation>
             <build>
                 <plugins>
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/CookieImplTest.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/CookieImplTest.java
index 1068272..5f727fc 100644
--- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/CookieImplTest.java
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/CookieImplTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -187,6 +187,12 @@
         cookie = new NewCookie("fred", "flintstone", null, null, "a modern stonage family", 60, false);
         expResult = "fred=flintstone;Version=1;Comment=\"a modern stonage family\";Max-Age=60";
         assertEquals(expResult, cookie.toString());
+
+        cookie = new NewCookie("fred", "flintstone", null, null, 1,
+                "a modern stonage family", 60, null, false, false,
+                NewCookie.SameSite.STRICT);
+        expResult = "fred=flintstone;Version=1;Comment=\"a modern stonage family\";Max-Age=60;SameSite=STRICT";
+        assertEquals(expResult, cookie.toString());
     }
 
     @Test
@@ -209,6 +215,16 @@
         assertEquals(1, cookie.getVersion());
         assertEquals(60, cookie.getMaxAge());
         assertTrue(cookie.isSecure());
+
+        cookie = NewCookie.valueOf(
+                "fred=flintstone;Version=1;Comment=\"a modern stonage family\";Max-Age=60;Secure;SameSite=NONE");
+        assertEquals("fred", cookie.getName());
+        assertEquals("flintstone", cookie.getValue());
+        assertEquals("a modern stonage family", cookie.getComment());
+        assertEquals(1, cookie.getVersion());
+        assertEquals(60, cookie.getMaxAge());
+        assertTrue(cookie.isSecure());
+        assertEquals(NewCookie.SameSite.NONE, cookie.getSameSite());
     }
 
 }
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/Jersey2462Test.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/Jersey2462Test.java
index f67d538..54bbf12 100644
--- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/Jersey2462Test.java
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/Jersey2462Test.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -174,13 +174,13 @@
             // let's also test some method calls
             int flags = 0;
 
-            if ("/echo".equals(jettyRequest.get().getPathInfo())) {
+            if ("/echo".equals(jettyRequest.get().getHttpURI().getPath())) {
                 flags += 1;
             }
             if (!jettyResponse.get().isCommitted()) {
                 flags += 10;
             }
-            final String header = jettyRequest.get().getHeader(REQUEST_NUMBER);
+            final String header = jettyRequest.get().getHeaders().get(REQUEST_NUMBER);
 
             ctx.setEntityStream(new ByteArrayInputStream(("filtered-" + flags + "-" + header).getBytes()));
         }
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java
index b1f5cfc..f6bb0b7 100644
--- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -54,10 +54,10 @@
 
     protected static List<TestContainerFactory> listContainerFactories(TestContainerFactory... factories) {
         final JdkVersion version = JdkVersion.getJdkVersion();
-        boolean isJDK8 = version.getMajor() == 1;
+        boolean isJDKGreaterThanOrEqualTo17 = version.getMajor() >= 17;
         final List<TestContainerFactory> filtered = new LinkedList<>();
         for (TestContainerFactory factory : factories) {
-            if (!isJDK8 || !JettyTestContainerFactory.class.isInstance(factory)) {
+            if (isJDKGreaterThanOrEqualTo17 || !JettyTestContainerFactory.class.isInstance(factory)) {
                 filtered.add(factory);
             }
         }
diff --git a/tests/integration/asm/pom.xml b/tests/integration/asm/pom.xml
index 54981f3..b3145d6 100644
--- a/tests/integration/asm/pom.xml
+++ b/tests/integration/asm/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/async-jersey-filter/pom.xml b/tests/integration/async-jersey-filter/pom.xml
index c881619..50db49d 100644
--- a/tests/integration/async-jersey-filter/pom.xml
+++ b/tests/integration/async-jersey-filter/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>async-jersey-filter</artifactId>
@@ -49,7 +49,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
     </dependencies>
@@ -65,8 +64,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/cdi-integration/cdi-beanvalidation-webapp/pom.xml b/tests/integration/cdi-integration/cdi-beanvalidation-webapp/pom.xml
index 06c585e..2f58eeb 100644
--- a/tests/integration/cdi-integration/cdi-beanvalidation-webapp/pom.xml
+++ b/tests/integration/cdi-integration/cdi-beanvalidation-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-beanvalidation-webapp</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-client-on-server/pom.xml b/tests/integration/cdi-integration/cdi-client-on-server/pom.xml
index 1c2c229..bb7fb92 100644
--- a/tests/integration/cdi-integration/cdi-client-on-server/pom.xml
+++ b/tests/integration/cdi-integration/cdi-client-on-server/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-client-on-server</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-client/pom.xml b/tests/integration/cdi-integration/cdi-client/pom.xml
index 912d4f3..2559d43 100644
--- a/tests/integration/cdi-integration/cdi-client/pom.xml
+++ b/tests/integration/cdi-integration/cdi-client/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-client</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-ejb-test-webapp/pom.xml b/tests/integration/cdi-integration/cdi-ejb-test-webapp/pom.xml
index beca9ff..7cc32cc 100644
--- a/tests/integration/cdi-integration/cdi-ejb-test-webapp/pom.xml
+++ b/tests/integration/cdi-integration/cdi-ejb-test-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-ejb-test-webapp</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-iface-with-non-jaxrs-impl-test-webapp/pom.xml b/tests/integration/cdi-integration/cdi-iface-with-non-jaxrs-impl-test-webapp/pom.xml
index 2d893ff..ca11b19 100644
--- a/tests/integration/cdi-integration/cdi-iface-with-non-jaxrs-impl-test-webapp/pom.xml
+++ b/tests/integration/cdi-integration/cdi-iface-with-non-jaxrs-impl-test-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-iface-with-non-jaxrs-impl-test-webapp</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-log-check/pom.xml b/tests/integration/cdi-integration/cdi-log-check/pom.xml
index d3bbfeb..40d5231 100644
--- a/tests/integration/cdi-integration/cdi-log-check/pom.xml
+++ b/tests/integration/cdi-integration/cdi-log-check/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-log-check</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-manually-bound/pom.xml b/tests/integration/cdi-integration/cdi-manually-bound/pom.xml
index 013c207..f93ab02 100644
--- a/tests/integration/cdi-integration/cdi-manually-bound/pom.xml
+++ b/tests/integration/cdi-integration/cdi-manually-bound/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>cdi-integration-project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/cdi-integration/cdi-multimodule/ear/pom.xml b/tests/integration/cdi-integration/cdi-multimodule/ear/pom.xml
index ce46b08..d593eff 100644
--- a/tests/integration/cdi-integration/cdi-multimodule/ear/pom.xml
+++ b/tests/integration/cdi-integration/cdi-multimodule/ear/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/cdi-integration/cdi-multimodule/lib/pom.xml b/tests/integration/cdi-integration/cdi-multimodule/lib/pom.xml
index 26506a2..bbbb899 100644
--- a/tests/integration/cdi-integration/cdi-multimodule/lib/pom.xml
+++ b/tests/integration/cdi-integration/cdi-multimodule/lib/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/cdi-integration/cdi-multimodule/pom.xml b/tests/integration/cdi-integration/cdi-multimodule/pom.xml
index 467158e..682fd03 100644
--- a/tests/integration/cdi-integration/cdi-multimodule/pom.xml
+++ b/tests/integration/cdi-integration/cdi-multimodule/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-multimodule</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-multimodule/war1/pom.xml b/tests/integration/cdi-integration/cdi-multimodule/war1/pom.xml
index 7383398..cfaf26a 100644
--- a/tests/integration/cdi-integration/cdi-multimodule/war1/pom.xml
+++ b/tests/integration/cdi-integration/cdi-multimodule/war1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
@@ -40,7 +40,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/tests/integration/cdi-integration/cdi-multimodule/war2/pom.xml b/tests/integration/cdi-integration/cdi-multimodule/war2/pom.xml
index 2bacefa..ea7e9e1 100644
--- a/tests/integration/cdi-integration/cdi-multimodule/war2/pom.xml
+++ b/tests/integration/cdi-integration/cdi-multimodule/war2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/cdi-integration/cdi-multipart-webapp/pom.xml b/tests/integration/cdi-integration/cdi-multipart-webapp/pom.xml
index a37f7e8..e43ca61 100644
--- a/tests/integration/cdi-integration/cdi-multipart-webapp/pom.xml
+++ b/tests/integration/cdi-integration/cdi-multipart-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-multipart-webapp</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-resource-with-at-context/pom.xml b/tests/integration/cdi-integration/cdi-resource-with-at-context/pom.xml
index 4917433..771d261 100644
--- a/tests/integration/cdi-integration/cdi-resource-with-at-context/pom.xml
+++ b/tests/integration/cdi-integration/cdi-resource-with-at-context/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -51,7 +51,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.test-framework.providers</groupId>
diff --git a/tests/integration/cdi-integration/cdi-singleton/pom.xml b/tests/integration/cdi-integration/cdi-singleton/pom.xml
index 9b54794..b4864d4 100644
--- a/tests/integration/cdi-integration/cdi-singleton/pom.xml
+++ b/tests/integration/cdi-integration/cdi-singleton/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>cdi-integration-project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/cdi-integration/cdi-test-webapp/pom.xml b/tests/integration/cdi-integration/cdi-test-webapp/pom.xml
index 88debad..99f1c90 100644
--- a/tests/integration/cdi-integration/cdi-test-webapp/pom.xml
+++ b/tests/integration/cdi-integration/cdi-test-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-test-webapp</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-test-webapp/src/main/resources/META-INF/beans.xml b/tests/integration/cdi-integration/cdi-test-webapp/src/main/resources/META-INF/beans.xml
index 14ea61e..8d3e4b2 100644
--- a/tests/integration/cdi-integration/cdi-test-webapp/src/main/resources/META-INF/beans.xml
+++ b/tests/integration/cdi-integration/cdi-test-webapp/src/main/resources/META-INF/beans.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,4 +17,9 @@
 
 -->
 
-<beans/>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                           http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="all">
+</beans>
diff --git a/tests/integration/cdi-integration/cdi-test-webapp/src/main/webapp/WEB-INF/beans.xml b/tests/integration/cdi-integration/cdi-test-webapp/src/main/webapp/WEB-INF/beans.xml
index 14ea61e..8d3e4b2 100644
--- a/tests/integration/cdi-integration/cdi-test-webapp/src/main/webapp/WEB-INF/beans.xml
+++ b/tests/integration/cdi-integration/cdi-test-webapp/src/main/webapp/WEB-INF/beans.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,4 +17,9 @@
 
 -->
 
-<beans/>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                           http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="all">
+</beans>
diff --git a/tests/integration/cdi-integration/cdi-with-jersey-injection-custom-cfg-webapp/pom.xml b/tests/integration/cdi-integration/cdi-with-jersey-injection-custom-cfg-webapp/pom.xml
index 7fdd4f4..12cb676 100644
--- a/tests/integration/cdi-integration/cdi-with-jersey-injection-custom-cfg-webapp/pom.xml
+++ b/tests/integration/cdi-integration/cdi-with-jersey-injection-custom-cfg-webapp/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-with-jersey-injection-custom-cfg-webapp</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-with-jersey-injection-custom-hk2-banned-webapp/pom.xml b/tests/integration/cdi-integration/cdi-with-jersey-injection-custom-hk2-banned-webapp/pom.xml
index d3c0a3a..5a2bf95 100644
--- a/tests/integration/cdi-integration/cdi-with-jersey-injection-custom-hk2-banned-webapp/pom.xml
+++ b/tests/integration/cdi-integration/cdi-with-jersey-injection-custom-hk2-banned-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-with-jersey-injection-custom-hk2-banned-webapp</artifactId>
diff --git a/tests/integration/cdi-integration/cdi-with-jersey-injection-webapp/pom.xml b/tests/integration/cdi-integration/cdi-with-jersey-injection-webapp/pom.xml
index 0a7d037..1171a86 100644
--- a/tests/integration/cdi-integration/cdi-with-jersey-injection-webapp/pom.xml
+++ b/tests/integration/cdi-integration/cdi-with-jersey-injection-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>cdi-with-jersey-injection-webapp</artifactId>
diff --git a/tests/integration/cdi-integration/context-inject-on-server/pom.xml b/tests/integration/cdi-integration/context-inject-on-server/pom.xml
index f4d2868..91c20a3 100644
--- a/tests/integration/cdi-integration/context-inject-on-server/pom.xml
+++ b/tests/integration/cdi-integration/context-inject-on-server/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>context-inject-on-server</artifactId>
@@ -49,7 +49,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.test-framework.providers</groupId>
diff --git a/tests/integration/cdi-integration/gf-cdi-inject/pom.xml b/tests/integration/cdi-integration/gf-cdi-inject/pom.xml
index 7939348..50dec33 100644
--- a/tests/integration/cdi-integration/gf-cdi-inject/pom.xml
+++ b/tests/integration/cdi-integration/gf-cdi-inject/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration.cdi</groupId>
         <artifactId>cdi-integration-project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>gf-cdi-inject-on-server</artifactId>
@@ -31,7 +31,7 @@
     <description>Embedded GF tests @Inject</description>
 
     <properties>
-        <glassfish.home>${project.build.directory}/glassfish6</glassfish.home>
+        <glassfish.home>${project.build.directory}/glassfish7</glassfish.home>
         <modules.dir>${glassfish.home}/glassfish/modules</modules.dir>
         <glassfish.container.version>${gf.impl.version}</glassfish.container.version>
     </properties>
@@ -79,6 +79,11 @@
             <groupId>org.glassfish.jersey.core</groupId>
             <artifactId>jersey-server</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>jakarta.activation</groupId>
+            <artifactId>jakarta.activation-api</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/tests/integration/cdi-integration/pom.xml b/tests/integration/cdi-integration/pom.xml
index fd86911..8b0d439 100644
--- a/tests/integration/cdi-integration/pom.xml
+++ b/tests/integration/cdi-integration/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>pom</packaging>
diff --git a/tests/integration/client-connector-provider/pom.xml b/tests/integration/client-connector-provider/pom.xml
index a11bf71..82aa5d1 100644
--- a/tests/integration/client-connector-provider/pom.xml
+++ b/tests/integration/client-connector-provider/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>client-connector-provider</artifactId>
diff --git a/tests/integration/ejb-multimodule-reload/ear/pom.xml b/tests/integration/ejb-multimodule-reload/ear/pom.xml
index cc87bdc..d5e0ccf 100644
--- a/tests/integration/ejb-multimodule-reload/ear/pom.xml
+++ b/tests/integration/ejb-multimodule-reload/ear/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/ejb-multimodule-reload/lib/pom.xml b/tests/integration/ejb-multimodule-reload/lib/pom.xml
index d1949af..d982224 100644
--- a/tests/integration/ejb-multimodule-reload/lib/pom.xml
+++ b/tests/integration/ejb-multimodule-reload/lib/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/ejb-multimodule-reload/pom.xml b/tests/integration/ejb-multimodule-reload/pom.xml
index f129c55..f7d49df 100644
--- a/tests/integration/ejb-multimodule-reload/pom.xml
+++ b/tests/integration/ejb-multimodule-reload/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>ejb-multimodule-reload</artifactId>
diff --git a/tests/integration/ejb-multimodule-reload/war1/pom.xml b/tests/integration/ejb-multimodule-reload/war1/pom.xml
index 85d5d3e..3339abe 100644
--- a/tests/integration/ejb-multimodule-reload/war1/pom.xml
+++ b/tests/integration/ejb-multimodule-reload/war1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/ejb-multimodule-reload/war2/pom.xml b/tests/integration/ejb-multimodule-reload/war2/pom.xml
index 1a42ef9..cbc1c22 100644
--- a/tests/integration/ejb-multimodule-reload/war2/pom.xml
+++ b/tests/integration/ejb-multimodule-reload/war2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/ejb-multimodule/ear/pom.xml b/tests/integration/ejb-multimodule/ear/pom.xml
index 0714a35..a9d9a0a 100644
--- a/tests/integration/ejb-multimodule/ear/pom.xml
+++ b/tests/integration/ejb-multimodule/ear/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/ejb-multimodule/lib/pom.xml b/tests/integration/ejb-multimodule/lib/pom.xml
index 5daaf10..3b29350 100644
--- a/tests/integration/ejb-multimodule/lib/pom.xml
+++ b/tests/integration/ejb-multimodule/lib/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/ejb-multimodule/pom.xml b/tests/integration/ejb-multimodule/pom.xml
index 2178b6a..ff9ad58 100644
--- a/tests/integration/ejb-multimodule/pom.xml
+++ b/tests/integration/ejb-multimodule/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>ejb-multimodule</artifactId>
diff --git a/tests/integration/ejb-multimodule/war/pom.xml b/tests/integration/ejb-multimodule/war/pom.xml
index 2f46c9b..ca8216a 100644
--- a/tests/integration/ejb-multimodule/war/pom.xml
+++ b/tests/integration/ejb-multimodule/war/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/ejb-test-webapp/pom.xml b/tests/integration/ejb-test-webapp/pom.xml
index 7880577..7258e8e 100644
--- a/tests/integration/ejb-test-webapp/pom.xml
+++ b/tests/integration/ejb-test-webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>ejb-test-webapp</artifactId>
@@ -40,7 +40,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
          <dependency>
diff --git a/tests/integration/externalproperties/pom.xml b/tests/integration/externalproperties/pom.xml
index 914bf25..fa2a55d 100644
--- a/tests/integration/externalproperties/pom.xml
+++ b/tests/integration/externalproperties/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>externalproperties</artifactId>
diff --git a/tests/integration/externalproperties/src/test/java/org/glassfish/jersey/tests/externalproperties/HttpProxyTest.java b/tests/integration/externalproperties/src/test/java/org/glassfish/jersey/tests/externalproperties/HttpProxyTest.java
index c6ecc29..84edb0f 100644
--- a/tests/integration/externalproperties/src/test/java/org/glassfish/jersey/tests/externalproperties/HttpProxyTest.java
+++ b/tests/integration/externalproperties/src/test/java/org/glassfish/jersey/tests/externalproperties/HttpProxyTest.java
@@ -16,9 +16,10 @@
 
 package org.glassfish.jersey.tests.externalproperties;
 
+import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
 import org.glassfish.jersey.ExternalProperties;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
@@ -30,8 +31,6 @@
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
 import jakarta.ws.rs.core.Application;
@@ -99,15 +98,13 @@
         Assertions.assertFalse(proxyHit);
     }
 
-    class ProxyHandler extends AbstractHandler {
+    class ProxyHandler extends Handler.Abstract {
         @Override
-        public void handle(String target,
-                           Request baseRequest,
-                           HttpServletRequest request,
-                           HttpServletResponse response) {
+        public boolean handle(Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception {
             proxyHit = true;
             response.setStatus(407);
-            baseRequest.setHandled(true);
+            callback.succeeded();
+            return true;
         }
 
         ProxyHandler(boolean pProxyHit) {
@@ -117,4 +114,3 @@
     }
 
 }
-
diff --git a/tests/integration/j-376/pom.xml b/tests/integration/j-376/pom.xml
index a969555..8153618 100644
--- a/tests/integration/j-376/pom.xml
+++ b/tests/integration/j-376/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>j-376</artifactId>
@@ -75,9 +75,21 @@
         <dependency>
             <groupId>org.jboss.weld.se</groupId>
             <artifactId>weld-se-core</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.jboss.logging</groupId>
+                    <artifactId>jboss-logging</artifactId>
+                </exclusion>
+            </exclusions>
             <scope>compile</scope>
         </dependency>
         <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <version>${jboss.logging.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.glassfish.jersey.ext.cdi</groupId>
             <artifactId>jersey-cdi1x</artifactId>
             <version>${project.version}</version>
diff --git a/tests/integration/j-441/ear/pom.xml b/tests/integration/j-441/ear/pom.xml
index f249bf3..5e78c79 100644
--- a/tests/integration/j-441/ear/pom.xml
+++ b/tests/integration/j-441/ear/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
     <artifactId>j-441-ear</artifactId>
diff --git a/tests/integration/j-441/pom.xml b/tests/integration/j-441/pom.xml
index 5e5cbba..c747525 100644
--- a/tests/integration/j-441/pom.xml
+++ b/tests/integration/j-441/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>j-441</artifactId>
diff --git a/tests/integration/j-441/war1/pom.xml b/tests/integration/j-441/war1/pom.xml
index 8f8d5fd..74dba24 100644
--- a/tests/integration/j-441/war1/pom.xml
+++ b/tests/integration/j-441/war1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
@@ -42,7 +42,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/tests/integration/j-441/war2/pom.xml b/tests/integration/j-441/war2/pom.xml
index d94697e..1afe3b3 100644
--- a/tests/integration/j-441/war2/pom.xml
+++ b/tests/integration/j-441/war2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
@@ -42,7 +42,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/tests/integration/j-59/ear/pom.xml b/tests/integration/j-59/ear/pom.xml
index 76e1b4f..4e4fed3 100644
--- a/tests/integration/j-59/ear/pom.xml
+++ b/tests/integration/j-59/ear/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/j-59/lib/pom.xml b/tests/integration/j-59/lib/pom.xml
index ac55643..0c9c1fb 100644
--- a/tests/integration/j-59/lib/pom.xml
+++ b/tests/integration/j-59/lib/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
diff --git a/tests/integration/j-59/pom.xml b/tests/integration/j-59/pom.xml
index e0852cb..935a08e 100644
--- a/tests/integration/j-59/pom.xml
+++ b/tests/integration/j-59/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>j-59</artifactId>
diff --git a/tests/integration/j-59/war/pom.xml b/tests/integration/j-59/war/pom.xml
index 89be368..dfa084f 100644
--- a/tests/integration/j-59/war/pom.xml
+++ b/tests/integration/j-59/war/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
@@ -65,6 +65,11 @@
             <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>jakarta.jws</groupId>
+            <artifactId>jakarta.jws-api</artifactId>
+            <version>1.1.1</version>
+        </dependency>
     </dependencies>
 
     <build>
@@ -96,22 +101,6 @@
         </plugins>
     </build>
 
-    <profiles>
-        <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <dependencies>
-              <dependency>
-                  <groupId>jakarta.jws</groupId>
-                  <artifactId>jakarta.jws-api</artifactId>
-                  <version>1.1.1</version>
-              </dependency>
-            </dependencies>
-        </profile>
-    </profiles>
-
     <properties>
         <failOnMissingWebXml>false</failOnMissingWebXml>
         <skipTests>true</skipTests>
diff --git a/tests/integration/jackson-14/pom.xml b/tests/integration/jackson-14/pom.xml
index 0ef4f03..12b1986 100644
--- a/tests/integration/jackson-14/pom.xml
+++ b/tests/integration/jackson-14/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/jaxrs-component-inject/pom.xml b/tests/integration/jaxrs-component-inject/pom.xml
index 1c69d67..8dae71d 100644
--- a/tests/integration/jaxrs-component-inject/pom.xml
+++ b/tests/integration/jaxrs-component-inject/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jaxrs-component-inject</artifactId>
@@ -54,8 +54,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-1107/pom.xml b/tests/integration/jersey-1107/pom.xml
index ede5afa..092d754 100644
--- a/tests/integration/jersey-1107/pom.xml
+++ b/tests/integration/jersey-1107/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-1107</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-1223/pom.xml b/tests/integration/jersey-1223/pom.xml
index dee0979..7366006 100644
--- a/tests/integration/jersey-1223/pom.xml
+++ b/tests/integration/jersey-1223/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>jersey-1223</artifactId>
@@ -58,8 +58,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-1604/pom.xml b/tests/integration/jersey-1604/pom.xml
index 157a853..a2fd82f 100644
--- a/tests/integration/jersey-1604/pom.xml
+++ b/tests/integration/jersey-1604/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>jersey-1604</artifactId>
@@ -61,8 +61,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-1667/pom.xml b/tests/integration/jersey-1667/pom.xml
index b735cb7..4aba42f 100644
--- a/tests/integration/jersey-1667/pom.xml
+++ b/tests/integration/jersey-1667/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-1667</artifactId>
@@ -60,8 +60,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-1883/pom.xml b/tests/integration/jersey-1883/pom.xml
index 485a0a4..74eaca9 100644
--- a/tests/integration/jersey-1883/pom.xml
+++ b/tests/integration/jersey-1883/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-1883</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-1928/pom.xml b/tests/integration/jersey-1928/pom.xml
index 284ef02..a686f5b 100644
--- a/tests/integration/jersey-1928/pom.xml
+++ b/tests/integration/jersey-1928/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>jersey-1928</artifactId>
@@ -57,8 +57,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-1960/pom.xml b/tests/integration/jersey-1960/pom.xml
index 86d4533..da35a12 100644
--- a/tests/integration/jersey-1960/pom.xml
+++ b/tests/integration/jersey-1960/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-1960</artifactId>
@@ -36,7 +36,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -63,8 +62,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-1964/pom.xml b/tests/integration/jersey-1964/pom.xml
index 964c9ce..bdb930f 100644
--- a/tests/integration/jersey-1964/pom.xml
+++ b/tests/integration/jersey-1964/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-1964</artifactId>
@@ -48,7 +48,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -70,8 +69,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2031/pom.xml b/tests/integration/jersey-2031/pom.xml
index 2917b62..4f953ee 100644
--- a/tests/integration/jersey-2031/pom.xml
+++ b/tests/integration/jersey-2031/pom.xml
@@ -25,7 +25,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2031</artifactId>
@@ -46,7 +46,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -67,8 +66,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee9</groupId>
+                <artifactId>jetty-ee9-maven-plugin</artifactId>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
diff --git a/tests/integration/jersey-2136/pom.xml b/tests/integration/jersey-2136/pom.xml
index 78c3d08..34d3258 100644
--- a/tests/integration/jersey-2136/pom.xml
+++ b/tests/integration/jersey-2136/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2136</artifactId>
diff --git a/tests/integration/jersey-2137/pom.xml b/tests/integration/jersey-2137/pom.xml
index b0b9e8b..36b221b 100644
--- a/tests/integration/jersey-2137/pom.xml
+++ b/tests/integration/jersey-2137/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2137</artifactId>
diff --git a/tests/integration/jersey-2154/pom.xml b/tests/integration/jersey-2154/pom.xml
index 6d94579..2e7a40f 100644
--- a/tests/integration/jersey-2154/pom.xml
+++ b/tests/integration/jersey-2154/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2154</artifactId>
diff --git a/tests/integration/jersey-2160/pom.xml b/tests/integration/jersey-2160/pom.xml
index 1a64aec..a698d69 100644
--- a/tests/integration/jersey-2160/pom.xml
+++ b/tests/integration/jersey-2160/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2160</artifactId>
@@ -36,7 +36,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -63,8 +62,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2164/pom.xml b/tests/integration/jersey-2164/pom.xml
index 0a1de3c..344de9b 100644
--- a/tests/integration/jersey-2164/pom.xml
+++ b/tests/integration/jersey-2164/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2164</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2167/pom.xml b/tests/integration/jersey-2167/pom.xml
index e57690d..4693ff7 100644
--- a/tests/integration/jersey-2167/pom.xml
+++ b/tests/integration/jersey-2167/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2167</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2176/pom.xml b/tests/integration/jersey-2176/pom.xml
index 2f15b54..2b1f799 100644
--- a/tests/integration/jersey-2176/pom.xml
+++ b/tests/integration/jersey-2176/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2176</artifactId>
@@ -41,7 +41,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -63,8 +62,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee9</groupId>
+                <artifactId>jetty-ee9-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/Jersey2176App.java b/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/Jersey2176App.java
index 4bc3f0c..bff0fe2 100644
--- a/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/Jersey2176App.java
+++ b/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/Jersey2176App.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -34,6 +34,7 @@
         property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, setStatusOverSendError);
         register(MyWriterInterceptor.class);
         register(Issue2176ReproducerResource.class);
+        register(Jersey2176ExceptionMapper.class);
     }
 
     public boolean isSetStatusOverSendError() {
diff --git a/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/Jersey2176ExceptionMapper.java b/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/Jersey2176ExceptionMapper.java
new file mode 100644
index 0000000..3a97c3d
--- /dev/null
+++ b/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/Jersey2176ExceptionMapper.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.jersey2176;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
+
+public class Jersey2176ExceptionMapper implements ExceptionMapper<Throwable> {
+    @Override
+    public Response toResponse(Throwable exception) {
+        if (exception instanceof WebApplicationException) {
+            return ((WebApplicationException) exception).getResponse();
+        }
+        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(exception).build();
+    }
+}
diff --git a/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/TraceResponseFilter.java b/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/TraceResponseFilter.java
index ddb6b60..dadc0cd 100644
--- a/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/TraceResponseFilter.java
+++ b/tests/integration/jersey-2176/src/main/java/org/glassfish/jersey/tests/integration/jersey2176/TraceResponseFilter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -61,6 +61,9 @@
         } catch (final Throwable th) {
             status = "FAIL";
         } finally {
+            if (((HttpServletResponse) response).getStatus() == 500) {
+                status = "FAIL";
+            }
             final long duration = System.nanoTime() - startTime;
             ((HttpServletResponse) response).addHeader(X_SERVER_DURATION_HEADER, String.valueOf(duration));
             ((HttpServletResponse) response).addHeader(X_STATUS_HEADER, status);
diff --git a/tests/integration/jersey-2184/pom.xml b/tests/integration/jersey-2184/pom.xml
index 2a04eb8..0431ff2 100644
--- a/tests/integration/jersey-2184/pom.xml
+++ b/tests/integration/jersey-2184/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2184</artifactId>
@@ -42,7 +42,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -64,8 +63,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2255/pom.xml b/tests/integration/jersey-2255/pom.xml
index e4d70e0..4944f35 100644
--- a/tests/integration/jersey-2255/pom.xml
+++ b/tests/integration/jersey-2255/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2255</artifactId>
@@ -64,8 +64,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2322/pom.xml b/tests/integration/jersey-2322/pom.xml
index 47f6087..fe74066 100644
--- a/tests/integration/jersey-2322/pom.xml
+++ b/tests/integration/jersey-2322/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2322</artifactId>
@@ -58,22 +58,14 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <excludes>
-                        <exclude>**/*</exclude>
-                    </excludes>
-                    <testExcludes>
-                        <testExclude>**/*</testExclude>
-                    </testExcludes>
-                </configuration>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2335/pom.xml b/tests/integration/jersey-2335/pom.xml
index 0c0e722..e584ec5 100644
--- a/tests/integration/jersey-2335/pom.xml
+++ b/tests/integration/jersey-2335/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2335</artifactId>
@@ -60,8 +60,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2421/pom.xml b/tests/integration/jersey-2421/pom.xml
index 9610ac0..6333580 100644
--- a/tests/integration/jersey-2421/pom.xml
+++ b/tests/integration/jersey-2421/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2421</artifactId>
diff --git a/tests/integration/jersey-2551/pom.xml b/tests/integration/jersey-2551/pom.xml
index 2b276b6..e88d21c 100644
--- a/tests/integration/jersey-2551/pom.xml
+++ b/tests/integration/jersey-2551/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2551</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2612/pom.xml b/tests/integration/jersey-2612/pom.xml
index e3c014b..ca46c5b 100644
--- a/tests/integration/jersey-2612/pom.xml
+++ b/tests/integration/jersey-2612/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2612</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2637/pom.xml b/tests/integration/jersey-2637/pom.xml
index 2589cd6..b873eb8 100644
--- a/tests/integration/jersey-2637/pom.xml
+++ b/tests/integration/jersey-2637/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2637</artifactId>
@@ -38,7 +38,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -64,8 +63,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2654/pom.xml b/tests/integration/jersey-2654/pom.xml
index eeb36ac..6933ca0 100644
--- a/tests/integration/jersey-2654/pom.xml
+++ b/tests/integration/jersey-2654/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2654</artifactId>
@@ -55,8 +55,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2673/pom.xml b/tests/integration/jersey-2673/pom.xml
index df3b9db..403a67a 100644
--- a/tests/integration/jersey-2673/pom.xml
+++ b/tests/integration/jersey-2673/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2673</artifactId>
@@ -53,7 +53,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -75,8 +74,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2689/pom.xml b/tests/integration/jersey-2689/pom.xml
index 82439d5..b2288a8 100644
--- a/tests/integration/jersey-2689/pom.xml
+++ b/tests/integration/jersey-2689/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2689</artifactId>
@@ -81,7 +81,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
     </dependencies>
@@ -97,8 +96,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2704/pom.xml b/tests/integration/jersey-2704/pom.xml
index 6587e06..a6aae38 100644
--- a/tests/integration/jersey-2704/pom.xml
+++ b/tests/integration/jersey-2704/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2704</artifactId>
@@ -48,7 +48,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
     </dependencies>
@@ -64,8 +63,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2776/pom.xml b/tests/integration/jersey-2776/pom.xml
index ed12934..783ba1d 100644
--- a/tests/integration/jersey-2776/pom.xml
+++ b/tests/integration/jersey-2776/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2776</artifactId>
diff --git a/tests/integration/jersey-2794/pom.xml b/tests/integration/jersey-2794/pom.xml
index a657be7..99610e2 100644
--- a/tests/integration/jersey-2794/pom.xml
+++ b/tests/integration/jersey-2794/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2794</artifactId>
@@ -63,8 +63,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2846/pom.xml b/tests/integration/jersey-2846/pom.xml
index cf10467..ce24404 100644
--- a/tests/integration/jersey-2846/pom.xml
+++ b/tests/integration/jersey-2846/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2846</artifactId>
@@ -63,8 +63,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2878/pom.xml b/tests/integration/jersey-2878/pom.xml
index 22925a8..38fe5fe 100644
--- a/tests/integration/jersey-2878/pom.xml
+++ b/tests/integration/jersey-2878/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2878</artifactId>
@@ -64,8 +64,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-2892/pom.xml b/tests/integration/jersey-2892/pom.xml
index be6dd22..c053453 100644
--- a/tests/integration/jersey-2892/pom.xml
+++ b/tests/integration/jersey-2892/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-2892</artifactId>
@@ -70,8 +70,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-3662/pom.xml b/tests/integration/jersey-3662/pom.xml
index d9a61e0..f49319c 100644
--- a/tests/integration/jersey-3662/pom.xml
+++ b/tests/integration/jersey-3662/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/jersey-3670/pom.xml b/tests/integration/jersey-3670/pom.xml
index 0cade80..f20b5f4 100644
--- a/tests/integration/jersey-3670/pom.xml
+++ b/tests/integration/jersey-3670/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-3670</artifactId>
diff --git a/tests/integration/jersey-3796/pom.xml b/tests/integration/jersey-3796/pom.xml
index f62af07..85b8089 100644
--- a/tests/integration/jersey-3796/pom.xml
+++ b/tests/integration/jersey-3796/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-3796</artifactId>
@@ -47,7 +47,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -76,8 +75,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/jersey-3992/pom.xml b/tests/integration/jersey-3992/pom.xml
index b1acaa9..e02b49d 100644
--- a/tests/integration/jersey-3992/pom.xml
+++ b/tests/integration/jersey-3992/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-3992</artifactId>
diff --git a/tests/integration/jersey-4003/pom.xml b/tests/integration/jersey-4003/pom.xml
index 7d5bb78..4f8eb3b 100644
--- a/tests/integration/jersey-4003/pom.xml
+++ b/tests/integration/jersey-4003/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/jersey-4099/pom.xml b/tests/integration/jersey-4099/pom.xml
index 8c70bb4..fa547fc 100644
--- a/tests/integration/jersey-4099/pom.xml
+++ b/tests/integration/jersey-4099/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-4099</artifactId>
@@ -60,6 +60,18 @@
         <dependency>
             <groupId>org.jboss.weld.se</groupId>
             <artifactId>weld-se-core</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.jboss.logging</groupId>
+                    <artifactId>jboss-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <version>${jboss.logging.version}</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.inject</groupId>
diff --git a/tests/integration/jersey-4321/pom.xml b/tests/integration/jersey-4321/pom.xml
index 06034c7..5c567d4 100644
--- a/tests/integration/jersey-4321/pom.xml
+++ b/tests/integration/jersey-4321/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/jersey-4507/pom.xml b/tests/integration/jersey-4507/pom.xml
index c6c5b8f..add1313 100644
--- a/tests/integration/jersey-4507/pom.xml
+++ b/tests/integration/jersey-4507/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/jersey-4542/pom.xml b/tests/integration/jersey-4542/pom.xml
index 6493a6d..9f67a79 100644
--- a/tests/integration/jersey-4542/pom.xml
+++ b/tests/integration/jersey-4542/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/jersey-4542/src/test/resources/META-INF/beans.xml b/tests/integration/jersey-4542/src/test/resources/META-INF/beans.xml
index d773c46..d6b4b48 100644
--- a/tests/integration/jersey-4542/src/test/resources/META-INF/beans.xml
+++ b/tests/integration/jersey-4542/src/test/resources/META-INF/beans.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
 
     This program and the accompanying materials are made available under the
     terms of the Eclipse Public License v. 2.0, which is available at
@@ -17,4 +17,9 @@
 
 -->
 
-<beans/>
\ No newline at end of file
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+                           http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="all">
+</beans>
\ No newline at end of file
diff --git a/tests/integration/jersey-4697/pom.xml b/tests/integration/jersey-4697/pom.xml
index 537af89..f3e89df 100644
--- a/tests/integration/jersey-4697/pom.xml
+++ b/tests/integration/jersey-4697/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/jersey-4722/pom.xml b/tests/integration/jersey-4722/pom.xml
index c983d70..02b0809 100644
--- a/tests/integration/jersey-4722/pom.xml
+++ b/tests/integration/jersey-4722/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -39,13 +39,11 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.glassfish.jersey.test-framework.providers</groupId>
             <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
-            <version>${project.version}</version>
             <exclusions>
                 <exclusion>
                     <groupId>org.glassfish.jersey.media</groupId>
diff --git a/tests/integration/jersey-4949/pom.xml b/tests/integration/jersey-4949/pom.xml
index 3550947..9c43419 100644
--- a/tests/integration/jersey-4949/pom.xml
+++ b/tests/integration/jersey-4949/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-4949</artifactId>
@@ -60,8 +60,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
                 <configuration>
                     <scan>10</scan>
                     <webApp>
diff --git a/tests/integration/jersey-5087/pom.xml b/tests/integration/jersey-5087/pom.xml
index ed7ddc0..ba590c3 100644
--- a/tests/integration/jersey-5087/pom.xml
+++ b/tests/integration/jersey-5087/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/jersey-780/pom.xml b/tests/integration/jersey-780/pom.xml
index b7cd1a3..39b8f7e 100644
--- a/tests/integration/jersey-780/pom.xml
+++ b/tests/integration/jersey-780/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-780</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/microprofile/config/helidon/pom.xml b/tests/integration/microprofile/config/helidon/pom.xml
index dae6aca..ede2a57 100644
--- a/tests/integration/microprofile/config/helidon/pom.xml
+++ b/tests/integration/microprofile/config/helidon/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>microprofile-config-project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration.microprofile</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/microprofile/config/pom.xml b/tests/integration/microprofile/config/pom.xml
index 670aa0c..e100574 100644
--- a/tests/integration/microprofile/config/pom.xml
+++ b/tests/integration/microprofile/config/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>microprofile-integration-project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration.microprofile</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>pom</packaging>
diff --git a/tests/integration/microprofile/config/webapp/pom.xml b/tests/integration/microprofile/config/webapp/pom.xml
index 251bd05..fe1c633 100644
--- a/tests/integration/microprofile/config/webapp/pom.xml
+++ b/tests/integration/microprofile/config/webapp/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>microprofile-config-project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration.microprofile</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/microprofile/pom.xml b/tests/integration/microprofile/pom.xml
index c1bd293..e1118c3 100644
--- a/tests/integration/microprofile/pom.xml
+++ b/tests/integration/microprofile/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>pom</packaging>
diff --git a/tests/integration/microprofile/rest-client-tck/pom.xml b/tests/integration/microprofile/rest-client-tck/pom.xml
index 496f1ca..b2a326f 100644
--- a/tests/integration/microprofile/rest-client-tck/pom.xml
+++ b/tests/integration/microprofile/rest-client-tck/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>microprofile-integration-project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration.microprofile</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -50,11 +50,11 @@
             <artifactId>weld-se-core</artifactId>
             <scope>test</scope>
         </dependency>
-        <!--<dependency>
+        <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
             <version>4.0.1</version>
-        </dependency>-->
+        </dependency>
         <dependency>
             <groupId>io.smallrye.config</groupId>
             <artifactId>smallrye-config</artifactId>
@@ -190,7 +190,7 @@
                     <name>skipTests</name>
                     <value>!true</value>
                 </property>
-                <jdk>[11,)</jdk>
+                <jdk>[17,)</jdk>
             </activation>
             <build>
                 <plugins>
diff --git a/tests/integration/microprofile/rest-client/pom.xml b/tests/integration/microprofile/rest-client/pom.xml
index 9aa1fef..55d9354 100644
--- a/tests/integration/microprofile/rest-client/pom.xml
+++ b/tests/integration/microprofile/rest-client/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>microprofile-integration-project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration.microprofile</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml
index 4a5c0f2..f59ed79 100644
--- a/tests/integration/pom.xml
+++ b/tests/integration/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.tests.integration</groupId>
@@ -58,30 +58,27 @@
         <module>jersey-4542</module>
         <module>jersey-4697</module>
         <module>jersey-4722</module>
-        <module>microprofile</module>
-        <module>reactive-streams</module>
         <module>jersey-5087</module>
+        <module>microprofile</module>
+        <module>property-check</module>
+        <module>reactive-streams</module>
+        <module>servlet-2.5-reload</module>
+        <module>servlet-3-gf-async</module>
+        <module>servlet-3-sse-1</module>
+        <!--        <module>spring4</module>-->
+        <!--        <module>spring5</module>-->
+        <module>thin-server</module>
     </modules>
 
+    <properties>
+        <env>default</env>
+        <jersey.config.test.container.port>9998</jersey.config.test.container.port>
+        <jetty.log.file>${project.build.directory}/jetty-out.log</jetty.log.file>
+    </properties>
+
     <profiles>
         <profile>
-            <id>default</id>
-            <properties>
-                <env>default</env>
-                <jersey.config.test.container.port>9998</jersey.config.test.container.port>
-            </properties>
-            <activation>
-                <jdk>[1.8,)</jdk>
-<!--                <activeByDefault>true</activeByDefault> does not work ?!-->
-            </activation>
-        </profile>
-        <profile>
             <id>sonar</id>
-            <properties>
-                <env>default</env>
-                <jersey.config.test.container.port>9998</jersey.config.test.container.port>
-                <jetty.log.file>${project.build.directory}/jetty-out.log</jetty.log.file>
-            </properties>
             <build>
                 <pluginManagement>
                     <plugins>
@@ -123,9 +120,9 @@
             </build>
         </profile>
         <profile>
-            <id>Jetty11</id>
+            <id>jdk17</id>
             <activation>
-                <jdk>[11,)</jdk>
+                <jdk>[17,)</jdk>
             </activation>
             <modules>
                 <module>async-jersey-filter</module>
@@ -136,7 +133,6 @@
                 <module>jersey-1223</module>
                 <module>jersey-1604</module>
                 <module>jersey-1667</module>
-<!--                <module>jersey-1829</module> Jakartification-->
                 <module>jersey-1883</module>
                 <module>jersey-1928</module>
                 <module>jersey-1960</module>
@@ -163,7 +159,6 @@
                 <module>jersey-2892</module>
                 <module>jersey-3796</module>
                 <module>jersey-4949</module>
-                <module>property-check</module>
                 <module>security-digest</module>
                 <module>servlet-2.5-autodiscovery-1</module>
                 <module>servlet-2.5-autodiscovery-2</module>
@@ -180,11 +175,9 @@
                 <module>servlet-2.5-mvc-1</module>
                 <module>servlet-2.5-mvc-2</module>
                 <module>servlet-2.5-mvc-3</module>
-                <module>servlet-2.5-reload</module>
                 <module>servlet-3-async</module>
                 <module>servlet-3-chunked-io</module>
                 <module>servlet-3-filter</module>
-                <module>servlet-3-gf-async</module>
                 <module>servlet-3-inflector-1</module>
                 <module>servlet-3-init-1</module>
                 <module>servlet-3-init-2</module>
@@ -197,22 +190,13 @@
                 <module>servlet-3-init-9</module>
                 <module>servlet-3-init-provider</module>
                 <module>servlet-3-params</module>
-                <module>servlet-3-sse-1</module>
                 <module>servlet-4.0-mvc-1</module>
                 <module>servlet-tests</module>
                 <module>servlet-request-wrapper-binding</module>
                 <module>servlet-request-wrapper-binding-2</module>
                 <module>sonar-test</module>
-                <module>tracing-support</module>
-            </modules>
-        </profile>
-        <profile>
-            <id>spring6-jdk17</id>
-            <activation>
-                <jdk>[17,)</jdk>
-            </activation>
-            <modules>
                 <module>spring6</module>
+                <module>tracing-support</module>
             </modules>
         </profile>
     </profiles>
@@ -262,8 +246,8 @@
                     </executions>
                 </plugin>
                 <plugin>
-                    <groupId>org.eclipse.jetty</groupId>
-                    <artifactId>jetty-maven-plugin</artifactId>
+                    <groupId>org.eclipse.jetty.ee9</groupId>
+                    <artifactId>jetty-ee9-maven-plugin</artifactId>
                     <version>${jetty.plugin.version}</version>
                     <configuration>
                         <skip>${skip.tests}</skip>
@@ -286,9 +270,45 @@
                             <goals>
                                 <goal>start</goal>
                             </goals>
-                            <configuration>
-                                <scanIntervalSeconds>0</scanIntervalSeconds>
-                            </configuration>
+                        </execution>
+                        <execution>
+                            <id>stop-jetty</id>
+                            <phase>post-integration-test</phase>
+                            <goals>
+                                <goal>stop</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.eclipse.jetty.ee10</groupId>
+                    <artifactId>jetty-ee10-maven-plugin</artifactId>
+                    <version>${jetty.plugin.version}</version>
+                    <configuration>
+                        <skip>${skip.tests}</skip>
+                        <stopPort>9999</stopPort>
+                        <stopKey>STOP</stopKey>
+                        <stopWait>10</stopWait>
+                        <webApp>
+                            <contextPath>/</contextPath>
+                            <webInfIncludeJarPattern>.*/.*jersey-[^/]\.jar$</webInfIncludeJarPattern>
+                        </webApp>
+                        <httpConnector>
+                            <port>${jersey.config.test.container.port}</port>
+                            <idleTimeout>60000</idleTimeout>
+                        </httpConnector>
+                        <systemProperties>
+                            <PORT>${jersey.config.test.container.port}</PORT>
+                            <IDLE_TIMEOUT>60000</IDLE_TIMEOUT>
+                        </systemProperties>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <id>start-jetty</id>
+                            <phase>pre-integration-test</phase>
+                            <goals>
+                                <goal>start</goal>
+                            </goals>
                         </execution>
                         <execution>
                             <id>stop-jetty</id>
diff --git a/tests/integration/property-check/pom.xml b/tests/integration/property-check/pom.xml
index df52904..3556251 100644
--- a/tests/integration/property-check/pom.xml
+++ b/tests/integration/property-check/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>property-check</artifactId>
diff --git a/tests/integration/reactive-streams/pom.xml b/tests/integration/reactive-streams/pom.xml
index 8a4170c..0882880 100644
--- a/tests/integration/reactive-streams/pom.xml
+++ b/tests/integration/reactive-streams/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>pom</packaging>
diff --git a/tests/integration/reactive-streams/sse/pom.xml b/tests/integration/reactive-streams/sse/pom.xml
index 8e077ed..228561f 100644
--- a/tests/integration/reactive-streams/sse/pom.xml
+++ b/tests/integration/reactive-streams/sse/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <artifactId>reactive-streams-integration-project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration.reactive</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/integration/security-digest/pom.xml b/tests/integration/security-digest/pom.xml
index 35e3336..0de0655 100644
--- a/tests/integration/security-digest/pom.xml
+++ b/tests/integration/security-digest/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>security-digest</artifactId>
@@ -58,15 +58,20 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
 
                 <configuration>
+                    <webApp>
+                        <parentLoaderPriority>true</parentLoaderPriority>
+                    </webApp>
                     <!-- define login service for jetty and the realm to be used -->
                     <loginServices>
                         <loginService implementation="org.eclipse.jetty.security.HashLoginService">
                             <name>my-realm</name>
-                            <config>${basedir}/src/main/resources/jetty/realm.properties</config>
+                            <config implementation="org.eclipse.jetty.ee10.maven.plugin.MavenResource">
+                                <resourceAsString>${basedir}/src/main/resources/jetty/realm.properties</resourceAsString>
+                            </config>
                         </loginService>
                     </loginServices>
                 </configuration>
diff --git a/tests/integration/servlet-2.5-autodiscovery-1/pom.xml b/tests/integration/servlet-2.5-autodiscovery-1/pom.xml
index 07dfe06..98c1fff 100644
--- a/tests/integration/servlet-2.5-autodiscovery-1/pom.xml
+++ b/tests/integration/servlet-2.5-autodiscovery-1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-autodiscovery-1</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-autodiscovery-2/pom.xml b/tests/integration/servlet-2.5-autodiscovery-2/pom.xml
index 73c2778..ebfda2d 100644
--- a/tests/integration/servlet-2.5-autodiscovery-2/pom.xml
+++ b/tests/integration/servlet-2.5-autodiscovery-2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-autodiscovery-2</artifactId>
@@ -67,8 +67,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-filter/pom.xml b/tests/integration/servlet-2.5-filter/pom.xml
index 8420c45..0f16723 100644
--- a/tests/integration/servlet-2.5-filter/pom.xml
+++ b/tests/integration/servlet-2.5-filter/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-filter</artifactId>
@@ -60,8 +60,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-inflector-1/pom.xml b/tests/integration/servlet-2.5-inflector-1/pom.xml
index 0e6bfae..ed1c161 100644
--- a/tests/integration/servlet-2.5-inflector-1/pom.xml
+++ b/tests/integration/servlet-2.5-inflector-1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-inflector-1</artifactId>
@@ -43,7 +43,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -65,8 +64,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-init-1/pom.xml b/tests/integration/servlet-2.5-init-1/pom.xml
index 3495b3b..72fcdde 100644
--- a/tests/integration/servlet-2.5-init-1/pom.xml
+++ b/tests/integration/servlet-2.5-init-1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-init-1</artifactId>
@@ -36,7 +36,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -63,8 +62,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-init-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_init_1/Servlet25Init1ITCase.java b/tests/integration/servlet-2.5-init-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_init_1/Servlet25Init1ITCase.java
index c44f34a..d3c0e0e 100644
--- a/tests/integration/servlet-2.5-init-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_init_1/Servlet25Init1ITCase.java
+++ b/tests/integration/servlet-2.5-init-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_init_1/Servlet25Init1ITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -87,7 +87,7 @@
     @Test
     public void testInjection() {
         String s = target().path("servlet_path/helloworld/injection").request().get(String.class);
-        assertEquals("GETtruetestServlet1testServlet1/", s);
+        assertEquals("GETtruetestServlet1testServlet1ROOT", s);
     }
 
     // Reproducer for JERSEY-1801
diff --git a/tests/integration/servlet-2.5-init-2/pom.xml b/tests/integration/servlet-2.5-init-2/pom.xml
index 838084a..813ba49 100644
--- a/tests/integration/servlet-2.5-init-2/pom.xml
+++ b/tests/integration/servlet-2.5-init-2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-init-2</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-init-3/pom.xml b/tests/integration/servlet-2.5-init-3/pom.xml
index a258bbd..cad9526 100644
--- a/tests/integration/servlet-2.5-init-3/pom.xml
+++ b/tests/integration/servlet-2.5-init-3/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-init-3</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-init-4/pom.xml b/tests/integration/servlet-2.5-init-4/pom.xml
index f90f731..fdc1410 100644
--- a/tests/integration/servlet-2.5-init-4/pom.xml
+++ b/tests/integration/servlet-2.5-init-4/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-init-4</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-init-5/pom.xml b/tests/integration/servlet-2.5-init-5/pom.xml
index 9a7e50d..35b5618 100644
--- a/tests/integration/servlet-2.5-init-5/pom.xml
+++ b/tests/integration/servlet-2.5-init-5/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-init-5</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-init-6/pom.xml b/tests/integration/servlet-2.5-init-6/pom.xml
index e3f9041..0870ccb 100644
--- a/tests/integration/servlet-2.5-init-6/pom.xml
+++ b/tests/integration/servlet-2.5-init-6/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-init-6</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-init-7/pom.xml b/tests/integration/servlet-2.5-init-7/pom.xml
index c27e43a..bfeb54d 100644
--- a/tests/integration/servlet-2.5-init-7/pom.xml
+++ b/tests/integration/servlet-2.5-init-7/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-init-7</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-init-8/pom.xml b/tests/integration/servlet-2.5-init-8/pom.xml
index f22b922..f7dc189 100644
--- a/tests/integration/servlet-2.5-init-8/pom.xml
+++ b/tests/integration/servlet-2.5-init-8/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-init-8</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-mvc-1/pom.xml b/tests/integration/servlet-2.5-mvc-1/pom.xml
index 947d89c..0009436 100644
--- a/tests/integration/servlet-2.5-mvc-1/pom.xml
+++ b/tests/integration/servlet-2.5-mvc-1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-mvc-1</artifactId>
@@ -57,7 +57,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -78,8 +77,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee9</groupId>
+                <artifactId>jetty-ee9-maven-plugin</artifactId>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
diff --git a/tests/integration/servlet-2.5-mvc-2/pom.xml b/tests/integration/servlet-2.5-mvc-2/pom.xml
index b7e57c7..fb26eaf 100644
--- a/tests/integration/servlet-2.5-mvc-2/pom.xml
+++ b/tests/integration/servlet-2.5-mvc-2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-mvc-2</artifactId>
@@ -57,7 +57,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -78,8 +77,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-2.5-mvc-3/pom.xml b/tests/integration/servlet-2.5-mvc-3/pom.xml
index fc449a2..57074de 100644
--- a/tests/integration/servlet-2.5-mvc-3/pom.xml
+++ b/tests/integration/servlet-2.5-mvc-3/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-mvc-3</artifactId>
@@ -57,7 +57,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -78,8 +77,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee9</groupId>
+                <artifactId>jetty-ee9-maven-plugin</artifactId>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
diff --git a/tests/integration/servlet-2.5-reload/pom.xml b/tests/integration/servlet-2.5-reload/pom.xml
index 34295e2..a359015 100644
--- a/tests/integration/servlet-2.5-reload/pom.xml
+++ b/tests/integration/servlet-2.5-reload/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-2.5-reload</artifactId>
diff --git a/tests/integration/servlet-3-async/pom.xml b/tests/integration/servlet-3-async/pom.xml
index 0a1ec76..f27c3e2 100644
--- a/tests/integration/servlet-3-async/pom.xml
+++ b/tests/integration/servlet-3-async/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-async</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-chunked-io/pom.xml b/tests/integration/servlet-3-chunked-io/pom.xml
index 4c5e676..e16f934 100644
--- a/tests/integration/servlet-3-chunked-io/pom.xml
+++ b/tests/integration/servlet-3-chunked-io/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-chunked-io</artifactId>
@@ -65,8 +65,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-filter/pom.xml b/tests/integration/servlet-3-filter/pom.xml
index 924c436..410dff6 100644
--- a/tests/integration/servlet-3-filter/pom.xml
+++ b/tests/integration/servlet-3-filter/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-filter</artifactId>
@@ -61,8 +61,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-gf-async/pom.xml b/tests/integration/servlet-3-gf-async/pom.xml
index ebf67ea..221dcc3 100644
--- a/tests/integration/servlet-3-gf-async/pom.xml
+++ b/tests/integration/servlet-3-gf-async/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-gf-async</artifactId>
diff --git a/tests/integration/servlet-3-inflector-1/pom.xml b/tests/integration/servlet-3-inflector-1/pom.xml
index d8d6be0..88f8b3e 100644
--- a/tests/integration/servlet-3-inflector-1/pom.xml
+++ b/tests/integration/servlet-3-inflector-1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-inflector-1</artifactId>
@@ -43,7 +43,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -65,8 +64,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-1/pom.xml b/tests/integration/servlet-3-init-1/pom.xml
index 33320eb..d9cf871 100644
--- a/tests/integration/servlet-3-init-1/pom.xml
+++ b/tests/integration/servlet-3-init-1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-1</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-2/pom.xml b/tests/integration/servlet-3-init-2/pom.xml
index 3333c4f..26bbbea 100644
--- a/tests/integration/servlet-3-init-2/pom.xml
+++ b/tests/integration/servlet-3-init-2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-2</artifactId>
@@ -64,8 +64,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-3/pom.xml b/tests/integration/servlet-3-init-3/pom.xml
index ee52d61..4344768 100644
--- a/tests/integration/servlet-3-init-3/pom.xml
+++ b/tests/integration/servlet-3-init-3/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-3</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-4/pom.xml b/tests/integration/servlet-3-init-4/pom.xml
index 3f6f092..6c836c3 100644
--- a/tests/integration/servlet-3-init-4/pom.xml
+++ b/tests/integration/servlet-3-init-4/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-4</artifactId>
@@ -59,8 +59,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-5/pom.xml b/tests/integration/servlet-3-init-5/pom.xml
index 9d3f75c..5cd699b 100644
--- a/tests/integration/servlet-3-init-5/pom.xml
+++ b/tests/integration/servlet-3-init-5/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-5</artifactId>
@@ -56,8 +56,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-6/pom.xml b/tests/integration/servlet-3-init-6/pom.xml
index 110d574..0399614 100644
--- a/tests/integration/servlet-3-init-6/pom.xml
+++ b/tests/integration/servlet-3-init-6/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-6</artifactId>
@@ -57,8 +57,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-7/pom.xml b/tests/integration/servlet-3-init-7/pom.xml
index 30e5bac..ba2db59 100644
--- a/tests/integration/servlet-3-init-7/pom.xml
+++ b/tests/integration/servlet-3-init-7/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-7</artifactId>
@@ -58,8 +58,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-8/pom.xml b/tests/integration/servlet-3-init-8/pom.xml
index cc128c2..b6ac348 100644
--- a/tests/integration/servlet-3-init-8/pom.xml
+++ b/tests/integration/servlet-3-init-8/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-8</artifactId>
@@ -58,8 +58,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-9/pom.xml b/tests/integration/servlet-3-init-9/pom.xml
index 68ee240..aaba59f 100644
--- a/tests/integration/servlet-3-init-9/pom.xml
+++ b/tests/integration/servlet-3-init-9/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-9</artifactId>
@@ -42,7 +42,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -64,8 +63,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-init-provider/pom.xml b/tests/integration/servlet-3-init-provider/pom.xml
index 634957e..0aeedc3 100644
--- a/tests/integration/servlet-3-init-provider/pom.xml
+++ b/tests/integration/servlet-3-init-provider/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-init-provider</artifactId>
@@ -40,7 +40,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -68,8 +67,8 @@
                 </configuration>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-params/pom.xml b/tests/integration/servlet-3-params/pom.xml
index 11eadb7..a1d5315 100644
--- a/tests/integration/servlet-3-params/pom.xml
+++ b/tests/integration/servlet-3-params/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-params</artifactId>
@@ -40,7 +40,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -62,8 +61,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-3-sse-1/pom.xml b/tests/integration/servlet-3-sse-1/pom.xml
index 3324c59..94645f6 100644
--- a/tests/integration/servlet-3-sse-1/pom.xml
+++ b/tests/integration/servlet-3-sse-1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-3-sse-1</artifactId>
diff --git a/tests/integration/servlet-4.0-mvc-1/pom.xml b/tests/integration/servlet-4.0-mvc-1/pom.xml
index b864a7c..3bc56bc 100644
--- a/tests/integration/servlet-4.0-mvc-1/pom.xml
+++ b/tests/integration/servlet-4.0-mvc-1/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-4.0-mvc-1</artifactId>
@@ -49,7 +49,14 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.xml.bind</groupId>
+            <artifactId>jakarta.xml.bind-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-osgi</artifactId>
         </dependency>
 
         <dependency>
@@ -75,14 +82,13 @@
                 </configuration>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
-                <!--TODO jakartify this -->
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
                 <dependencies>
                     <dependency>
                         <groupId>jakarta.servlet</groupId>
                         <artifactId>jakarta.servlet-api</artifactId>
-                        <version>${servlet5.version}</version>
+                        <version>${servlet6.version}</version>
                     </dependency>
                 </dependencies>
                 <configuration>
@@ -91,24 +97,4 @@
             </plugin>
         </plugins>
     </build>
-
-    <profiles>
-        <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>jakarta.xml.bind</groupId>
-                    <artifactId>jakarta.xml.bind-api</artifactId>
-                </dependency>
-                <dependency>
-                    <groupId>com.sun.xml.bind</groupId>
-                    <artifactId>jaxb-osgi</artifactId>
-                </dependency>
-            </dependencies>
-        </profile>
-    </profiles>
-
 </project>
diff --git a/tests/integration/servlet-request-wrapper-binding-2/pom.xml b/tests/integration/servlet-request-wrapper-binding-2/pom.xml
index 2bc9be8..245cc82 100644
--- a/tests/integration/servlet-request-wrapper-binding-2/pom.xml
+++ b/tests/integration/servlet-request-wrapper-binding-2/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-request-wrappper-binding-2</artifactId>
@@ -40,7 +40,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -68,8 +68,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-request-wrapper-binding-2/src/main/java/org/glassfish/jersey/tests/integration/servlet_request_wrapper_binding2/RequestResponseWrapperProvider.java b/tests/integration/servlet-request-wrapper-binding-2/src/main/java/org/glassfish/jersey/tests/integration/servlet_request_wrapper_binding2/RequestResponseWrapperProvider.java
index 86017ec..e152f64 100644
--- a/tests/integration/servlet-request-wrapper-binding-2/src/main/java/org/glassfish/jersey/tests/integration/servlet_request_wrapper_binding2/RequestResponseWrapperProvider.java
+++ b/tests/integration/servlet-request-wrapper-binding-2/src/main/java/org/glassfish/jersey/tests/integration/servlet_request_wrapper_binding2/RequestResponseWrapperProvider.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2022 Contributors to the Eclipse Foundation
  * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -39,6 +40,7 @@
 import jakarta.servlet.AsyncContext;
 import jakarta.servlet.DispatcherType;
 import jakarta.servlet.RequestDispatcher;
+import jakarta.servlet.ServletConnection;
 import jakarta.servlet.ServletContext;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.ServletInputStream;
@@ -291,16 +293,6 @@
                 }
 
                 @Override
-                public String encodeUrl(String s) {
-                    return getHttpServletResponse().encodeUrl(s);
-                }
-
-                @Override
-                public String encodeRedirectUrl(String s) {
-                    return getHttpServletResponse().encodeRedirectUrl(s);
-                }
-
-                @Override
                 public void sendError(int i, String s) throws IOException {
                     getHttpServletResponse().sendError(i, s);
                 }
@@ -330,14 +322,17 @@
                     getHttpServletResponse().setHeader(h, v);
                 }
 
+                @Override
                 public Collection<String> getHeaderNames() {
                     return getHttpServletResponse().getHeaderNames();
                 }
 
+                @Override
                 public Collection<String> getHeaders(String s) {
                     return getHttpServletResponse().getHeaders(s);
                 }
 
+                @Override
                 public String getHeader(String s) {
                     return getHttpServletResponse().getHeader(s);
                 }
@@ -368,11 +363,6 @@
                 }
 
                 @Override
-                public void setStatus(int i, String s) {
-                    getHttpServletResponse().setStatus(i, s);
-                }
-
-                @Override
                 public String getCharacterEncoding() {
                     return getHttpServletResponse().getCharacterEncoding();
                 }
@@ -501,6 +491,22 @@
     private abstract static class MyHttpServletRequestImpl implements HttpServletRequest {
 
         @Override
+        public String getRequestId() {
+            return getHttpServletRequest().getRequestId();
+        }
+
+        @Override
+        public String getProtocolRequestId() {
+            return getHttpServletRequest().getProtocolRequestId();
+        }
+
+        @Override
+        public ServletConnection getServletConnection() {
+            return getHttpServletRequest().getServletConnection();
+        }
+
+
+        @Override
         public String getAuthType() {
             return getHttpServletRequest().getAuthType();
         }
@@ -658,11 +664,6 @@
         }
 
         @Override
-        public boolean isRequestedSessionIdFromUrl() {
-            return getHttpServletRequest().isRequestedSessionIdFromUrl();
-        }
-
-        @Override
         public Object getAttribute(String s) {
             return getHttpServletRequest().getAttribute(s);
         }
@@ -783,11 +784,6 @@
         }
 
         @Override
-        public String getRealPath(String s) {
-            return getHttpServletRequest().getRealPath(s);
-        }
-
-        @Override
         public int getRemotePort() {
             return getHttpServletRequest().getRemotePort();
         }
diff --git a/tests/integration/servlet-request-wrapper-binding/pom.xml b/tests/integration/servlet-request-wrapper-binding/pom.xml
index cdcee28..7c22226 100644
--- a/tests/integration/servlet-request-wrapper-binding/pom.xml
+++ b/tests/integration/servlet-request-wrapper-binding/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-request-wrappper-binding</artifactId>
@@ -40,7 +40,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -68,8 +67,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/servlet-tests/pom.xml b/tests/integration/servlet-tests/pom.xml
index 5363e82..6a002e0 100644
--- a/tests/integration/servlet-tests/pom.xml
+++ b/tests/integration/servlet-tests/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>servlet-tests</artifactId>
@@ -36,7 +36,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -62,8 +62,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-              <groupId>org.eclipse.jetty</groupId>
-              <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/sonar-test/pom.xml b/tests/integration/sonar-test/pom.xml
index 7895b97..bb68319 100644
--- a/tests/integration/sonar-test/pom.xml
+++ b/tests/integration/sonar-test/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>sonar-test</artifactId>
@@ -58,8 +58,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
diff --git a/tests/integration/spring6/pom.xml b/tests/integration/spring6/pom.xml
index 43a6859..9c005c2 100644
--- a/tests/integration/spring6/pom.xml
+++ b/tests/integration/spring6/pom.xml
@@ -25,7 +25,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>spring6</artifactId>
@@ -50,7 +50,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -133,9 +133,8 @@
                 <artifactId>maven-failsafe-plugin</artifactId>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
-                <version>11.0.14</version>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
                 <configuration>
                     <webApp>
                         <contextPath>/</contextPath>
diff --git a/tests/integration/thin-server/pom.xml b/tests/integration/thin-server/pom.xml
new file mode 100644
index 0000000..d4cbaa8
--- /dev/null
+++ b/tests/integration/thin-server/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>project</artifactId>
+        <groupId>org.glassfish.jersey.tests.integration</groupId>
+        <version>3.1.99-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>thin-server</artifactId>
+    <name>jersey-thin-server</name>
+    <description>
+        Run server without HTTP stack in tests.
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-server</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework</groupId>
+            <artifactId>jersey-test-framework-util</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java b/tests/integration/thin-server/src/main/java/org.glassfish.jersey.integration.thinserver/ThinServerResource.java
similarity index 65%
rename from core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
rename to tests/integration/thin-server/src/main/java/org.glassfish.jersey.integration.thinserver/ThinServerResource.java
index dd25372..9cb3cb7 100644
--- a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
+++ b/tests/integration/thin-server/src/main/java/org.glassfish.jersey.integration.thinserver/ThinServerResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,16 @@
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
 
-package org.glassfish.jersey.internal.jsr166;
+package org.glassfish.jersey.integration.thinserver;
 
-public interface JerseyFlowSubscriber<T> extends Flow.Subscriber<T> {
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+
+@Path("/")
+public class ThinServerResource {
+    @GET
+    @Path("someget")
+    public String get() {
+        return ThinServerResource.class.getName();
+    }
 }
diff --git a/tests/integration/thin-server/src/test/java/org/glassfish/jersey/integration/thinserver/ThinServerTest.java b/tests/integration/thin-server/src/test/java/org/glassfish/jersey/integration/thinserver/ThinServerTest.java
new file mode 100644
index 0000000..d3b9916
--- /dev/null
+++ b/tests/integration/thin-server/src/test/java/org/glassfish/jersey/integration/thinserver/ThinServerTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.integration.thinserver;
+
+import jakarta.ws.rs.HttpMethod;
+import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.message.internal.OutboundJaxrsResponse;
+import org.glassfish.jersey.message.internal.OutboundMessageContext;
+import org.glassfish.jersey.server.ApplicationHandler;
+import org.glassfish.jersey.server.ContainerRequest;
+import org.glassfish.jersey.server.ContainerResponse;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.util.server.ContainerRequestBuilder;
+import org.junit.jupiter.api.Test;
+
+import java.net.URI;
+import java.util.concurrent.ExecutionException;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ThinServerTest {
+    @Test
+    public void testGet() throws ExecutionException, InterruptedException {
+        ContainerRequest request =
+                ContainerRequestBuilder.from(URI.create("/someget"), HttpMethod.GET, new ClientConfig()).build();
+
+        ApplicationHandler applicationHandler = new ApplicationHandler(new ResourceConfig(ThinServerResource.class));
+        ContainerResponse containerResponse = applicationHandler.apply(request).get();
+        OutboundMessageContext outboundMessageContext = containerResponse.getWrappedMessageContext();
+        Response response = new OutboundJaxrsResponse(containerResponse.getStatusInfo(), outboundMessageContext);
+        assertEquals(ThinServerResource.class.getName(), response.getEntity());
+    }
+}
diff --git a/tests/integration/tracing-support/pom.xml b/tests/integration/tracing-support/pom.xml
index 192f52d..1e1b03a 100644
--- a/tests/integration/tracing-support/pom.xml
+++ b/tests/integration/tracing-support/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>tracing-support</artifactId>
@@ -63,15 +63,16 @@
                 </configuration>
             </plugin>
             <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
-                <version>${jetty.tracing.version}</version>
+                <groupId>org.eclipse.jetty.ee10</groupId>
+                <artifactId>jetty-ee10-maven-plugin</artifactId>
                 <configuration>
-                    <connectors>
-                        <connector>
-                            <responseHeaderSize>16192</responseHeaderSize>
-                        </connector>
-                    </connectors>
+                    <httpConnector combine.self="override"/>
+                    <jettyXmls>
+                        <jettyXml>${basedir}/src/test/resources/jetty.xml</jettyXml>
+                    </jettyXmls>
+                    <systemProperties>
+                        <RESPONSE_HEADER_SIZE>16192</RESPONSE_HEADER_SIZE>
+                    </systemProperties>
                     <!-- server side config does not fork with jetty:run goal - it uses same jvm
                          use maven '-D' option instead:
                              mvn _goal_ -Djava.util.logging.config.file=target/test-classes/logging.properties
diff --git a/tests/integration/tracing-support/src/test/resources/jetty.xml b/tests/integration/tracing-support/src/test/resources/jetty.xml
new file mode 100644
index 0000000..dc8582c
--- /dev/null
+++ b/tests/integration/tracing-support/src/test/resources/jetty.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+
+    Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+    <New id="HttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
+        <Set name="responseHeaderSize"><SystemProperty name="RESPONSE_HEADER_SIZE"/></Set>
+    </New>
+
+    <Call name="addConnector">
+        <Arg>
+            <New class="org.eclipse.jetty.server.ServerConnector">
+                <Arg name="server"><Ref refid="Server" /></Arg>
+                <Arg name="factories">
+                    <Array type="org.eclipse.jetty.server.ConnectionFactory">
+                        <Item>
+                            <New class="org.eclipse.jetty.server.HttpConnectionFactory">
+                                <Arg name="config"><Ref refid="HttpConfig" /></Arg>
+                            </New>
+                        </Item>
+                    </Array>
+                </Arg>
+                <Set name="port"><SystemProperty name="PORT"/></Set>
+                <Set name="idleTimeout"><SystemProperty name="IDLE_TIMEOUT"/></Set>
+            </New>
+        </Arg>
+    </Call>
+</Configure>
\ No newline at end of file
diff --git a/tests/jersey-tck/README.md b/tests/jersey-tck/README.md
new file mode 100644
index 0000000..2457e01
--- /dev/null
+++ b/tests/jersey-tck/README.md
@@ -0,0 +1,15 @@
+# Jakarta REST TCK
+
+The **Jakarta REST TCK** is a standalone kit for testing compliance of an implementation with the Jakarta REST specification.
+
+
+## Performing Test
+
+While the test kit *is not dependent* of Maven, the most easy way to perform the tests is to create a copy of the sample Maven project found in the `jersey-tck` folder and adjust it to the actual needs of the implementation to be actually tested:
+* Replace the dependency to Jersey by a dependency to the implementation to be actually tested.
+* Execute `mvn verify`.
+* Find the test result as part of Maven's output on the console or refer to the surefire reports.
+
+**Note:** Certainly the same can be performed using *other* build tools, like Gradle, or even by running a standalone Jupiter API compatible test runner (e. g. JUnit 5 Console Runner), as long as the Jakarta REST TCK JAR file and the implementation to test are both found on the classpath.
+
+**Hint:** The test project can safely get stored as part of the implementation, so it can be easily executed as part of the QA process.
diff --git a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties b/tests/jersey-tck/j2ee.pass
similarity index 75%
copy from test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
copy to tests/jersey-tck/j2ee.pass
index 2886c72..7cd0e34 100644
--- a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
+++ b/tests/jersey-tck/j2ee.pass
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
 #
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License v. 2.0, which is available at
@@ -13,6 +13,4 @@
 #
 # SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 #
-
-# {0} - status code; {1} - status reason message
-not.supported=Jetty container is not supported on JDK version less than 11.
+AS_ADMIN_USERPASSWORD=j2ee
\ No newline at end of file
diff --git a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties b/tests/jersey-tck/javajoe.pass
similarity index 75%
copy from test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
copy to tests/jersey-tck/javajoe.pass
index 2886c72..f06be72 100644
--- a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
+++ b/tests/jersey-tck/javajoe.pass
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
 #
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License v. 2.0, which is available at
@@ -13,6 +13,4 @@
 #
 # SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 #
-
-# {0} - status code; {1} - status reason message
-not.supported=Jetty container is not supported on JDK version less than 11.
+AS_ADMIN_USERPASSWORD=javajoe
\ No newline at end of file
diff --git a/tests/jersey-tck/pom.xml b/tests/jersey-tck/pom.xml
new file mode 100644
index 0000000..0cd9ffd
--- /dev/null
+++ b/tests/jersey-tck/pom.xml
@@ -0,0 +1,545 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+
+    Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.glassfish.jersey.core</groupId>
+    <artifactId>jersey-tck</artifactId>
+    <version>3.1.0</version>
+    <packaging>jar</packaging>
+
+    <name>Jakarta RESTful WS Compliance for Jersey</name>
+    <description>This test verifies the compliance of Eclipse Jersey with Jakarta REST</description>
+
+    <properties>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+        <jersey.version>3.1.2</jersey.version> <!-- the public version that pass the tck -->
+        <glassfish.container.version>7.0.4</glassfish.container.version>
+        <glassfish.home>${project.build.directory}/glassfish7</glassfish.home>
+        <jakarta.platform.version>10.0.0</jakarta.platform.version>
+        <junit.jupiter.version>5.7.2</junit.jupiter.version>
+        <jakarta.rest.version>3.1.0</jakarta.rest.version>
+        <tck.artifactId>jakarta-restful-ws-tck</tck.artifactId>
+        <tck.version>3.1.3</tck.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.junit</groupId>
+                <artifactId>junit-bom</artifactId>
+                <version>${junit.jupiter.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jersey</groupId>
+                <artifactId>jersey-bom</artifactId>
+                <version>${jersey.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <repositories>
+        <repository>
+            <id>jakarta-snapshots</id>
+            <url>https://jakarta.oss.sonatype.org/content/repositories/staging/</url>
+        </repository>
+    </repositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>${junit.jupiter.version}</version>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.glassfish.hk2</groupId>
+            <artifactId>hk2-locator</artifactId>
+            <version>3.0.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-impl</artifactId>
+            <version>3.0.0</version>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.arquillian.container</groupId>
+            <artifactId>arquillian-glassfish-managed-6</artifactId>
+            <version>1.0.0.Alpha1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>jakarta.ws.rs</groupId>
+            <artifactId>${tck.artifactId}</artifactId>
+            <version>${tck.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>jakarta.ws.rs</groupId>
+            <artifactId>jakarta.ws.rs-api</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <version>2.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>simple-glassfish-api</artifactId>
+            <version>${glassfish.container.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.arquillian.junit5</groupId>
+            <artifactId>arquillian-junit5-container</artifactId>
+            <version>1.7.0.Alpha10</version>
+        </dependency>
+
+        <dependency>
+            <groupId>jakarta.platform</groupId>
+            <artifactId>jakarta.jakartaee-api</artifactId>
+            <version>${jakarta.platform.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-httpclient</groupId>
+            <artifactId>commons-httpclient</artifactId>
+            <version>3.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-server</artifactId>
+            <version>${jersey.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-grizzly2-http</artifactId>
+            <version>${jersey.version}</version>
+            <scope>test</scope>
+        </dependency> 
+        <dependency>
+            <groupId>org.netbeans.tools</groupId>
+            <artifactId>sigtest-maven-plugin</artifactId>
+            <version>1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-json-binding</artifactId>
+            <version>${jersey.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-jaxb</artifactId>
+            <version>${jersey.version}</version>
+            <scope>test</scope>
+        </dependency>
+       <dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-sse</artifactId>
+            <version>${jersey.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+
+    <build>	    
+    <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>3.2.0</version>
+                <executions>
+                    <execution>
+                        <id>unpack</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>unpack</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>org.glassfish.main.distributions</groupId>
+                                    <artifactId>glassfish</artifactId>
+                                    <version>${glassfish.container.version}</version>
+                                    <type>zip</type>
+                                    <overWrite>false</overWrite>
+                                    <outputDirectory>${project.build.directory}</outputDirectory>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>copy</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.core</groupId>
+                                    <artifactId>jersey-client</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${glassfish.home}/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-client.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.core</groupId>
+                                    <artifactId>jersey-server</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${glassfish.home}/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-server.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.core</groupId>
+                                    <artifactId>jersey-common</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${glassfish.home}/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-common.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.containers</groupId>
+                                    <artifactId>jersey-container-grizzly2-http</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${glassfish.home}/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-container-grizzly2-http.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.containers</groupId>
+                                    <artifactId>jersey-container-servlet-core</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${glassfish.home}/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-container-servlet-core.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.containers</groupId>
+                                    <artifactId>jersey-container-servlet</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${glassfish.home}/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-container-servlet.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.media</groupId>
+                                    <artifactId>jersey-media-sse</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${glassfish.home}/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-media-sse.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.media</groupId>
+                                    <artifactId>jersey-media-json-binding</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${glassfish.home}/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-media-json-binding.jar</destFileName>
+                                </artifactItem>
+                                 <artifactItem>
+                                    <groupId>jakarta.ws.rs</groupId>
+                                    <artifactId>jakarta.ws.rs-api</artifactId>
+                                    <version>${jakarta.rest.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${glassfish.home}/glassfish/modules</outputDirectory>
+                                    <destFileName>jakarta.ws.rs-api.jar</destFileName>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>exec-maven-plugin</artifactId>
+                <groupId>org.codehaus.mojo</groupId>
+                <executions>
+                    <execution>
+                        <id>StopDomain1</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${asadmin.home}</workingDirectory>
+                            <executable>${asadmin}</executable>
+                            <arguments>
+                                <argument>stop-domain</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>StartDomain1</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${asadmin.home}</workingDirectory>
+                            <executable>${asadmin}</executable>
+                            <arguments>
+                                <argument>start-domain</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>Enable Trace requests</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${asadmin.home}</workingDirectory>
+                            <executable>${asadmin}</executable>
+                            <arguments>
+                                <argument>set</argument>
+                                <argument>server-config.network-config.protocols.protocol.http-listener-1.http.trace-enabled=true</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>Delete User j2ee</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${asadmin.home}</workingDirectory>
+                            <executable>${asadmin}</executable>
+                            <arguments>
+                                <argument>--passwordfile</argument>
+                                <argument>${project.basedir}/j2ee.pass</argument>
+                                <argument>delete-file-user</argument>
+                                <argument>j2ee</argument>
+                            </arguments>
+                            <successCodes>
+                                <successCode>0</successCode>
+                                <successCode>1</successCode>
+                            </successCodes>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>Add User j2ee</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${asadmin.home}</workingDirectory>
+                            <executable>${asadmin}</executable>
+                            <arguments>
+                                <argument>--passwordfile</argument>
+                                <argument>${project.basedir}/j2ee.pass</argument>
+                                <argument>create-file-user</argument>
+                                <argument>--groups</argument>
+                                <argument>staff:mgr</argument>
+                                <argument>j2ee</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>Delete User javajoe</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${asadmin.home}</workingDirectory>
+                            <executable>${asadmin}</executable>
+                            <arguments>
+                                <argument>--passwordfile</argument>
+                                <argument>${project.basedir}/javajoe.pass</argument>
+                                <argument>delete-file-user</argument>
+                                <argument>javajoe</argument>
+                            </arguments>
+                            <successCodes>
+                                <successCode>0</successCode>
+                                <successCode>1</successCode>
+                            </successCodes>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>Add User javajoe</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${asadmin.home}</workingDirectory>
+                            <executable>${asadmin}</executable>
+                            <arguments>
+                                <argument>--passwordfile</argument>
+                                <argument>${project.basedir}/javajoe.pass</argument>
+                                <argument>create-file-user</argument>
+                                <argument>--groups</argument>
+                                <argument>guest</argument>
+                                <argument>javajoe</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>list users</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${asadmin.home}</workingDirectory>
+                            <executable>${asadmin}</executable>
+                            <arguments>
+                                <argument>list-file-users</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>StopDomain</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <workingDirectory>${asadmin.home}</workingDirectory>
+                            <executable>${asadmin}</executable>
+                            <arguments>
+                                <argument>stop-domain</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            
+            <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <version>3.0.0-M5</version>
+                <executions>
+                    <execution>
+                        <id>gf-tests</id>
+                        <goals>
+                            <goal>integration-test</goal>
+                            <goal>verify</goal>
+                        </goals>
+                        <configuration>
+                            <excludes>
+                                <exclude>**/SeBootstrapIT.java</exclude>
+                            </excludes>
+                            <skipTests>false</skipTests> <!-- Do not skip when the jersey-tck profile is on -->
+                            <dependenciesToScan>jakarta.ws.rs:${tck.artifactId}</dependenciesToScan>
+                            <systemPropertyVariables>
+                                <GLASSFISH_HOME>${glassfish.home}</GLASSFISH_HOME>
+                                <servlet_adaptor>org.glassfish.jersey.servlet.ServletContainer</servlet_adaptor>
+                                <webServerHost>localhost</webServerHost>
+                                <webServerPort>8080</webServerPort>
+                                <junit.log.traceflag>true</junit.log.traceflag>
+                                <user>j2ee</user>
+                                <password>j2ee</password>
+                                <authuser>javajoe</authuser>
+                                <authpassword>javajoe</authpassword>
+                                <porting.ts.url.class.1>ee.jakarta.tck.ws.rs.lib.implementation.sun.common.SunRIURL</porting.ts.url.class.1>
+                                <jimage.dir>${project.build.directory}/jdk11-bundle</jimage.dir>
+                                <optional.tech.packages.to.ignore>jakarta.xml.bind</optional.tech.packages.to.ignore>
+                                <signature.sigTestClasspath>${glassfish.home}/glassfish/modules/jakarta.ws.rs-api.jar:${glassfish.home}/glassfish/modules/jakarta.xml.bind-api.jar:${project.build.directory}/jdk11-bundle/java.base:${project.build.directory}/jdk11-bundle/java.rmi:${project.build.directory}/jdk11-bundle/java.sql:${project.build.directory}/jdk11-bundle/java.naming</signature.sigTestClasspath>
+                            </systemPropertyVariables>
+                            <environmentVariables>
+                                <GLASSFISH_HOME>${glassfish.home}</GLASSFISH_HOME>
+                            </environmentVariables>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>se-tests</id>
+                        <goals>
+                            <goal>integration-test</goal>
+                            <goal>verify</goal>
+                        </goals>
+                        <configuration>
+                            <skipTests>false</skipTests> <!-- Do not skip when the jersey-tck profile is on -->
+                            <includes>
+                                <include>**/SeBootstrapIT.java</include>
+                            </includes>
+                            <dependenciesToScan>jakarta.ws.rs:${tck.artifactId}</dependenciesToScan>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <profiles>
+        <profile>
+            <id>onLinux</id>
+            <activation>
+                <os>
+                    <family>unix</family>
+                </os>
+            </activation>
+            <properties>
+                <asadmin.home>${basedir}</asadmin.home>
+                <asadmin>${glassfish.home}/glassfish/bin/asadmin</asadmin>
+            </properties>
+        </profile>
+        <profile>
+            <id>onWindows</id>
+            <activation>
+                <os>
+                    <family>Windows</family>
+                </os>
+            </activation>
+            <properties>
+                <asadmin.home>${glassfish.home}/glassfish/bin</asadmin.home>
+                <asadmin>asadmin</asadmin>
+            </properties>
+        </profile>
+        <profile>
+            <id>jersey-tck</id>
+            <properties>
+                <jersey.version>3.1.99-SNAPSHOT</jersey.version> <!-- When running the profile, use SNAPSHOT -->
+            </properties>
+        </profile>
+    </profiles>
+</project>
diff --git a/tests/jersey-tck/src/main/java/org/glassfish/jersey/core/tck/JerseyApplicationArchiveProcessor.java b/tests/jersey-tck/src/main/java/org/glassfish/jersey/core/tck/JerseyApplicationArchiveProcessor.java
new file mode 100644
index 0000000..c5597e5
--- /dev/null
+++ b/tests/jersey-tck/src/main/java/org/glassfish/jersey/core/tck/JerseyApplicationArchiveProcessor.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.core.tck;
+
+import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
+import org.jboss.arquillian.test.spi.TestClass;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+
+public class JerseyApplicationArchiveProcessor implements ApplicationArchiveProcessor {
+    @Override
+    public void process(Archive<?> archive, TestClass testClass) {
+        if ("jaxrs_ee_rs_container_requestcontext_security_web.war".equals(archive.getName())) {
+            WebArchive webArchive = (WebArchive) archive;
+            webArchive.addAsWebInfResource("jaxrs_ee_rs_container_requestcontext_security_web.war.sun-web.xml", "sun-web.xml");
+        } else if ("jaxrs_ee_core_securitycontext_basic_web.war".equals(archive.getName())) {
+            WebArchive webArchive = (WebArchive) archive;
+            webArchive.addAsWebInfResource("jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml", "sun-web.xml");
+        }
+    }
+}
diff --git a/tests/jersey-tck/src/main/java/org/glassfish/jersey/core/tck/JerseyLoadableExtension.java b/tests/jersey-tck/src/main/java/org/glassfish/jersey/core/tck/JerseyLoadableExtension.java
new file mode 100644
index 0000000..d4da355
--- /dev/null
+++ b/tests/jersey-tck/src/main/java/org/glassfish/jersey/core/tck/JerseyLoadableExtension.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.core.tck;
+
+import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
+import org.jboss.arquillian.core.spi.LoadableExtension;
+
+public class JerseyLoadableExtension implements LoadableExtension {
+    @Override
+    public void register(ExtensionBuilder extensionBuilder) {
+        extensionBuilder.service(ApplicationArchiveProcessor.class, JerseyApplicationArchiveProcessor.class);
+    }
+}
diff --git a/tests/jersey-tck/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/tests/jersey-tck/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100644
index 0000000..577c00f
--- /dev/null
+++ b/tests/jersey-tck/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1 @@
+org.glassfish.jersey.core.tck.JerseyLoadableExtension
\ No newline at end of file
diff --git a/tests/jersey-tck/src/main/resources/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml b/tests/jersey-tck/src/main/resources/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml
new file mode 100644
index 0000000..8e2a251
--- /dev/null
+++ b/tests/jersey-tck/src/main/resources/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Sun ONE Application Server 8.0 Servlet 2.4//EN" "http://www.sun.com/software/sunone/appserver/dtds/sun-web-app_2_5-0.dtd">
+<sun-web-app>
+  <context-root>jaxrs_ee_core_securitycontext_basic_web</context-root>
+  <security-role-mapping>
+    <role-name>DIRECTOR</role-name>
+    <principal-name>j2ee</principal-name>
+  </security-role-mapping>
+  <security-role-mapping>
+    <role-name>OTHERROLE</role-name>
+    <principal-name>javajoe</principal-name>
+  </security-role-mapping>    
+</sun-web-app>
diff --git a/tests/jersey-tck/src/main/resources/jaxrs_ee_rs_container_requestcontext_security_web.war.sun-web.xml b/tests/jersey-tck/src/main/resources/jaxrs_ee_rs_container_requestcontext_security_web.war.sun-web.xml
new file mode 100644
index 0000000..a5efdc5
--- /dev/null
+++ b/tests/jersey-tck/src/main/resources/jaxrs_ee_rs_container_requestcontext_security_web.war.sun-web.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Sun ONE Application Server 8.0 Servlet 2.4//EN" "http://www.sun.com/software/sunone/appserver/dtds/sun-web-app_2_5-0.dtd">
+<sun-web-app>
+  <context-root>jaxrs_ee_rs_container_requestcontext_security_web</context-root>
+  <security-role-mapping>
+    <role-name>DIRECTOR</role-name>
+    <principal-name>j2ee</principal-name>
+  </security-role-mapping>
+</sun-web-app>
diff --git a/tests/jmockit/pom.xml b/tests/jmockit/pom.xml
index c45b82d..7088123 100644
--- a/tests/jmockit/pom.xml
+++ b/tests/jmockit/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <artifactId>project</artifactId>
         <groupId>org.glassfish.jersey.tests</groupId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/tests/jmockit/src/test/java/org/glassfish/jersey/tests/jmockit/server/WebServerFactoryTest.java b/tests/jmockit/src/test/java/org/glassfish/jersey/tests/jmockit/server/WebServerFactoryTest.java
new file mode 100644
index 0000000..974404c
--- /dev/null
+++ b/tests/jmockit/src/test/java/org/glassfish/jersey/tests/jmockit/server/WebServerFactoryTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.jmockit.server;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.theInstance;
+import static org.junit.Assert.assertThat;
+
+import java.util.Iterator;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.core.Application;
+
+import org.glassfish.jersey.internal.ServiceFinder;
+import org.glassfish.jersey.internal.ServiceFinder.ServiceIteratorProvider;
+import org.glassfish.jersey.internal.guava.Iterators;
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.inject.InjectionManagerFactory;
+import org.glassfish.jersey.server.WebServerFactory;
+import org.glassfish.jersey.server.spi.WebServer;
+import org.glassfish.jersey.server.spi.WebServerProvider;
+import org.junit.After;
+import org.junit.Test;
+
+import mockit.Mocked;
+
+/**
+ * Unit tests for {@link WebServerFactory}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+public final class WebServerFactoryTest {
+
+    @Test
+    public final void shouldBuildServer(@Mocked final Application mockApplication,
+                                        @Mocked final WebServer mockServer,
+                                        @Mocked final SeBootstrap.Configuration mockConfiguration,
+                                        @Mocked final InjectionManager mockInjectionManager) {
+        // given
+        ServiceFinder.setIteratorProvider(new ServiceIteratorProvider() {
+            @Override
+            public final <T> Iterator<T> createIterator(final Class<T> service, final String serviceName,
+                    final ClassLoader loader, final boolean ignoreOnClassNotFound) {
+                return Iterators.singletonIterator(service.cast(
+                        service == WebServerProvider.class ? new WebServerProvider() {
+                            @Override
+                            public final <U extends WebServer> U createServer(
+                                    final Class<U> type,
+                                    final Application application,
+                                    final SeBootstrap.Configuration configuration) {
+                                return application == mockApplication && configuration == mockConfiguration
+                                        ? type.cast(mockServer)
+                                        : null;
+                            }
+
+                            @Override
+                            public <T extends WebServer> T createServer(
+                                    final Class<T> type,
+                                    final Class<? extends Application> applicationClass,
+                                    final SeBootstrap.Configuration configuration) {
+                                return null;
+                            }
+                        }
+                                : service == InjectionManagerFactory.class ? new InjectionManagerFactory() {
+                            @Override
+                            public final InjectionManager create(final Object parent) {
+                                return mockInjectionManager;
+                            }
+                        }
+                                : null));
+            }
+
+            @Override
+            public final <T> Iterator<Class<T>> createClassIterator(final Class<T> service, final String serviceName,
+                    final ClassLoader loader, final boolean ignoreOnClassNotFound) {
+                return null;
+            }
+        });
+
+        // when
+        final WebServer server = WebServerFactory.createServer(WebServer.class, mockApplication, mockConfiguration);
+
+        // then
+        assertThat(server, is(theInstance(mockServer)));
+    }
+
+    @After
+    public final void resetServiceFinder() {
+        ServiceFinder.setIteratorProvider(null);
+    }
+
+}
diff --git a/tests/mem-leaks/pom.xml b/tests/mem-leaks/pom.xml
index 92c40c3..dcbb3e4 100644
--- a/tests/mem-leaks/pom.xml
+++ b/tests/mem-leaks/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.tests.memleaks</groupId>
diff --git a/tests/mem-leaks/redeployment/pom.xml b/tests/mem-leaks/redeployment/pom.xml
index 2f47efc..4d653e3 100644
--- a/tests/mem-leaks/redeployment/pom.xml
+++ b/tests/mem-leaks/redeployment/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.tests.memleaks.redeployment</groupId>
diff --git a/tests/mem-leaks/redeployment/redeployment-hello-world-app-ref/pom.xml b/tests/mem-leaks/redeployment/redeployment-hello-world-app-ref/pom.xml
index e751f7d..7e81bc2 100644
--- a/tests/mem-leaks/redeployment/redeployment-hello-world-app-ref/pom.xml
+++ b/tests/mem-leaks/redeployment/redeployment-hello-world-app-ref/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks.redeployment</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>redeployment-hello-world-app-ref</artifactId>
@@ -132,7 +132,7 @@
             <groupId>org.glassfish.jersey.examples</groupId>
             <artifactId>helloworld-webapp</artifactId>
             <type>war</type>
-            <version>3.0.99-SNAPSHOT</version>
+            <version>3.1.99-SNAPSHOT</version>
         </dependency>
     </dependencies>
 
diff --git a/tests/mem-leaks/redeployment/redeployment-leaking-test-app/pom.xml b/tests/mem-leaks/redeployment/redeployment-leaking-test-app/pom.xml
index 0001f9a..b71d2b3 100644
--- a/tests/mem-leaks/redeployment/redeployment-leaking-test-app/pom.xml
+++ b/tests/mem-leaks/redeployment/redeployment-leaking-test-app/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks.redeployment</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>redeployment-leaking-test-app</artifactId>
diff --git a/tests/mem-leaks/redeployment/redeployment-no-jersey-app/pom.xml b/tests/mem-leaks/redeployment/redeployment-no-jersey-app/pom.xml
index 3749b50..1064c12 100644
--- a/tests/mem-leaks/redeployment/redeployment-no-jersey-app/pom.xml
+++ b/tests/mem-leaks/redeployment/redeployment-no-jersey-app/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks.redeployment</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>redeployment-no-jersey-app</artifactId>
@@ -125,7 +125,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/tests/mem-leaks/redeployment/redeployment-threadlocals-app/pom.xml b/tests/mem-leaks/redeployment/redeployment-threadlocals-app/pom.xml
index e86fde1..d70c09c 100644
--- a/tests/mem-leaks/redeployment/redeployment-threadlocals-app/pom.xml
+++ b/tests/mem-leaks/redeployment/redeployment-threadlocals-app/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks.redeployment</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>redeployment-threadlocals-app</artifactId>
@@ -106,7 +106,6 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
     </dependencies>
diff --git a/tests/mem-leaks/test-cases/bean-param-leak/pom.xml b/tests/mem-leaks/test-cases/bean-param-leak/pom.xml
index f742db4..b46cd66 100644
--- a/tests/mem-leaks/test-cases/bean-param-leak/pom.xml
+++ b/tests/mem-leaks/test-cases/bean-param-leak/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>bean-param-leak</artifactId>
diff --git a/tests/mem-leaks/test-cases/leaking-test-app/pom.xml b/tests/mem-leaks/test-cases/leaking-test-app/pom.xml
index 8ca065b..aebd688 100644
--- a/tests/mem-leaks/test-cases/leaking-test-app/pom.xml
+++ b/tests/mem-leaks/test-cases/leaking-test-app/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>leaking-test-app</artifactId>
diff --git a/tests/mem-leaks/test-cases/pom.xml b/tests/mem-leaks/test-cases/pom.xml
index ab85d8c..7261a8a 100644
--- a/tests/mem-leaks/test-cases/pom.xml
+++ b/tests/mem-leaks/test-cases/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.tests.memleaks.testcases</groupId>
diff --git a/tests/mem-leaks/test-cases/shutdown-hook-leak-client/pom.xml b/tests/mem-leaks/test-cases/shutdown-hook-leak-client/pom.xml
index 51c8608..d96e312 100644
--- a/tests/mem-leaks/test-cases/shutdown-hook-leak-client/pom.xml
+++ b/tests/mem-leaks/test-cases/shutdown-hook-leak-client/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>shutdown-hook-leak-client</artifactId>
diff --git a/tests/mem-leaks/test-cases/shutdown-hook-leak/pom.xml b/tests/mem-leaks/test-cases/shutdown-hook-leak/pom.xml
index ec90f06..bc4db91 100644
--- a/tests/mem-leaks/test-cases/shutdown-hook-leak/pom.xml
+++ b/tests/mem-leaks/test-cases/shutdown-hook-leak/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.memleaks.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>shutdown-hook-leak</artifactId>
diff --git a/tests/osgi/functional/pom.xml b/tests/osgi/functional/pom.xml
index 17bf9ee..41db18e 100644
--- a/tests/osgi/functional/pom.xml
+++ b/tests/osgi/functional/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.osgi</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>jersey-tests-osgi-functional</artifactId>
@@ -218,7 +218,6 @@
             <scope>test</scope>
             <version>${httpclient.version}</version>
         </dependency>
-
         <dependency>
             <groupId>org.glassfish.jersey.media</groupId>
             <artifactId>jersey-media-json-jackson</artifactId>
@@ -287,7 +286,7 @@
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet5.version}</version>
+            <version>${servlet6.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/JsonJacksonTest.java b/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/JsonJacksonTest.java
index 7d06f02..7aebd55 100644
--- a/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/JsonJacksonTest.java
+++ b/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/JsonJacksonTest.java
@@ -41,6 +41,9 @@
         options.addAll(Helper.expandedList(
                 // vmOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"),
 
+                // TODO - remove when jackson-module-jakarta-xmlbind-annotations supports JAX-B/4
+                mavenBundle().groupId("jakarta.xml.bind").artifactId("jakarta.xml.bind-api").version("3.0.1"),
+
                 mavenBundle().groupId("org.glassfish.jersey.media").artifactId("jersey-media-json-jackson").versionAsInProject(),
                 mavenBundle().groupId("org.glassfish.jersey.ext").artifactId("jersey-entity-filtering").versionAsInProject(),
 
diff --git a/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/JsonMoxyTest.java b/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/JsonMoxyTest.java
index 0f7eb6f..4b2876b 100644
--- a/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/JsonMoxyTest.java
+++ b/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/JsonMoxyTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -56,8 +56,8 @@
                 mavenBundle().groupId("org.glassfish.jersey.ext").artifactId("jersey-entity-filtering").versionAsInProject(),
                 mavenBundle().groupId("org.eclipse.persistence").artifactId("org.eclipse.persistence.moxy").versionAsInProject(),
                 mavenBundle().groupId("org.eclipse.persistence").artifactId("org.eclipse.persistence.core").versionAsInProject(),
-                mavenBundle().groupId("org.eclipse.persistence").artifactId("org.eclipse.persistence.asm").versionAsInProject(),
-                mavenBundle().groupId("org.glassfish").artifactId("jakarta.json").versionAsInProject(),
+                mavenBundle().groupId("org.ow2.asm").artifactId("asm").versionAsInProject(),
+                mavenBundle().groupId("jakarta.json").artifactId("jakarta.json-api").versionAsInProject(),
 
                 // validation
                 mavenBundle().groupId("org.hibernate.validator").artifactId("hibernate-validator").versionAsInProject(),
diff --git a/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/PackageScanningTest.java b/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/PackageScanningTest.java
index 424b1ba..c3a2fca 100644
--- a/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/PackageScanningTest.java
+++ b/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/basic/PackageScanningTest.java
@@ -79,7 +79,7 @@
                         .versionAsInProject(),
 
                 // MBR/MBW for JSON-P is on the classpath.
-                mavenBundle().groupId("org.glassfish").artifactId("jakarta.json").versionAsInProject()
+                mavenBundle().groupId("jakarta.json").artifactId("jakarta.json-api").versionAsInProject()
         ));
 
         options = Helper.addPaxExamMavenLocalRepositoryProperty(options);
diff --git a/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/util/Helper.java b/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/util/Helper.java
index 76a1515..4be49dd 100644
--- a/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/util/Helper.java
+++ b/tests/osgi/functional/src/test/java/org/glassfish/jersey/osgi/test/util/Helper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -183,9 +183,9 @@
                     mavenBundle().groupId("org.glassfish.jersey.core").artifactId("jersey-client").versionAsInProject(),
 
                     // Jersey Injection provider
-                    mavenBundle().groupId("org.glassfish.jersey.inject").artifactId("jersey-hk2").versionAsInProject(),
+                    mavenBundle().groupId("org.glassfish.jersey.inject").artifactId("jersey-hk2").versionAsInProject()
 //                     Jaxb - api
-                    getActivationBundle()
+//                    getActivationBundle()
             ));
         }
 
diff --git a/tests/osgi/pom.xml b/tests/osgi/pom.xml
index b08f6b2..1364c6b 100644
--- a/tests/osgi/pom.xml
+++ b/tests/osgi/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.tests.osgi</groupId>
diff --git a/tests/performance/benchmarks/pom.xml b/tests/performance/benchmarks/pom.xml
index 1f7bef1..f6ed0a5 100644
--- a/tests/performance/benchmarks/pom.xml
+++ b/tests/performance/benchmarks/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>performance-test-benchmarks</artifactId>
diff --git a/tests/performance/pom.xml b/tests/performance/pom.xml
index 8db201a..b69e3e5 100644
--- a/tests/performance/pom.xml
+++ b/tests/performance/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.tests.performance</groupId>
diff --git a/tests/performance/runners/jersey-grizzly-runner/pom.xml b/tests/performance/runners/jersey-grizzly-runner/pom.xml
index 352890b..ea760b4 100644
--- a/tests/performance/runners/jersey-grizzly-runner/pom.xml
+++ b/tests/performance/runners/jersey-grizzly-runner/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.runners</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
 
diff --git a/tests/performance/runners/pom.xml b/tests/performance/runners/pom.xml
index a75bf66..391ebc5 100644
--- a/tests/performance/runners/pom.xml
+++ b/tests/performance/runners/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.tests.performance.runners</groupId>
diff --git a/tests/performance/test-cases/assemblies/pom.xml b/tests/performance/test-cases/assemblies/pom.xml
index 9562ead..b42a240 100644
--- a/tests/performance/test-cases/assemblies/pom.xml
+++ b/tests/performance/test-cases/assemblies/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>assemblies</artifactId>
diff --git a/tests/performance/test-cases/filter-dynamic/pom.xml b/tests/performance/test-cases/filter-dynamic/pom.xml
index abb25b3..22b4ad4 100644
--- a/tests/performance/test-cases/filter-dynamic/pom.xml
+++ b/tests/performance/test-cases/filter-dynamic/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>filter-dynamic</artifactId>
diff --git a/tests/performance/test-cases/filter-global/pom.xml b/tests/performance/test-cases/filter-global/pom.xml
index 6083e1a..2d314d0 100644
--- a/tests/performance/test-cases/filter-global/pom.xml
+++ b/tests/performance/test-cases/filter-global/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>filter-global</artifactId>
diff --git a/tests/performance/test-cases/filter-name/pom.xml b/tests/performance/test-cases/filter-name/pom.xml
index 04b5fa0..d1adcad 100644
--- a/tests/performance/test-cases/filter-name/pom.xml
+++ b/tests/performance/test-cases/filter-name/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>filter-name</artifactId>
diff --git a/tests/performance/test-cases/interceptor-dynamic/pom.xml b/tests/performance/test-cases/interceptor-dynamic/pom.xml
index a3709ae..9556824 100644
--- a/tests/performance/test-cases/interceptor-dynamic/pom.xml
+++ b/tests/performance/test-cases/interceptor-dynamic/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>interceptor-dynamic</artifactId>
diff --git a/tests/performance/test-cases/interceptor-global/pom.xml b/tests/performance/test-cases/interceptor-global/pom.xml
index af2ef78..9f8898b 100644
--- a/tests/performance/test-cases/interceptor-global/pom.xml
+++ b/tests/performance/test-cases/interceptor-global/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>interceptor-global</artifactId>
diff --git a/tests/performance/test-cases/interceptor-name/pom.xml b/tests/performance/test-cases/interceptor-name/pom.xml
index 4b34120..a1d4a05 100644
--- a/tests/performance/test-cases/interceptor-name/pom.xml
+++ b/tests/performance/test-cases/interceptor-name/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>interceptor-name</artifactId>
diff --git a/tests/performance/test-cases/mbw-custom-provider/pom.xml b/tests/performance/test-cases/mbw-custom-provider/pom.xml
index bf2d2ad..cd53362 100644
--- a/tests/performance/test-cases/mbw-custom-provider/pom.xml
+++ b/tests/performance/test-cases/mbw-custom-provider/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>custom-provider</artifactId>
diff --git a/tests/performance/test-cases/mbw-json-jackson/pom.xml b/tests/performance/test-cases/mbw-json-jackson/pom.xml
index 8179693..d289c8a 100644
--- a/tests/performance/test-cases/mbw-json-jackson/pom.xml
+++ b/tests/performance/test-cases/mbw-json-jackson/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>json-jackson</artifactId>
diff --git a/tests/performance/test-cases/mbw-json-moxy/pom.xml b/tests/performance/test-cases/mbw-json-moxy/pom.xml
index 13532ba..82c2bac 100644
--- a/tests/performance/test-cases/mbw-json-moxy/pom.xml
+++ b/tests/performance/test-cases/mbw-json-moxy/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>json-moxy</artifactId>
diff --git a/tests/performance/test-cases/mbw-kryo/pom.xml b/tests/performance/test-cases/mbw-kryo/pom.xml
index 5b47d3d..79da8c2 100644
--- a/tests/performance/test-cases/mbw-kryo/pom.xml
+++ b/tests/performance/test-cases/mbw-kryo/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>mbw-kryo</artifactId>
diff --git a/tests/performance/test-cases/mbw-text-plain/pom.xml b/tests/performance/test-cases/mbw-text-plain/pom.xml
index f9c8485..db21cdb 100644
--- a/tests/performance/test-cases/mbw-text-plain/pom.xml
+++ b/tests/performance/test-cases/mbw-text-plain/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>text-plain</artifactId>
diff --git a/tests/performance/test-cases/mbw-xml-jaxb/pom.xml b/tests/performance/test-cases/mbw-xml-jaxb/pom.xml
index 596cb72..f052ef6 100644
--- a/tests/performance/test-cases/mbw-xml-jaxb/pom.xml
+++ b/tests/performance/test-cases/mbw-xml-jaxb/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>xml-jaxb</artifactId>
@@ -46,6 +46,11 @@
             <artifactId>jakarta.ws.rs-api</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-osgi</artifactId>
+        </dependency>
+
 
         <dependency>
             <groupId>org.glassfish.jersey.test-framework.providers</groupId>
@@ -63,42 +68,4 @@
         </plugins>
     </build>
 
-    <profiles>
-        <profile>
-            <id>jdk11+</id>
-            <activation>
-                <jdk>[11,)</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>jakarta.xml.bind</groupId>
-                    <artifactId>jakarta.xml.bind-api</artifactId>
-                </dependency>
-                <dependency>
-                    <groupId>com.sun.xml.bind</groupId>
-                    <artifactId>jaxb-osgi</artifactId>
-                </dependency>
-            </dependencies>
-        </profile>
-        <profile>
-            <id>jdk8</id>
-            <activation>
-                <jdk>1.8</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <configuration>
-                            <excludes>
-                                <exclude>org/glassfish/jersey/tests/performance/mbw/xml/XmlEntityTest.java</exclude>
-                            </excludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-
 </project>
diff --git a/tests/performance/test-cases/mbw-xml-moxy/pom.xml b/tests/performance/test-cases/mbw-xml-moxy/pom.xml
index 72d6530..e94746f 100644
--- a/tests/performance/test-cases/mbw-xml-moxy/pom.xml
+++ b/tests/performance/test-cases/mbw-xml-moxy/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>xml-moxy</artifactId>
diff --git a/tests/performance/test-cases/param-srl/pom.xml b/tests/performance/test-cases/param-srl/pom.xml
index 4a6569e..5ff72e4 100644
--- a/tests/performance/test-cases/param-srl/pom.xml
+++ b/tests/performance/test-cases/param-srl/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>param-srl</artifactId>
diff --git a/tests/performance/test-cases/pom.xml b/tests/performance/test-cases/pom.xml
index 8be9cc2..7436395 100644
--- a/tests/performance/test-cases/pom.xml
+++ b/tests/performance/test-cases/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
diff --git a/tests/performance/test-cases/proxy-injection/pom.xml b/tests/performance/test-cases/proxy-injection/pom.xml
index 395cf20..e01f2d4 100644
--- a/tests/performance/test-cases/proxy-injection/pom.xml
+++ b/tests/performance/test-cases/proxy-injection/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance.testcases</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>proxy-injection</artifactId>
diff --git a/tests/performance/tools/pom.xml b/tests/performance/tools/pom.xml
index 24ed28e..ded7750 100644
--- a/tests/performance/tools/pom.xml
+++ b/tests/performance/tools/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.performance</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
     <groupId>org.glassfish.jersey.tests.performance.tools</groupId>
     <artifactId>performance-test-tools</artifactId>
diff --git a/tests/pom.xml b/tests/pom.xml
index 8306acc..1fc9c20 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <groupId>org.glassfish.jersey.tests</groupId>
@@ -107,12 +107,28 @@
             </build>
         </profile>
         <profile>
+            <id>jersey-tck</id>
+            <modules>
+                <module>jersey-tck</module>
+            </modules>
+            <build>
+            </build>
+        </profile>
+        <profile>
             <id>JDK11+</id>
             <activation>
                 <jdk>[11,)</jdk>
             </activation>
             <modules>
                 <module>release-test</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>JDK17+</id>
+            <activation>
+                <jdk>[17,)</jdk>
+            </activation>
+            <modules>
                 <module>version-agnostic</module>
             </modules>
         </profile>
diff --git a/tests/release-test/pom.xml b/tests/release-test/pom.xml
index 6f7ad39..246040a 100644
--- a/tests/release-test/pom.xml
+++ b/tests/release-test/pom.xml
@@ -23,12 +23,13 @@
     <parent>
         <groupId>org.glassfish.jersey</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 
     <groupId>org.glassfish.jersey.tests</groupId>
     <artifactId>release-test</artifactId>
+    <version>3.1.99-SNAPSHOT</version>
     <packaging>jar</packaging>
     <name>jersey-release-test</name>
 
@@ -57,6 +58,13 @@
                     </includes>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 
diff --git a/tests/stress/pom.xml b/tests/stress/pom.xml
index c11b9f6..9f3d04d 100644
--- a/tests/stress/pom.xml
+++ b/tests/stress/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.glassfish.jersey.tests</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.99-SNAPSHOT</version>
+        <version>3.1.99-SNAPSHOT</version>
     </parent>
 
     <artifactId>stress</artifactId>
diff --git a/tests/version-agnostic/pom.xml b/tests/version-agnostic/pom.xml
index c4c44f5..85bd01a 100644
--- a/tests/version-agnostic/pom.xml
+++ b/tests/version-agnostic/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.eclipse.ee4j</groupId>
         <artifactId>project</artifactId>
-        <version>1.0.8</version>
+        <version>1.0.9</version>
         <relativePath>../../../pom.xml</relativePath>
     </parent>
 
@@ -38,7 +38,7 @@
         <maven.compiler.source>8</maven.compiler.source>
         <maven.compiler.target>8</maven.compiler.target>
         <hk2.version>3.0.3</hk2.version>
-        <jersey.version>3.0.99-SNAPSHOT</jersey.version>
+        <jersey.version>3.1.99-SNAPSHOT</jersey.version>
     </properties>
 
     <build>
@@ -46,7 +46,7 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
-                <version>3.0.0-M7</version>
+                <version>3.2.2</version>
                 <configuration>
                     <forkCount>1</forkCount>
                     <reuseForks>false</reuseForks>
@@ -75,6 +75,14 @@
                     <bsdTemplateFile>etc/config/edl-copyright.txt</bsdTemplateFile>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <version>3.1.1</version>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
         </plugins>
     </build>