Merge remote-tracking branch 'origin/3.x' into 'origin/3.1'
Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
diff --git a/NOTICE.md b/NOTICE.md
index ca03fd1..9c76708 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -41,13 +41,13 @@
* Project: http://aopalliance.sourceforge.net
* Copyright: Material in the public domain is not protected by copyright
-Bean Validation API 3.0.0
+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.0.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 b9f2684..3561865 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
@@ -120,7 +120,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>
</properties>
</project>
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-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 e70010e..feb6cba 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,6 +80,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-jetty-connector</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/bundles/apidocs/pom.xml b/bundles/apidocs/pom.xml
index 073f826..b6a3c91 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>
@@ -129,6 +134,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>
@@ -165,6 +174,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>
@@ -245,54 +270,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>
@@ -310,6 +287,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 052c188..0fee916 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..9b2ff73 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,6 @@
<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>
@@ -74,18 +70,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 +111,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>
@@ -134,169 +125,4 @@
</plugin>
</plugins>
</build>
-
- <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/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/JettyConnectorProvider.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/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
similarity index 100%
rename from connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java
rename to connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
diff --git a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
similarity index 100%
rename from connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
rename to connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
diff --git a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
similarity index 100%
rename from connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
rename to connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
diff --git a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
similarity index 100%
rename from connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
rename to connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
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/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java b/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
deleted file mode 100644
index b061ef5..0000000
--- a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
+++ /dev/null
@@ -1,33 +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.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}
- */
-@Contract
-public interface JettyHttpClientContract {
- /**
- * Supply a user predefined HttpClient
- * @return a user predefined HttpClient
- */
- HttpClient getHttpClient();
-}
diff --git a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java b/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
deleted file mode 100644
index 59c8fd3..0000000
--- a/connectors/jetty-connector/src/main/java8/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
+++ /dev/null
@@ -1,61 +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.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}.
- * 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>
- * Typical usage:
- * </p>
- * <pre>
- * {@code
- * HttpClient httpClient = ...
- *
- * ClientConfig config = new ClientConfig();
- * config.connectorProvider(new JettyConnectorProvider());
- * config.register(new JettyHttpClientSupplier(httpClient));
- * Client client = ClientBuilder.newClient(config);
- * }
- * </pre>
- * <p>
- * The {@code HttpClient} is configured as if it was created by {@link JettyConnector} the usual way.
- * </p>
- */
-public class JettyHttpClientSupplier implements JettyHttpClientContract {
- 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.
- */
- public JettyHttpClientSupplier(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
- }
-}
diff --git a/connectors/jnh-connector/pom.xml b/connectors/jnh-connector/pom.xml
new file mode 100644
index 0000000..45b7af4
--- /dev/null
+++ b/connectors/jnh-connector/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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
+
+-->
+
+<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..3a48d2c
--- /dev/null
+++ b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpClientProperties.java
@@ -0,0 +1,83 @@
+/*
+ * 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 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";
+
+ /**
+ * An instance of the {@link java.net.Authenticator} class that should be used to retrieve
+ * credentials from a user.
+ *
+ */
+ public static final String PREEMPTIVE_BASIC_AUTHENTICATION =
+ "jersey.config.jnh.client.preemptiveBasicAuthentication";
+
+ /**
+ * 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 java.lang.Boolean}.
+ * If the property is absent the default value is {@code false}
+ */
+ public static final String DISABLE_COOKIES =
+ "jersey.config.jnh.client.disableCookies";
+
+
+ /**
+ * 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..7530c4e
--- /dev/null
+++ b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpConnector.java
@@ -0,0 +1,299 @@
+/*
+ * 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.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.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.time.temporal.ChronoUnit;
+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.logging.Logger;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * 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) {
+ HttpClient.Builder httpClientBuilder = HttpClient.newBuilder();
+ httpClientBuilder.version(HttpClient.Version.HTTP_1_1);
+ 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);
+ 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) {
+ HttpRequest.Builder builder = HttpRequest.newBuilder();
+ builder.uri(request.getUri());
+ HttpRequest.BodyPublisher bodyPublisher = HttpRequest.BodyPublishers.noBody();
+ if (request.hasEntity()) {
+ try {
+ request.enableBuffering();
+ 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.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());
+ }
+ }
+ clientResponse.setEntityStream(response.body());
+ 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;
+ }
+}
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/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/package-info.java
similarity index 70%
copy from core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
copy to connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/package-info.java
index dd25372..6a5e83a 100644
--- a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
+++ b/connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 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
@@ -14,7 +14,8 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
-package org.glassfish.jersey.internal.jsr166;
-
-public interface JerseyFlowSubscriber<T> extends Flow.Subscriber<T> {
-}
+/**
+ * Jersey client {@link org.glassfish.jersey.client.spi.Connector connector} based on
+ * Java's {@link java.net.http.HttpClient}.
+ */
+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/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/EntityTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/EntityTest.java
new file mode 100644
index 0000000..f1af21c
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/EntityTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Entity;
+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 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 {
+
+ private static final Logger LOGGER = Logger.getLogger(EntityTest.class.getName());
+
+ private static final String PATH = "test";
+
+ @Path("/test")
+ public static class EntityResource {
+
+ @GET
+ public Person get() {
+ return new Person("John", "Doe");
+ }
+
+ @POST
+ public Person post(Person entity) {
+ return entity;
+ }
+
+ }
+
+ @XmlRootElement
+ public static class Person {
+
+ private String firstName;
+ private String lastName;
+
+ public Person() {
+ //For JAXB processing
+ }
+
+ public Person(String firstName, String lastName) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ @Override
+ public String toString() {
+ return firstName + " " + lastName;
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ 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 JavaNetHttpConnectorProvider())
+ .register(JacksonFeature.class);
+ }
+
+ @Test
+ public void testGet() {
+ Response response = target(PATH).request(MediaType.APPLICATION_XML_TYPE).get();
+ Person person = response.readEntity(Person.class);
+ assertEquals("John Doe", person.toString());
+ response = target(PATH).request(MediaType.APPLICATION_JSON_TYPE).get();
+ person = response.readEntity(Person.class);
+ assertEquals("John Doe", person.toString());
+ }
+
+ @Test
+ public void testGetAsync() throws ExecutionException, InterruptedException {
+ Response response = target(PATH).request(MediaType.APPLICATION_XML_TYPE).async().get().get();
+ Person person = response.readEntity(Person.class);
+ assertEquals("John Doe", person.toString());
+ response = target(PATH).request(MediaType.APPLICATION_JSON_TYPE).async().get().get();
+ person = response.readEntity(Person.class);
+ assertEquals("John Doe", person.toString());
+ }
+
+ @Test
+ public void testPost() {
+ Response response = target(PATH).request(MediaType.APPLICATION_XML_TYPE).post(Entity.xml(new Person("John", "Doe")));
+ Person person = response.readEntity(Person.class);
+ assertEquals("John Doe", person.toString());
+ response = target(PATH).request(MediaType.APPLICATION_JSON_TYPE).post(Entity.xml(new Person("John", "Doe")));
+ person = response.readEntity(Person.class);
+ assertEquals("John Doe", person.toString());
+ }
+
+ @Test
+ public void testPostAsync() throws ExecutionException, InterruptedException, TimeoutException {
+ Response response = target(PATH).request(MediaType.APPLICATION_XML_TYPE).async()
+ .post(Entity.xml(new Person("John", "Doe"))).get();
+ Person person = response.readEntity(Person.class);
+ assertEquals("John Doe", person.toString());
+ response = target(PATH).request(MediaType.APPLICATION_JSON_TYPE).async().post(Entity.xml(new Person("John", "Doe")))
+ .get();
+ person = response.readEntity(Person.class);
+ assertEquals("John Doe", person.toString());
+ }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ErrorTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ErrorTest.java
new file mode 100644
index 0000000..960f063
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ErrorTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.ClientErrorException;
+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.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;
+
+public class ErrorTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(ErrorTest.class.getName());
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(ErrorResource.class);
+ config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+ return config;
+ }
+
+
+ @Override
+ protected void configureClient(ClientConfig config) {
+ config.connectorProvider(new JavaNetHttpConnectorProvider());
+ }
+
+
+ @Path("/test")
+ public static class ErrorResource {
+ @POST
+ public Response post(String entity) {
+ return Response.serverError().build();
+ }
+
+ @Path("entity")
+ @POST
+ public Response postWithEntity(String entity) {
+ return Response.serverError().entity("error").build();
+ }
+ }
+
+ @Test
+ public void testPostError() {
+ final WebTarget target = target("test");
+
+ for (int i = 0; i < 100; i++) {
+ final Response resp = target.request().post(Entity.text("POST"));
+ assertEquals(500, resp.getStatus());
+ }
+ }
+
+ @Test
+ public void testPostErrorWithEntity() {
+ WebTarget r = target("test");
+
+ for (int i = 0; i < 100; i++) {
+ try {
+ r.request().post(Entity.text("POST"));
+ } catch (ClientErrorException ex) {
+ String s = ex.getResponse().readEntity(String.class);
+ assertEquals("error", s);
+ }
+ }
+ }
+
+ @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++) {
+ 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--;
+ }
+ }
+ }
+
+ @Test
+ public void testPostErrorWithEntityAsync() {
+ WebTarget r = target("test");
+
+ for (int i = 0; i < 100; i++) {
+ try {
+ r.request().async().post(Entity.text("POST"));
+ } catch (ClientErrorException ex) {
+ String s = ex.getResponse().readEntity(String.class);
+ assertEquals("error", s);
+ }
+ }
+ }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/FollowRedirectsTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/FollowRedirectsTest.java
new file mode 100644
index 0000000..f6432a3
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/FollowRedirectsTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.ClientRequestContext;
+import jakarta.ws.rs.client.ClientResponseContext;
+import jakarta.ws.rs.client.ClientResponseFilter;
+import jakarta.ws.rs.client.WebTarget;
+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());
+
+ @Path("/test")
+ public static class RedirectResource {
+ @GET
+ public String get() {
+ return "GET";
+ }
+
+ @GET
+ @Path("redirect")
+ public Response redirect() {
+ return Response.seeOther(UriBuilder.fromResource(RedirectResource.class).build()).build();
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(RedirectResource.class);
+ config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+ return config;
+ }
+
+ @Override
+ protected void configureClient(ClientConfig config) {
+ config.property(ClientProperties.FOLLOW_REDIRECTS, false);
+ config.connectorProvider(new JavaNetHttpConnectorProvider());
+ }
+
+ private static class RedirectTestFilter implements ClientResponseFilter {
+ public static final String RESOLVED_URI_HEADER = "resolved-uri";
+
+ @Override
+ public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
+ if (responseContext instanceof ClientResponse) {
+ ClientResponse clientResponse = (ClientResponse) responseContext;
+ responseContext.getHeaders().putSingle(RESOLVED_URI_HEADER, clientResponse.getResolvedRequestUri().toString());
+ }
+ }
+ }
+
+ @Test
+ public void testDoFollow() {
+ final URI u = target().getUri();
+ ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
+ config.connectorProvider(new JavaNetHttpConnectorProvider());
+ Client c = ClientBuilder.newClient(config);
+ WebTarget t = c.target(u);
+ Response r = t.path("test/redirect")
+ .register(RedirectTestFilter.class)
+ .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();
+ }
+
+ @Test
+ public void testDoFollowPerRequestOverride() {
+ WebTarget t = target("test/redirect");
+ t.property(ClientProperties.FOLLOW_REDIRECTS, true);
+ Response r = t.request().get();
+ assertEquals(200, r.getStatus());
+ assertEquals("GET", r.readEntity(String.class));
+ }
+
+ @Test
+ public void testDontFollow() {
+ WebTarget t = target("test/redirect");
+ assertEquals(303, t.request().get().getStatus());
+ }
+
+ @Test
+ public void testDontFollowPerRequestOverride() {
+ final URI u = target().getUri();
+ ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
+ config.connectorProvider(new JavaNetHttpConnectorProvider());
+ Client client = ClientBuilder.newClient(config);
+ WebTarget t = client.target(u);
+ t.property(ClientProperties.FOLLOW_REDIRECTS, false);
+ Response r = t.path("test/redirect").request().get();
+ assertEquals(303, r.getStatus());
+ client.close();
+ }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/GZIPContentEncodingTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/GZIPContentEncodingTest.java
new file mode 100644
index 0000000..8d94f25
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/GZIPContentEncodingTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+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 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 static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class GZIPContentEncodingTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(GZIPContentEncodingTest.class.getName());
+
+ @Path("/")
+ public static class Resource {
+
+ @POST
+ public byte[] post(byte[] content) {
+ return content;
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(Resource.class);
+ config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+ return config;
+ }
+
+ @Override
+ protected void configureClient(ClientConfig config) {
+ config.register(GZipEncoder.class);
+ 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)));
+
+ Response cr = r.request().post(Entity.entity(content, MediaType.APPLICATION_OCTET_STREAM_TYPE));
+ assertTrue(cr.hasEntity());
+ cr.close();
+ }
+
+ @Test
+ public void testPostChunked() {
+ ClientConfig config = new ClientConfig();
+ config.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024);
+ config.connectorProvider(new JavaNetHttpConnectorProvider());
+ config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+
+ Client client = ClientBuilder.newClient(config);
+ WebTarget r = client.target(getBaseUri());
+
+ byte[] content = new byte[1024 * 1024];
+ assertTrue(Arrays.equals(content,
+ r.request().post(Entity.entity(content, MediaType.APPLICATION_OCTET_STREAM_TYPE)).readEntity(byte[].class)));
+
+ Response cr = r.request().post(Entity.text("POST"));
+ assertTrue(cr.hasEntity());
+ cr.close();
+
+ client.close();
+ }
+
+}
\ No newline at end of file
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HelloWorldTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HelloWorldTest.java
new file mode 100644
index 0000000..5143ec7
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HelloWorldTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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.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;
+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;
+
+public class HelloWorldTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(HelloWorldTest.class.getName());
+ private static final String ROOT_PATH = "helloworld";
+
+ @Path("helloworld")
+ public static class HelloWorldResource {
+ public static final String CLICHED_MESSAGE = "Hello World!";
+
+ @GET
+ @Produces("text/plain")
+ public String getHello() {
+ return CLICHED_MESSAGE;
+ }
+
+ }
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(HelloWorldResource.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 testConnection() {
+ Response response = target().path(ROOT_PATH).request("text/plain").get();
+ assertEquals(200, response.getStatus());
+ }
+
+ @Test
+ public void testClientStringResponse() {
+ String s = target().path(ROOT_PATH).request().get(String.class);
+ assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+ }
+
+ @Test
+ public void testAsyncClientRequests() throws InterruptedException {
+ final int REQUESTS = 20;
+ final CountDownLatch latch = new CountDownLatch(REQUESTS);
+ final long tic = System.currentTimeMillis();
+ for (int i = 0; i < REQUESTS; i++) {
+ final int id = i;
+ target().path(ROOT_PATH).request().async().get(new InvocationCallback<Response>() {
+ @Override
+ public void completed(Response response) {
+ try {
+ final String result = response.readEntity(String.class);
+ assertEquals(HelloWorldResource.CLICHED_MESSAGE, result);
+ } finally {
+ latch.countDown();
+ }
+ }
+
+ @Override
+ public void failed(Throwable error) {
+ error.printStackTrace();
+ latch.countDown();
+ }
+ });
+ }
+ latch.await(10 * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS);
+ final long toc = System.currentTimeMillis();
+ Logger.getLogger(HelloWorldTest.class.getName()).info("Executed in: " + (toc - tic));
+ }
+
+ @Test
+ public void testHead() {
+ Response response = target().path(ROOT_PATH).request().head();
+ assertEquals(200, response.getStatus());
+ assertEquals(MediaType.TEXT_PLAIN_TYPE, response.getMediaType());
+ }
+
+ @Test
+ public void testFooBarOptions() {
+ Response response = target().path(ROOT_PATH).request().header("Accept", "foo/bar").options();
+ assertEquals(200, response.getStatus());
+ final String allowHeader = response.getHeaderString("Allow");
+ _checkAllowContent(allowHeader);
+ assertEquals("foo/bar", response.getMediaType().toString());
+ assertEquals(0, response.getLength());
+ }
+
+ @Test
+ public void testTextPlainOptions() {
+ Response response = target().path(ROOT_PATH).request().header("Accept", MediaType.TEXT_PLAIN).options();
+ assertEquals(200, response.getStatus());
+ final String allowHeader = response.getHeaderString("Allow");
+ _checkAllowContent(allowHeader);
+ assertEquals(MediaType.TEXT_PLAIN_TYPE, response.getMediaType());
+ final String responseBody = response.readEntity(String.class);
+ _checkAllowContent(responseBody);
+ }
+
+ private void _checkAllowContent(final String content) {
+ assertTrue(content.contains("GET"));
+ assertTrue(content.contains("HEAD"));
+ assertTrue(content.contains("OPTIONS"));
+ }
+
+ @Test
+ public void testMissingResourceNotFound() {
+ Response response;
+
+ response = target().path(ROOT_PATH + "arbitrary").request().get();
+ assertEquals(404, response.getStatus());
+ response.close();
+
+ response = target().path(ROOT_PATH).path("arbitrary").request().get();
+ assertEquals(404, response.getStatus());
+ response.close();
+ }
+
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HttpHeadersTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HttpHeadersTest.java
new file mode 100644
index 0000000..550183c
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/HttpHeadersTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+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 org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class HttpHeadersTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(HttpHeadersTest.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) {
+ final List<String> requestHeader = httpHeaders.getRequestHeader(HttpHeaders.USER_AGENT);
+ if (requestHeader.size() != 1) {
+ return "FAIL";
+ }
+ return requestHeader.get(0);
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(HttpMethodResource.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 testPost() {
+ Response response = target().path("test").request().header("X-CLIENT", "client").post(null);
+
+ assertEquals(200, response.getStatus());
+ assertTrue(response.hasEntity());
+ }
+
+ /**
+ * Test, that {@code User-agent} header is as set by Jersey, not by underlying Jetty client.
+ */
+ @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);
+ }
+}
\ 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/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ManagedClientTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ManagedClientTest.java
new file mode 100644
index 0000000..8eca289
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/ManagedClientTest.java
@@ -0,0 +1,251 @@
+/*
+ * 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.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 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;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.DynamicFeature;
+import jakarta.ws.rs.container.ResourceInfo;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.FeatureContext;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ManagedClientTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(ManagedClientTest.class.getName());
+
+ /**
+ * Managed client configuration for client A.
+ */
+ @ClientBinding(configClass = MyClientAConfig.class)
+ @Documented
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.FIELD, ElementType.PARAMETER})
+ public static @interface ClientA {
+ }
+
+ /**
+ * Managed client configuration for client B.
+ */
+ @ClientBinding(configClass = MyClientBConfig.class)
+ @Documented
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.FIELD, ElementType.PARAMETER})
+ public @interface ClientB {
+ }
+
+ /**
+ * Dynamic feature that appends a properly configured {@link CustomHeaderFilter} instance
+ * to every method that is annotated with {@link Require @Require} internal feature
+ * annotation.
+ */
+ public static class CustomHeaderFeature implements DynamicFeature {
+
+ /**
+ * A method annotation to be placed on those resource methods to which a validating
+ * {@link CustomHeaderFilter} instance should be added.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Documented
+ @Target(ElementType.METHOD)
+ public static @interface Require {
+
+ /**
+ * Expected custom header name to be validated by the {@link CustomHeaderFilter}.
+ */
+ String headerName();
+
+ /**
+ * Expected custom header value to be validated by the {@link CustomHeaderFilter}.
+ */
+ String headerValue();
+ }
+
+ @Override
+ public void configure(ResourceInfo resourceInfo, FeatureContext context) {
+ final Require va = resourceInfo.getResourceMethod().getAnnotation(Require.class);
+ if (va != null) {
+ context.register(new CustomHeaderFilter(va.headerName(), va.headerValue()));
+ }
+ }
+ }
+
+ /**
+ * A filter for appending and validating custom headers.
+ * <p>
+ * On the client side, appends a new custom request header with a configured name and value to each outgoing request.
+ * </p>
+ * <p>
+ * On the server side, validates that each request has a custom header with a configured name and value.
+ * If the validation fails a HTTP 403 response is returned.
+ * </p>
+ */
+ public static class CustomHeaderFilter implements ContainerRequestFilter, ClientRequestFilter {
+
+ private final String headerName;
+ private final String headerValue;
+
+ public CustomHeaderFilter(String headerName, String headerValue) {
+ if (headerName == null || headerValue == null) {
+ throw new IllegalArgumentException("Header name and value must not be null.");
+ }
+ this.headerName = headerName;
+ this.headerValue = headerValue;
+ }
+
+ @Override
+ 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());
+ }
+ }
+
+ @Override
+ public void filter(ClientRequestContext ctx) throws IOException { // append
+ ctx.getHeaders().putSingle(headerName, headerValue);
+ }
+ }
+
+ /**
+ * Internal resource accessed from the managed client resource.
+ */
+ @Path("internal")
+ public static class InternalResource {
+
+ @GET
+ @Path("a")
+ @CustomHeaderFeature.Require(headerName = "custom-header", headerValue = "a")
+ public String getA() {
+ return "a";
+ }
+
+ @GET
+ @Path("b")
+ @CustomHeaderFeature.Require(headerName = "custom-header", headerValue = "b")
+ public String getB() {
+ return "b";
+ }
+ }
+
+ /**
+ * A resource that uses managed clients to retrieve values of internal
+ * resources 'A' and 'B', which are protected by a {@link CustomHeaderFilter}
+ * and require a specific custom header in a request to be set to a specific value.
+ * <p>
+ * Properly configured managed clients have a {@code CustomHeaderFilter} instance
+ * configured to insert the {@link CustomHeaderFeature.Require required} custom header
+ * with a proper value into the outgoing client requests.
+ * </p>
+ */
+ @Path("public")
+ public static class PublicResource {
+
+ @Uri("a")
+ @ClientA // resolves to <base>/internal/a
+ private WebTarget targetA;
+
+ @GET
+ @Produces("text/plain")
+ @Path("a")
+ public String getTargetA() {
+ return targetA.request(MediaType.TEXT_PLAIN).get(String.class);
+ }
+
+ @GET
+ @Produces("text/plain")
+ @Path("b")
+ public Response getTargetB(@Uri("internal/b") @ClientB WebTarget targetB) {
+ return targetB.request(MediaType.TEXT_PLAIN).get();
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(PublicResource.class, InternalResource.class, CustomHeaderFeature.class)
+ .property(ClientA.class.getName() + ".baseUri", this.getBaseUri().toString() + "internal");
+ config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+ return config;
+ }
+
+ public static class MyClientAConfig extends ClientConfig {
+
+ public MyClientAConfig() {
+ this.register(new CustomHeaderFilter("custom-header", "a"));
+ }
+ }
+
+ public static class MyClientBConfig extends ClientConfig {
+
+ public MyClientBConfig() {
+ this.register(new CustomHeaderFilter("custom-header", "b"));
+ }
+ }
+
+ @Override
+ protected void configureClient(ClientConfig config) {
+ config.connectorProvider(new JavaNetHttpConnectorProvider());
+ }
+
+ /**
+ * Test that a connection via managed clients works properly.
+ *
+ * @throws Exception in case of test failure.
+ */
+ @Test
+ public void testManagedClient() throws Exception {
+ final WebTarget resource = target().path("public").path("{name}");
+ Response response;
+
+ response = resource.resolveTemplate("name", "a").request(MediaType.TEXT_PLAIN).get();
+ assertEquals(200, response.getStatus());
+ assertEquals("a", response.readEntity(String.class));
+
+ response = resource.resolveTemplate("name", "b").request(MediaType.TEXT_PLAIN).get();
+ assertEquals(200, response.getStatus());
+ assertEquals("b", response.readEntity(String.class));
+ }
+
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/MethodTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/MethodTest.java
new file mode 100644
index 0000000..a4837ee
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/MethodTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.PATCH;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class MethodTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(MethodTest.class.getName());
+
+ private static final String PATH = "test";
+
+ @Path("/test")
+ public static class HttpMethodResource {
+ @GET
+ public String get() {
+ return "GET";
+ }
+
+ @POST
+ public String post(String entity) {
+ return entity;
+ }
+
+ @PUT
+ public String put(String entity) {
+ return entity;
+ }
+
+ @PATCH
+ public String patch(String entity) {
+ return entity;
+ }
+
+ @DELETE
+ public String delete() {
+ return "DELETE";
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(HttpMethodResource.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 testGet() {
+ Response response = target(PATH).request().get();
+ assertEquals("GET", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testGetAsync() throws ExecutionException, InterruptedException {
+ Response response = target(PATH).request().async().get().get();
+ assertEquals("GET", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testPost() {
+ Response response = target(PATH).request().post(Entity.entity("POST", MediaType.TEXT_PLAIN));
+ assertEquals("POST", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testPostAsync() throws ExecutionException, InterruptedException {
+ Response response = target(PATH).request().async().post(Entity.entity("POST", MediaType.TEXT_PLAIN)).get();
+ assertEquals("POST", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testPut() {
+ Response response = target(PATH).request().put(Entity.entity("PUT", MediaType.TEXT_PLAIN));
+ assertEquals("PUT", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testPutAsync() throws ExecutionException, InterruptedException {
+ Response response = target(PATH).request().async().put(Entity.entity("PUT", MediaType.TEXT_PLAIN)).get();
+ assertEquals("PUT", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testDelete() {
+ Response response = target(PATH).request().delete();
+ assertEquals("DELETE", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testDeleteAsync() throws ExecutionException, InterruptedException {
+ Response response = target(PATH).request().async().delete().get();
+ assertEquals("DELETE", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testPatch() {
+ Response response = target(PATH).request().method("PATCH", Entity.entity("PATCH", MediaType.TEXT_PLAIN));
+ assertEquals("PATCH", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testOptionsWithEntity() {
+ Response response = target(PATH).request().build("OPTIONS", Entity.text("OPTIONS")).invoke();
+ assertEquals(200, response.getStatus());
+ response.close();
+ }
+}
diff --git a/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/NoEntityTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/NoEntityTest.java
new file mode 100644
index 0000000..0954072
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/NoEntityTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+import org.junit.jupiter.api.Test;
+
+public class NoEntityTest extends JerseyTest {
+ private static final Logger LOGGER = Logger.getLogger(NoEntityTest.class.getName());
+
+ @Path("/test")
+ public static class HttpMethodResource {
+ @GET
+ public Response get() {
+ return Response.status(Response.Status.CONFLICT).build();
+ }
+
+ @POST
+ public void post(String entity) {
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(HttpMethodResource.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 testGet() {
+ WebTarget r = target("test");
+
+ for (int i = 0; i < 5; i++) {
+ Response cr = r.request().get();
+ cr.close();
+ }
+ }
+
+ @Test
+ public void testGetWithClose() {
+ WebTarget r = target("test");
+ for (int i = 0; i < 5; i++) {
+ Response cr = r.request().get();
+ cr.close();
+ }
+ }
+
+ @Test
+ public void testPost() {
+ WebTarget r = target("test");
+ for (int i = 0; i < 5; i++) {
+ Response cr = r.request().post(null);
+ }
+ }
+
+ @Test
+ public void testPostWithClose() {
+ WebTarget r = target("test");
+ for (int i = 0; i < 5; i++) {
+ Response cr = r.request().post(null);
+ cr.close();
+ }
+ }
+}
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/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/TraceSupportTest.java b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/TraceSupportTest.java
new file mode 100644
index 0000000..b8a079a
--- /dev/null
+++ b/connectors/jnh-connector/src/test/java/org/glassfish/jersey/jnh/connector/TraceSupportTest.java
@@ -0,0 +1,230 @@
+/*
+ * 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.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 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;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Request;
+import jakarta.ws.rs.core.Response;
+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;
+
+public class TraceSupportTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(TraceSupportTest.class.getName());
+
+ /**
+ * Programmatic tracing root resource path.
+ */
+ public static final String ROOT_PATH_PROGRAMMATIC = "tracing/programmatic";
+
+ /**
+ * Annotated class-based tracing root resource path.
+ */
+ public static final String ROOT_PATH_ANNOTATED = "tracing/annotated";
+
+ @HttpMethod(TRACE.NAME)
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface TRACE {
+ public static final String NAME = "TRACE";
+ }
+
+ @Path(ROOT_PATH_ANNOTATED)
+ public static class TracingResource {
+
+ @TRACE
+ @Produces("text/plain")
+ public String trace(Request request) {
+ return stringify((ContainerRequest) request);
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(TracingResource.class);
+ config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+ final Resource.Builder resourceBuilder = Resource.builder(ROOT_PATH_PROGRAMMATIC);
+ resourceBuilder.addMethod(TRACE.NAME).handledBy(new Inflector<ContainerRequestContext, Response>() {
+
+ @Override
+ public Response apply(ContainerRequestContext request) {
+ if (request == null) {
+ return Response.noContent().build();
+ } else {
+ return Response.ok(stringify((ContainerRequest) request), MediaType.TEXT_PLAIN).build();
+ }
+ }
+ });
+
+ return config.registerResources(resourceBuilder.build());
+
+ }
+
+ private String[] expectedFragmentsProgrammatic = new String[]{
+ "TRACE http://localhost:" + this.getPort() + "/tracing/programmatic"
+ };
+ private String[] expectedFragmentsAnnotated = new String[]{
+ "TRACE http://localhost:" + this.getPort() + "/tracing/annotated"
+ };
+
+ private WebTarget prepareTarget(String path) {
+ final WebTarget target = target();
+ target.register(LoggingFeature.class);
+ return target.path(path);
+ }
+
+ @Test
+ public void testProgrammaticApp() throws Exception {
+ Response response = prepareTarget(ROOT_PATH_PROGRAMMATIC).request("text/plain").method(TRACE.NAME);
+
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+ 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);
+ }
+ }
+
+ @Test
+ public void testAnnotatedApp() throws Exception {
+ Response response = prepareTarget(ROOT_PATH_ANNOTATED).request("text/plain").method(TRACE.NAME);
+
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+ String responseEntity = response.readEntity(String.class);
+ for (String expectedFragment : expectedFragmentsAnnotated) {
+ assertTrue(responseEntity.contains(expectedFragment),
+ // toLowerCase - http header field names are case insensitive
+ "Expected fragment '" + expectedFragment + "' not found in response:\n" + responseEntity);
+ }
+ }
+
+ @Test
+ public void testTraceWithEntity() throws Exception {
+ _testTraceWithEntity(false, false);
+ }
+
+ @Test
+ public void testAsyncTraceWithEntity() throws Exception {
+ _testTraceWithEntity(true, false);
+ }
+
+ @Test
+ public void testTraceWithEntityJettyConnector() throws Exception {
+ _testTraceWithEntity(false, true);
+ }
+
+ @Test
+ public void testAsyncTraceWithEntityJettyConnector() throws Exception {
+ _testTraceWithEntity(true, true);
+ }
+
+ private void _testTraceWithEntity(final boolean isAsync, final boolean useJettyConnection) throws Exception {
+ try {
+ WebTarget target = useJettyConnection ? getJettyClient().target(target().getUri()) : target();
+ target = target.path(ROOT_PATH_ANNOTATED);
+
+ final Entity<String> entity = Entity.entity("trace", MediaType.WILDCARD_TYPE);
+
+ Response response;
+ if (!isAsync) {
+ response = target.request().method(TRACE.NAME, entity);
+ } else {
+ response = target.request().async().method(TRACE.NAME, entity).get();
+ }
+
+ fail("A TRACE request MUST NOT include an entity. (response=" + response + ")");
+ } catch (Exception e) {
+ // OK
+ }
+ }
+
+ private Client getJettyClient() {
+ return ClientBuilder.newClient(new ClientConfig().connectorProvider(new JavaNetHttpConnectorProvider()));
+ }
+
+
+ public static String stringify(ContainerRequest request) {
+ StringBuilder buffer = new StringBuilder();
+
+ printRequestLine(buffer, request);
+ printPrefixedHeaders(buffer, request.getHeaders());
+
+ if (request.hasEntity()) {
+ buffer.append(request.readEntity(String.class)).append("\n");
+ }
+
+ return buffer.toString();
+ }
+
+ private static void printRequestLine(StringBuilder buffer, ContainerRequest request) {
+ buffer.append(request.getMethod()).append(" ").append(request.getUriInfo().getRequestUri().toASCIIString()).append("\n");
+ }
+
+ private static void printPrefixedHeaders(StringBuilder buffer, Map<String, List<String>> headers) {
+ for (Map.Entry<String, List<String>> e : headers.entrySet()) {
+ List<String> val = e.getValue();
+ String header = e.getKey();
+
+ if (val.size() == 1) {
+ buffer.append(header).append(": ").append(val.get(0)).append("\n");
+ } else {
+ StringBuilder sb = new StringBuilder();
+ boolean add = false;
+ for (String s : val) {
+ if (add) {
+ sb.append(',');
+ }
+ add = true;
+ sb.append(s);
+ }
+ buffer.append(header).append(": ").append(sb.toString()).append("\n");
+ }
+ }
+ }
+}
\ No newline at end of file
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 deb7a0a..0c2dcb4 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,6 +40,7 @@
<module>helidon-connector</module>
<module>jdk-connector</module>
<module>jetty-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..0acec80 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>
@@ -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>
@@ -157,33 +171,5 @@
</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>
- </executions>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
- </profile>
</profiles>
</project>
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-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 472d5ed..dfd22de 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 5b51a2f..bb39876 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..79abe32 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>
@@ -59,7 +59,6 @@
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
- <version>${servlet5.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -119,174 +118,4 @@
</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/*.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/JettyHttpContainer.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-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.java
similarity index 97%
rename from containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
rename to containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.java
index df67cb5..36be72d 100644
--- a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
+++ b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.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
@@ -36,7 +36,6 @@
import jakarta.servlet.AsyncListener;
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;
@@ -198,7 +197,7 @@
if (configSetStatusOverSendError) {
response.reset();
//noinspection deprecation
- response.setStatus(BAD_REQUEST_STATUS.getStatusCode(), BAD_REQUEST_STATUS.getReasonPhrase());
+ response.setStatus(BAD_REQUEST_STATUS.getStatusCode());
} else {
response.sendError(BAD_REQUEST_STATUS.getStatusCode(), BAD_REQUEST_STATUS.getReasonPhrase());
}
@@ -488,6 +487,17 @@
}
/**
+ * 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.
*/
diff --git a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
similarity index 99%
rename from containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
rename to containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
index 39f23e8..3ccb7b8 100644
--- a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
+++ b/containers/jetty-http/src/main/java/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, 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
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServer.java b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServer.java
new file mode 100644
index 0000000..64af030
--- /dev/null
+++ b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServer.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.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/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..5122435
--- /dev/null
+++ b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServerProvider.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.jetty;
+
+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 JettyHttpServerProvider implements WebServerProvider {
+
+ @Override
+ public <T extends WebServer> T createServer(final Class<T> type, final Application application,
+ final SeBootstrap.Configuration configuration) {
+ 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) {
+ return WebServerProvider.isSupportedWebServer(JettyHttpServer.class, type, configuration)
+ ? type.cast(new JettyHttpServer(applicationClass, JerseySeBootstrapConfiguration.from(configuration)))
+ : null;
+ }
+}
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 b852e54..0000000
--- a/containers/jetty-http/src/main/java8/org/glassfish/jersey/jetty/JettyHttpContainer.java
+++ /dev/null
@@ -1,58 +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;
-
-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());
- }
-
- @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/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-servlet/pom.xml b/containers/jetty-servlet/pom.xml
index 58a2d63..090155f 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>
@@ -46,7 +46,15 @@
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
- <version>${servlet5.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-webapp</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-jetty-http</artifactId>
+ <version>${project.version}</version>
</dependency>
</dependencies>
@@ -76,200 +84,4 @@
</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>
- </activation>
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
- <version>${jetty.javax.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-webapp</artifactId>
- <version>${jetty.javax.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>
- <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/servlet/JettyWebContainerFactory.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-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java b/containers/jetty-servlet/src/main/java/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
similarity index 99%
rename from containers/jetty-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
rename to containers/jetty-servlet/src/main/java/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
index 7f46e7b..a663a50 100644
--- a/containers/jetty-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
+++ b/containers/jetty-servlet/src/main/java/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, 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
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/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 dbe8dc7..00758b4 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
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2021 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
@@ -170,6 +170,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 0f99633..cc799ff 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>
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 a7af0b6..bbd8a11 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>
@@ -122,7 +122,6 @@
<!-- not to warn about missing activation -->
<groupId>com.sun.activation</groupId>
<artifactId>jakarta.activation</artifactId>
- <version>${jakarta.activation.version}</version>
<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/ClientRequest.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientRequest.java
index f9539b0..45cb994 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
@@ -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
@@ -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/internal/HttpUrlConnector.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java
index c7e0ac2..420982f 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java
@@ -391,7 +391,7 @@
}
}
- processExtentions(request, uc);
+ processExtensions(request, uc);
request.setStreamProvider(contentLength -> {
setOutboundHeaders(request.getStringHeaders(), uc);
@@ -565,7 +565,7 @@
}
}
- private void processExtentions(ClientRequest request, HttpURLConnection uc) {
+ private void processExtensions(ClientRequest request, HttpURLConnection uc) {
connectorExtension.invoke(request, uc);
}
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 5c34d44..f60e3ba 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>
@@ -253,446 +253,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 />
@@ -732,11 +292,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/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java b/core-common/src/main/java/org/glassfish/jersey/innate/package-info.java
similarity index 75%
rename from core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
rename to core-common/src/main/java/org/glassfish/jersey/innate/package-info.java
index dd25372..b0648e7 100644
--- a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
+++ b/core-common/src/main/java/org/glassfish/jersey/innate/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 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
@@ -14,7 +14,7 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
-package org.glassfish.jersey.internal.jsr166;
-
-public interface JerseyFlowSubscriber<T> extends Flow.Subscriber<T> {
-}
+/**
+ * Jersey innate packages. The innate packages will not be opened by JPMS outside of Jersey.
+ */
+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/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java b/core-common/src/main/java/org/glassfish/jersey/innate/spi/package-info.java
similarity index 75%
copy from core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
copy to core-common/src/main/java/org/glassfish/jersey/innate/spi/package-info.java
index dd25372..3d70312 100644
--- a/core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
+++ b/core-common/src/main/java/org/glassfish/jersey/innate/spi/package-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 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
@@ -14,7 +14,7 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
-package org.glassfish.jersey.internal.jsr166;
-
-public interface JerseyFlowSubscriber<T> extends Flow.Subscriber<T> {
-}
+/**
+ * Common Jersey innate SPI classes. The innate package will not be opened by JPMS.
+ */
+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 b0984f5..35725b7 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;
@@ -255,6 +259,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}.
*/
@@ -417,6 +454,7 @@
new TypeFromStringEnum(),
new TypeValueOf(),
new CharacterProvider(),
+ new InputStreamProvider(),
new TypeFromString(),
new StringConstructor(),
new OptionalCustomProvider(manager),
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 a91521d..c7a8615 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
@@ -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
@@ -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..b6e428d 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, 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,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
@@ -77,18 +95,24 @@
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 +145,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 +226,89 @@
}
}
}
+
+ @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;
+ if (entityPartProvider.get() != null) { // else jersey-multipart module is missing
+ final Function<ContainerRequest, ?> valueSupplier = entityPartProvider.get().getValueProvider(
+ new WrappingFormParamParameter(entityPartParameter, parameter));
+ final EntityPart entityPart = (EntityPart) valueSupplier.apply(containerRequest);
+ 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 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 b1f1ff8..bf54a01 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
@@ -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.
* Copyright (c) 2018 Payara Foundation and/or its affiliates.
*
* This program and the accompanying materials are made available under the
@@ -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;
@@ -48,6 +50,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;
@@ -300,6 +303,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 e3bb3a6..b6912b0 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 938e440..c979b32 100644
--- a/docs/src/main/docbook/appendix-properties.xml
+++ b/docs/src/main/docbook/appendix-properties.xml
@@ -767,6 +767,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>
@@ -1914,4 +1986,90 @@
</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>
+ </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 e19ffe0..0501f29 100644
--- a/docs/src/main/docbook/client.xml
+++ b/docs/src/main/docbook/client.xml
@@ -670,6 +670,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>
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<SeBootstrap.Instance> 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<SeBootstrap.Instance> 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 e947990..702c511 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">
@@ -213,6 +215,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>">
@@ -231,6 +234,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>">
@@ -248,6 +252,7 @@
<!ENTITY jaxrs.ext.RuntimeDelegate.HeaderDelegate "<link xlink:href='&jaxrs.javadoc.uri;/ext/RuntimeDelegate.HeaderDelegate.html'>RuntimeDelegate.HeaderDelegate<T></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>">
@@ -478,6 +483,12 @@
<!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.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.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>">
@@ -604,11 +615,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>">
@@ -651,6 +666,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>">
@@ -790,6 +807,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>">
@@ -823,6 +842,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<T></literal>">
@@ -868,6 +888,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>">
@@ -1109,6 +1130,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 f830e90..7908ce1 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;
]>
@@ -1549,25 +1553,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>
@@ -1582,20 +1572,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));
@@ -1604,15 +1604,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
@@ -1627,34 +1627,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
@@ -1672,17 +1672,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()
@@ -1692,19 +1692,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<EntityPart> multiPartEntity = new List<>();
+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<List<EntityPart>> genericEntity = new GenericEntity<>(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<EntityPart> multiPartEntity = new List<>();
+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<List<EntityPart>> genericEntity = new GenericEntity<>(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
@@ -1861,5 +1918,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<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());
+ final GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(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<EntityPart> 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<EntityPart> getList() throws IOException {
+ final List<EntityPart> list = new LinkedList<>();
+ 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 3b68582..b999c44 100644
--- a/docs/src/main/docbook/migration.xml
+++ b/docs/src/main/docbook/migration.xml
@@ -36,7 +36,7 @@
<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>
@@ -45,16 +45,16 @@
Or require higher JDK (11+).
</para>
<para>
- Spring for now is not supported.
- </para>
- <para>
- Helidon connector for now is not supported.
- </para>
- <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>
@@ -98,13 +98,22 @@
</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>
</chapter>
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 3a0298b..c9a8476 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 71390cd..e8d46fd 100644
--- a/examples/NOTICE.md
+++ b/examples/NOTICE.md
@@ -37,13 +37,13 @@
* Project: http://aopalliance.sourceforge.net
* Copyright: Material in the public domain is not protected by copyright
-Bean Validation API 3.0.0
+Bean Validation API 3.0.2
* License: Apache License, 2.0
* Project: http://beanvalidation.org/1.1/
* 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.0.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..c8a356b 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>
@@ -88,19 +92,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/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 845f0c5..e82c293 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>
diff --git a/examples/freemarker-webapp/pom.xml b/examples/freemarker-webapp/pom.xml
index c98071a..57ae280 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>
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 9716e74..cb19296 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 f39742d..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>
@@ -95,7 +95,6 @@
<dependency>
<groupId>jakarta.activation</groupId>
<artifactId>jakarta.activation-api</artifactId>
- <version>${jakarta.activation.version}</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
diff --git a/examples/helloworld-pure-jax-rs/pom.xml b/examples/helloworld-pure-jax-rs/pom.xml
index 219d7ab..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>
@@ -98,7 +98,6 @@
<dependency>
<groupId>jakarta.activation</groupId>
<artifactId>jakarta.activation-api</artifactId>
- <version>${jakarta.activation.version}</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
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..dd7770d 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>
diff --git a/examples/helloworld-webapp/pom.xml b/examples/helloworld-webapp/pom.xml
index 616aac5..911fe4c 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>
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 b1bf7e0..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>
@@ -110,7 +110,6 @@
<dependency>
<groupId>jakarta.activation</groupId>
<artifactId>jakarta.activation-api</artifactId>
- <version>${jakarta.activation.version}</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
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..c54dd9d 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>
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..0059d0e 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>
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..de1f27d 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>
diff --git a/examples/managed-client-webapp/pom.xml b/examples/managed-client-webapp/pom.xml
index 9c9c160..34b4a5c 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>
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/multipart-webapp/pom.xml b/examples/multipart-webapp/pom.xml
index 9d18c4d..03c7db7 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>
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 8305387..040f3a7 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>
@@ -147,7 +147,6 @@
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>jakarta.activation</artifactId>
- <version>${jakarta.activation.version}</version>
</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..cd074f0 100644
--- a/examples/osgi-http-service/functional-test/pom.xml
+++ b/examples/osgi-http-service/functional-test/pom.xml
@@ -240,7 +240,6 @@
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>jakarta.activation</artifactId>
- <version>${jakarta.activation.version}</version>
</dependency>
</dependencies>
</profile>
diff --git a/examples/pom.xml b/examples/pom.xml
index de547df..8c41144 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>
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/rx-client-webapp/pom.xml b/examples/rx-client-webapp/pom.xml
index ef72671..0ef41db 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>
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..8342cf4 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>
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..c8e7598 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>
diff --git a/examples/sse-item-store-jersey-webapp/pom.xml b/examples/sse-item-store-jersey-webapp/pom.xml
index c22a6e8..69bbd7d 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>
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 0890ac4..8485e22 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..0546f02 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.0.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
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/microprofile/mp-config/pom.xml b/ext/microprofile/mp-config/pom.xml
index cf469c2..c57831f 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>
diff --git a/ext/microprofile/mp-rest-client/pom.xml b/ext/microprofile/mp-rest-client/pom.xml
index c00a41d..b01d133 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>
@@ -114,7 +114,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>
@@ -125,4 +124,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 3aea324..46a340b 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 db36d83..e01ed01 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/proxy-client/src/main/java/org/glassfish/jersey/client/proxy/RequestParameters.java b/ext/proxy-client/src/main/java/org/glassfish/jersey/client/proxy/RequestParameters.java
index 6457dd7..543e1c5 100644
--- a/ext/proxy-client/src/main/java/org/glassfish/jersey/client/proxy/RequestParameters.java
+++ b/ext/proxy-client/src/main/java/org/glassfish/jersey/client/proxy/RequestParameters.java
@@ -61,8 +61,7 @@
RequestParameters(final WebTarget newTarget, final MultivaluedMap<String, Object> headers,
final List<Cookie> cookies, final Form form) {
- this.headers = new MultivaluedHashMap<>();
- this.headers.putAll(headers);
+ this.headers = new MultivaluedHashMap<>(headers);
this.cookies = new LinkedList<>(cookies);
this.form = new Form();
this.form.asMap().putAll(form.asMap());
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 e6d7187..3566d36 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 eb5a188..3f5e8c5 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 bb9be29..6575b0a 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>
@@ -42,6 +42,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>
</dependency>
<dependency>
@@ -97,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..d422973 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>
@@ -113,6 +113,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..b3c7adc 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>
@@ -92,6 +92,12 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>jersey-jetty-connector</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
@@ -100,40 +106,4 @@
</dependency>
</dependencies>
- <profiles>
- <profile>
- <id>JettyExclude</id>
- <activation>
- <jdk>1.8</jdk>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <testExcludes>
- <testExclude>org/glassfish/jersey/media/multipart/internal/MultiPartHeaderModificationTest.java</testExclude>
- </testExcludes>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>Jetty11</id>
- <activation>
- <jdk>[11,)</jdk>
- </activation>
- <dependencies>
- <dependency>
- <groupId>org.glassfish.jersey.connectors</groupId>
- <artifactId>jersey-jetty-connector</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- </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..03bf661 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, 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
@@ -20,6 +20,8 @@
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;
@@ -45,6 +47,9 @@
context.register(MultiPartWriter.class);
+ context.register(EntityPartReader.class);
+ context.register(EntityPartWriter.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..864cec4
--- /dev/null
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/EntityPartReader.java
@@ -0,0 +1,90 @@
+/*
+ * 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.internal;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.WebApplicationException;
+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<EntityPart> 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;
+
+ @Inject
+ 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..f5c3472
--- /dev/null
+++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/EntityPartWriter.java
@@ -0,0 +1,78 @@
+/*
+ * 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.internal;
+
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.WebApplicationException;
+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<EntityPart> 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;
+
+ @Inject
+ 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/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 851c026..904214d 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
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2018 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
@@ -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.parsing.content.disposition=Error parsing content disposition: {0}
error.reading.entity=Error reading entity as {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/EntityPartTest.java b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/EntityPartTest.java
new file mode 100644
index 0000000..084238f
--- /dev/null
+++ b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/EntityPartTest.java
@@ -0,0 +1,373 @@
+/*
+ * 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));
+ }
+ }
+
+ @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/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/pom.xml b/pom.xml
index 8d650e2..78a39c3 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
@@ -473,7 +473,7 @@
<doctitle>Jersey ${jersey.version} API Documentation</doctitle>
<windowtitle>Jersey ${jersey.version} API</windowtitle>
<bottom>
- <![CDATA[Copyright © 2007-2021,
+ <![CDATA[Copyright © 2007-2022,
<a href="http://www.oracle.com">Oracle</a>
and/or its affiliates.
All Rights Reserved. Use is subject to license terms.]]>
@@ -1475,7 +1475,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>
@@ -1610,6 +1610,11 @@
<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>
@@ -2039,13 +2044,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>
@@ -2058,6 +2056,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>
@@ -2161,7 +2172,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>
@@ -2248,18 +2259,14 @@
<guava.version>31.1-jre</guava.version>
<hamcrest.version>2.2</hamcrest.version>
- <!--<helidon.version>1.4.9</helidon.version>-->
+ <!--<helidon.version>1.0.3</helidon.version>-->
<helidon.jersey.connector.version>3.0.2</helidon.jersey.connector.version>
<xmlunit.version>2.9.0</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>
<httpclient.version>4.5.14</httpclient.version>
<httpclient5.version>5.2.1</httpclient5.version>
<jackson.version>2.14.1</jackson.version>
<javassist.version>3.29.0-GA</javassist.version>
- <jboss.logging.version>3.4.2.Final</jboss.logging.version>
- <jersey1.version>1.19.3</jersey1.version>
- <jersey1.last.final.version>${jersey1.version}</jersey1.last.final.version>
+ <jboss.logging.version>3.5.0.Final</jboss.logging.version>
<jettison.version>1.3.7</jettison.version> <!-- TODO: 1.3.8 doesn't work; AbstractJsonTest complexBeanWithAttributes -->
<jmh.version>1.35</jmh.version>
<jmockit.version>1.49</jmockit.version>
@@ -2280,15 +2287,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.3</slf4j.version>
+ <slf4j.version>2.0.5</slf4j.version>
<spring6.version>6.0.0-M3</spring6.version>
<testng.version>7.6.1</testng.version>
<testng6.version>6.9.13.6</testng6.version>
<!-- Jakartified, eligible for CQ -->
- <weld.version>4.0.2.Final</weld.version>
+ <weld.version>5.0.1.Final</weld.version>
<weld3.version>3.1.7.SP1</weld3.version>
- <validation.impl.version>7.0.5.Final</validation.impl.version>
+ <validation.impl.version>8.0.0.Final</validation.impl.version>
<!-- END of Jakartified, eligible for CQ -->
<wiremock.version>2.27.2</wiremock.version>
<xerces.version>2.12.2</xerces.version>
@@ -2297,49 +2308,49 @@
<graalvm.version>20.3.2</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.1</gf.impl.version>
<!-- Jakartified -->
- <cdi.api.version>3.0.0</cdi.api.version>
+ <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.0</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>
- <jsp.version>3.0.0</jsp.version>
- <jstl.version>2.0.0</jstl.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.0-M2</hk2.config.version>
+ <jsp.version>3.1.0</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.0</istack.commons.runtime.version>
- <jakarta.activation-api.version>2.0.1</jakarta.activation-api.version>
+ <istack.commons.runtime.version>4.1.1</istack.commons.runtime.version>
+ <jakarta.activation-api.version>2.1.0</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>
+ <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.0</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.1</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.14</jetty.version>
- <jetty9.version>9.4.49.v20220914</jetty9.version>
+ <jetty9.version>9.4.51.v20230217</jetty9.version>
<jetty.plugin.version>11.0.14</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.0</jsonp.ri.version>
- <jsonp.jaxrs.version>1.0.0</jsonp.jaxrs.version>
- <moxy.version>3.0.2</moxy.version>
- <yasson.version>2.0.4</yasson.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.0</moxy.version>
+ <yasson.version>3.0.2</yasson.version>
<!-- END of Jakartified -->
<javax.annotation.version>1.3.2</javax.annotation.version> <!--Deprecated, used only for @generated annotation in perf tests -->
- <mimepull.version>1.9.13</mimepull.version>
+ <mimepull.version>1.9.15</mimepull.version>
</properties>
</project>
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 30bbfde..47d815f 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>
@@ -36,9 +36,9 @@
</description>
<properties>
- <groovy.version>3.0.2</groovy.version>
- <groovy-eclipse-compiler.version>3.6.0-03</groovy-eclipse-compiler.version>
- <groovy-eclipse-batch.version>3.0.2-02</groovy-eclipse-batch.version>
+ <groovy.version>3.0.9</groovy.version>
+ <groovy-eclipse-compiler.version>3.7.0</groovy-eclipse-compiler.version>
+ <groovy-eclipse-batch.version>3.0.8-01</groovy-eclipse-batch.version>
<maven.version>3.8.6</maven.version>
<maven-plugin.version>3.6.4</maven-plugin.version>
</properties>
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/pom.xml b/test-framework/providers/jetty/pom.xml
index 968e499..7e6ed8e 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>
@@ -44,148 +44,4 @@
</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/*.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/JettyTestContainerFactory.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/src/main/java11/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java b/test-framework/providers/jetty/src/main/java/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
similarity index 98%
rename from test-framework/providers/jetty/src/main/java11/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
rename to test-framework/providers/jetty/src/main/java/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
index e5dba36..2ce4577 100644
--- a/test-framework/providers/jetty/src/main/java11/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
+++ b/test-framework/providers/jetty/src/main/java/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) 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
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/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 ed62ce6..f271da3 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>
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 35dd31c..90ddafe 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>
@@ -217,44 +222,6 @@
<profiles>
<profile>
- <id>JettyTestExclude</id>
- <activation>
- <jdk>1.8</jdk>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <executions>
- <execution>
- <id>default-testCompile</id>
- <phase>test-compile</phase>
- <configuration>
- <testExcludes>
- <testExclude>org/glassfish/jersey/tests/e2e/client/connector/proxy/Proxy*Test.java</testExclude>
- </testExcludes>
- </configuration>
- <goals>
- <goal>testCompile</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </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 -->
@@ -281,4 +248,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..3d5fb1d 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,16 @@
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 = 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[2] = new JettyConnectorProvider();
+ providers[3] = new ApacheConnectorProvider();
+ providers[4] = new Apache5ConnectorProvider();
+ providers[5] = new NettyConnectorProvider();
+ providers[6] = new JavaNetHttpConnectorProvider();
+
return Arrays.asList(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 551d72c..697165f 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
@@ -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
@@ -58,10 +58,10 @@
import org.glassfish.jersey.client.ClientConfig;
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 +107,13 @@
{new JettyConnectorProvider(), false, false}, // change to true when JERSEY-2341 fixed
{new ApacheConnectorProvider(), false, false}, // change to true when JERSEY-2341 fixed
{new Apache5ConnectorProvider(), false, false}, // change to true when JERSEY-2341 fixed
+ {new JavaNetHttpConnectorProvider(), true, false},
{new HttpUrlConnectorProvider(), true, true},
{new GrizzlyConnectorProvider(), false, true}, // change to true when JERSEY-2341 fixed
{new JettyConnectorProvider(), false, true}, // change to true when JERSEY-2341 fixed
{new ApacheConnectorProvider(), false, true}, // change to true when JERSEY-2341 fixed
{new Apache5ConnectorProvider(), false, true}, // change to true when JERSEY-2341 fixed
+ {new JavaNetHttpConnectorProvider(), true, false},
});
}
@@ -119,10 +121,6 @@
public Collection<DynamicContainer> generateTests() {
Collection<DynamicContainer> tests = new ArrayList<>();
testData().forEach(arr -> {
- if (JdkVersion.getJdkVersion().getMajor() < 11
- && arr[0].getClass().getName().contains("Jetty")) {
- return;
- }
RequestHeaderModificationsTemplateTest test = new RequestHeaderModificationsTemplateTest(
(ConnectorProvider) arr[0], (boolean) arr[1], (boolean) arr[2]) {};
tests.add(TestHelper.toTestContainer(test, String.format("%s (%s, %s, %s)",
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..6d9b144 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,15 @@
* @return test parameters.
*/
public static Stream<ConnectorProvider> testData() {
- int size = JdkVersion.getJdkVersion().getMajor() < 11 ? 4 : 5;
+ int size = 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[2] = new JettyConnectorProvider();
+ providers[3] = new ApacheConnectorProvider();
+ providers[4] = new Apache5ConnectorProvider();
+ providers[5] = new JavaNetHttpConnectorProvider();
+
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-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..5c6b7fd 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>
diff --git a/tests/e2e/pom.xml b/tests/e2e/pom.xml
index 489b94c..834484f 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>
@@ -198,26 +198,6 @@
</properties>
</profile>
<profile>
- <id>JettyExclude</id>
- <activation>
- <jdk>1.8</jdk>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <testExcludes>
- <testExclude>org/glassfish/jersey/tests/e2e/container/Jersey2462Test.java</testExclude>
- <testExclude>org/glassfish/jersey/tests/e2e/container/JettyEmptyHeaderParamTest.java</testExclude>
- </testExcludes>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
<id>sonar</id>
<build>
<pluginManagement>
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/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..c257162 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>
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 3cca4bd..c8fba6a 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>
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/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/jaxrs-component-inject/pom.xml b/tests/integration/jaxrs-component-inject/pom.xml
index 1c69d67..a4861bd 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>
diff --git a/tests/integration/jersey-1107/pom.xml b/tests/integration/jersey-1107/pom.xml
index ede5afa..4d6cb66 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>
diff --git a/tests/integration/jersey-1223/pom.xml b/tests/integration/jersey-1223/pom.xml
index dee0979..5d02d7a 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>
diff --git a/tests/integration/jersey-1604/pom.xml b/tests/integration/jersey-1604/pom.xml
index 157a853..91fa17d 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>
diff --git a/tests/integration/jersey-1667/pom.xml b/tests/integration/jersey-1667/pom.xml
index b735cb7..67a5ea3 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>
diff --git a/tests/integration/jersey-1883/pom.xml b/tests/integration/jersey-1883/pom.xml
index 485a0a4..892e1a6 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>
diff --git a/tests/integration/jersey-1928/pom.xml b/tests/integration/jersey-1928/pom.xml
index 284ef02..f855c70 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>
diff --git a/tests/integration/jersey-1960/pom.xml b/tests/integration/jersey-1960/pom.xml
index 86d4533..e8898f3 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>
diff --git a/tests/integration/jersey-1964/pom.xml b/tests/integration/jersey-1964/pom.xml
index 964c9ce..fbb9c24 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>
diff --git a/tests/integration/jersey-2031/pom.xml b/tests/integration/jersey-2031/pom.xml
index 2917b62..f075558 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>
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..8a76b08 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>
diff --git a/tests/integration/jersey-2164/pom.xml b/tests/integration/jersey-2164/pom.xml
index 0a1de3c..7f7380f 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>
diff --git a/tests/integration/jersey-2167/pom.xml b/tests/integration/jersey-2167/pom.xml
index e57690d..7d93a9e 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>
diff --git a/tests/integration/jersey-2176/pom.xml b/tests/integration/jersey-2176/pom.xml
index 2f15b54..53e5a76 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>
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..a8dbc2d 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>
diff --git a/tests/integration/jersey-2255/pom.xml b/tests/integration/jersey-2255/pom.xml
index e4d70e0..81c8435 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>
diff --git a/tests/integration/jersey-2322/pom.xml b/tests/integration/jersey-2322/pom.xml
index 47f6087..59460b1 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,14 +58,6 @@
<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>
diff --git a/tests/integration/jersey-2335/pom.xml b/tests/integration/jersey-2335/pom.xml
index 0c0e722..25d3646 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>
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..e3b182e 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>
diff --git a/tests/integration/jersey-2612/pom.xml b/tests/integration/jersey-2612/pom.xml
index e3c014b..c637e87 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>
diff --git a/tests/integration/jersey-2637/pom.xml b/tests/integration/jersey-2637/pom.xml
index 2589cd6..692a268 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>
diff --git a/tests/integration/jersey-2654/pom.xml b/tests/integration/jersey-2654/pom.xml
index eeb36ac..6586fc3 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>
diff --git a/tests/integration/jersey-2673/pom.xml b/tests/integration/jersey-2673/pom.xml
index df3b9db..8563e75 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>
diff --git a/tests/integration/jersey-2689/pom.xml b/tests/integration/jersey-2689/pom.xml
index 82439d5..56e5822 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>
diff --git a/tests/integration/jersey-2704/pom.xml b/tests/integration/jersey-2704/pom.xml
index 6587e06..a3b3123 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>
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..579495c 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>
diff --git a/tests/integration/jersey-2846/pom.xml b/tests/integration/jersey-2846/pom.xml
index cf10467..f682da1 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>
diff --git a/tests/integration/jersey-2878/pom.xml b/tests/integration/jersey-2878/pom.xml
index 22925a8..3c5fb91 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>
diff --git a/tests/integration/jersey-2892/pom.xml b/tests/integration/jersey-2892/pom.xml
index be6dd22..40d31c8 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>
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..b66d29b 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>
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..3505996 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>
diff --git a/tests/integration/jersey-5087/pom.xml b/tests/integration/jersey-5087/pom.xml
index 7f97ce8..b9ad43d 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..6014048 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>
diff --git a/tests/integration/microprofile/config/helidon/pom.xml b/tests/integration/microprofile/config/helidon/pom.xml
index 369675c..8490dc2 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 e5f263e..369752e 100644
--- a/tests/integration/microprofile/rest-client-tck/pom.xml
+++ b/tests/integration/microprofile/rest-client-tck/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2019, 2022 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
@@ -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>
diff --git a/tests/integration/microprofile/rest-client/pom.xml b/tests/integration/microprofile/rest-client/pom.xml
index d277612..df65c05 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 7e5c726..3f2a60b 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>
@@ -34,21 +34,55 @@
<modules>
<module>asm</module>
+ <module>async-jersey-filter</module>
<module>cdi-integration</module>
<module>client-connector-provider</module>
<module>ejb-multimodule</module>
<module>ejb-multimodule-reload</module>
<module>ejb-test-webapp</module>
+ <module>externalproperties</module>
+ <module>jaxrs-component-inject</module>
<module>j-376</module>
<module>j-441</module>
<module>j-59</module>
+ <module>jersey-780</module>
+ <module>jersey-1107</module>
+ <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>
+ <module>jersey-1964</module>
+ <module>jersey-2031</module>
<module>jersey-2136</module>
<module>jersey-2137</module>
<module>jersey-2154</module>
+ <module>jersey-2160</module>
+ <module>jersey-2164</module>
+ <module>jersey-2167</module>
+ <module>jersey-2176</module>
+ <module>jersey-2184</module>
+ <module>jersey-2255</module>
+ <module>jersey-2322</module>
+ <module>jersey-2335</module>
<module>jersey-2421</module>
+ <module>jersey-2551</module>
+ <module>jersey-2612</module>
+ <module>jersey-2637</module>
+ <module>jersey-2654</module>
+ <module>jersey-2673</module>
+ <module>jersey-2689</module>
+ <module>jersey-2704</module>
<module>jersey-2776</module>
+ <module>jersey-2794</module>
+ <module>jersey-2846</module>
+ <module>jersey-2878</module>
+ <module>jersey-2892</module>
<module>jersey-3662</module>
<module>jersey-3670</module>
+ <module>jersey-3796</module>
<module>jersey-3992</module>
<module>jersey-4003</module>
<module>jersey-4099</module>
@@ -57,30 +91,65 @@
<module>jersey-4542</module>
<module>jersey-4697</module>
<module>jersey-4722</module>
- <module>microprofile</module>
- <module>reactive-streams</module>
+ <module>jersey-4949</module>
<module>jersey-5087</module>
+ <module>microprofile</module>
+ <module>property-check</module>
+ <module>reactive-streams</module>
+ <module>security-digest</module>
+ <module>servlet-2.5-autodiscovery-1</module>
+ <module>servlet-2.5-autodiscovery-2</module>
+ <module>servlet-2.5-filter</module>
+ <module>servlet-2.5-inflector-1</module>
+ <module>servlet-2.5-init-1</module>
+ <module>servlet-2.5-init-2</module>
+ <module>servlet-2.5-init-3</module>
+ <module>servlet-2.5-init-4</module>
+ <module>servlet-2.5-init-5</module>
+ <module>servlet-2.5-init-6</module>
+ <module>servlet-2.5-init-7</module>
+ <module>servlet-2.5-init-8</module>
+ <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>
+ <module>servlet-3-init-3</module>
+ <module>servlet-3-init-4</module>
+ <module>servlet-3-init-5</module>
+ <module>servlet-3-init-6</module>
+ <module>servlet-3-init-7</module>
+ <module>servlet-3-init-8</module>
+ <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>spring4</module>-->
+ <!-- <module>spring5</module>-->
+ <module>sonar-test</module>
+ <module>thin-server</module>
+ <module>tracing-support</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>
@@ -122,90 +191,6 @@
</build>
</profile>
<profile>
- <id>Jetty11</id>
- <activation>
- <jdk>[11,)</jdk>
- </activation>
- <modules>
- <module>async-jersey-filter</module>
- <module>externalproperties</module>
- <module>jaxrs-component-inject</module>
- <module>jersey-780</module>
- <module>jersey-1107</module>
- <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>
- <module>jersey-1964</module>
- <module>jersey-2031</module>
- <module>jersey-2160</module>
- <module>jersey-2164</module>
- <module>jersey-2167</module>
- <module>jersey-2176</module>
- <module>jersey-2184</module>
- <module>jersey-2255</module>
- <module>jersey-2322</module>
- <module>jersey-2335</module>
- <module>jersey-2551</module>
- <module>jersey-2612</module>
- <module>jersey-2637</module>
- <module>jersey-2654</module>
- <module>jersey-2673</module>
- <module>jersey-2689</module>
- <module>jersey-2704</module>
- <module>jersey-2794</module>
- <module>jersey-2846</module>
- <module>jersey-2878</module>
- <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>
- <module>servlet-2.5-filter</module>
- <module>servlet-2.5-inflector-1</module>
- <module>servlet-2.5-init-1</module>
- <module>servlet-2.5-init-2</module>
- <module>servlet-2.5-init-3</module>
- <module>servlet-2.5-init-4</module>
- <module>servlet-2.5-init-5</module>
- <module>servlet-2.5-init-6</module>
- <module>servlet-2.5-init-7</module>
- <module>servlet-2.5-init-8</module>
- <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>
- <module>servlet-3-init-3</module>
- <module>servlet-3-init-4</module>
- <module>servlet-3-init-5</module>
- <module>servlet-3-init-6</module>
- <module>servlet-3-init-7</module>
- <module>servlet-3-init-8</module>
- <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>
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..b33f41b 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>
diff --git a/tests/integration/servlet-2.5-autodiscovery-1/pom.xml b/tests/integration/servlet-2.5-autodiscovery-1/pom.xml
index 07dfe06..032ca7a 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>
diff --git a/tests/integration/servlet-2.5-autodiscovery-2/pom.xml b/tests/integration/servlet-2.5-autodiscovery-2/pom.xml
index 73c2778..db70dcd 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>
diff --git a/tests/integration/servlet-2.5-filter/pom.xml b/tests/integration/servlet-2.5-filter/pom.xml
index 8420c45..911927b 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>
diff --git a/tests/integration/servlet-2.5-inflector-1/pom.xml b/tests/integration/servlet-2.5-inflector-1/pom.xml
index 0e6bfae..98ff984 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>
diff --git a/tests/integration/servlet-2.5-init-1/pom.xml b/tests/integration/servlet-2.5-init-1/pom.xml
index 3495b3b..83adf6a 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>
diff --git a/tests/integration/servlet-2.5-init-2/pom.xml b/tests/integration/servlet-2.5-init-2/pom.xml
index 838084a..fe1bff8 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>
diff --git a/tests/integration/servlet-2.5-init-3/pom.xml b/tests/integration/servlet-2.5-init-3/pom.xml
index a258bbd..3623e99 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>
diff --git a/tests/integration/servlet-2.5-init-4/pom.xml b/tests/integration/servlet-2.5-init-4/pom.xml
index f90f731..16dbc42 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>
diff --git a/tests/integration/servlet-2.5-init-5/pom.xml b/tests/integration/servlet-2.5-init-5/pom.xml
index 9a7e50d..f9d9dcd 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>
diff --git a/tests/integration/servlet-2.5-init-6/pom.xml b/tests/integration/servlet-2.5-init-6/pom.xml
index e3f9041..44af411 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>
diff --git a/tests/integration/servlet-2.5-init-7/pom.xml b/tests/integration/servlet-2.5-init-7/pom.xml
index c27e43a..dff3108 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>
diff --git a/tests/integration/servlet-2.5-init-8/pom.xml b/tests/integration/servlet-2.5-init-8/pom.xml
index f22b922..7c9ded4 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>
diff --git a/tests/integration/servlet-2.5-mvc-1/pom.xml b/tests/integration/servlet-2.5-mvc-1/pom.xml
index 947d89c..ecdae06 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>
diff --git a/tests/integration/servlet-2.5-mvc-2/pom.xml b/tests/integration/servlet-2.5-mvc-2/pom.xml
index b7e57c7..cff9992 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>
diff --git a/tests/integration/servlet-2.5-mvc-3/pom.xml b/tests/integration/servlet-2.5-mvc-3/pom.xml
index fc449a2..453a58c 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>
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..bc52292 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>
diff --git a/tests/integration/servlet-3-chunked-io/pom.xml b/tests/integration/servlet-3-chunked-io/pom.xml
index 4c5e676..de086d4 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>
diff --git a/tests/integration/servlet-3-filter/pom.xml b/tests/integration/servlet-3-filter/pom.xml
index 924c436..2778521 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>
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..3eaca79 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>
diff --git a/tests/integration/servlet-3-init-1/pom.xml b/tests/integration/servlet-3-init-1/pom.xml
index 33320eb..286d63f 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>
diff --git a/tests/integration/servlet-3-init-2/pom.xml b/tests/integration/servlet-3-init-2/pom.xml
index 3333c4f..025afca 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>
diff --git a/tests/integration/servlet-3-init-3/pom.xml b/tests/integration/servlet-3-init-3/pom.xml
index ee52d61..15d3802 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>
diff --git a/tests/integration/servlet-3-init-4/pom.xml b/tests/integration/servlet-3-init-4/pom.xml
index 3f6f092..ed282aa 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>
diff --git a/tests/integration/servlet-3-init-5/pom.xml b/tests/integration/servlet-3-init-5/pom.xml
index 9d3f75c..5404797 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>
diff --git a/tests/integration/servlet-3-init-6/pom.xml b/tests/integration/servlet-3-init-6/pom.xml
index 110d574..e67e339 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>
diff --git a/tests/integration/servlet-3-init-7/pom.xml b/tests/integration/servlet-3-init-7/pom.xml
index 30e5bac..58cf49e 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>
diff --git a/tests/integration/servlet-3-init-8/pom.xml b/tests/integration/servlet-3-init-8/pom.xml
index cc128c2..a7127d4 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>
diff --git a/tests/integration/servlet-3-init-9/pom.xml b/tests/integration/servlet-3-init-9/pom.xml
index 68ee240..4f9341b 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>
diff --git a/tests/integration/servlet-3-init-provider/pom.xml b/tests/integration/servlet-3-init-provider/pom.xml
index 634957e..723b03b 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>
diff --git a/tests/integration/servlet-3-params/pom.xml b/tests/integration/servlet-3-params/pom.xml
index 11eadb7..e820f67 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>
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..c995f1d 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>
@@ -77,12 +84,11 @@
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
- <!--TODO jakartify this -->
<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..d1c38f3 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>
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..873c076 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>
diff --git a/tests/integration/servlet-tests/pom.xml b/tests/integration/servlet-tests/pom.xml
index 5363e82..5dc5479 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>
diff --git a/tests/integration/sonar-test/pom.xml b/tests/integration/sonar-test/pom.xml
index 7895b97..cf34796 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>
diff --git a/tests/integration/spring6/pom.xml b/tests/integration/spring6/pom.xml
index 43a6859..ec6c690 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>
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%
copy from core-common/src/main/java8/org/glassfish/jersey/internal/jsr166/JerseyFlowSubscriber.java
copy 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 a939fd7..03d3045 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>
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/tests/jersey-tck/j2ee.pass b/tests/jersey-tck/j2ee.pass
new file mode 100644
index 0000000..7cd0e34
--- /dev/null
+++ b/tests/jersey-tck/j2ee.pass
@@ -0,0 +1,16 @@
+#
+# 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
+#
+AS_ADMIN_USERPASSWORD=j2ee
\ No newline at end of file
diff --git a/tests/jersey-tck/javajoe.pass b/tests/jersey-tck/javajoe.pass
new file mode 100644
index 0000000..f06be72
--- /dev/null
+++ b/tests/jersey-tck/javajoe.pass
@@ -0,0 +1,16 @@
+#
+# 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
+#
+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..49e0f82
--- /dev/null
+++ b/tests/jersey-tck/pom.xml
@@ -0,0 +1,544 @@
+<?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.1</jersey.version> <!-- the public version that pass the tck -->
+ <glassfish.container.version>7.0.1</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>
+ </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>${project.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..c4558a8 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, 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
@@ -57,7 +57,7 @@
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("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 025ebb1..901478f 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,6 +107,14 @@
</build>
</profile>
<profile>
+ <id>jersey-tck</id>
+ <modules>
+ <module>jersey-tck</module>
+ </modules>
+ <build>
+ </build>
+ </profile>
+ <profile>
<id>JDK11+</id>
<activation>
<jdk>[11,)</jdk>
diff --git a/tests/release-test/pom.xml b/tests/release-test/pom.xml
index 00fa896..ce02a6f 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>
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>