Upgrade to Jetty 12
Signed-off-by: Steffen Nießing <zuniquex@protonmail.com>
diff --git a/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/pom.xml b/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/pom.xml
index f800680..dd79010 100644
--- a/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/pom.xml
@@ -38,14 +38,14 @@
</dependency> -->
<dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-servlet</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-servlet</artifactId>
<version>\${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-webapp</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-webapp</artifactId>
<version>\${jetty.version}</version>
<scope>provided</scope>
</dependency>
@@ -89,8 +89,8 @@
</executions>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
<version>\${jetty.version}</version>
<configuration>
<contextPath>/</contextPath>
@@ -117,7 +117,7 @@
<properties>
<jersey.version>${project.version}</jersey.version>
- <jetty.version>11.0.15</jetty.version>
+ <jetty.version>12.0.0</jetty.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<surefire.mvn.plugin.version>3.1.2</surefire.mvn.plugin.version>
<war.mvn.plugin.version>3.4.0</war.mvn.plugin.version>
diff --git a/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/src/main/java/heroku/Main.java b/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/src/main/java/heroku/Main.java
index 06594bf..30d0665 100644
--- a/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/src/main/java/heroku/Main.java
+++ b/archetypes/jersey-heroku-webapp/src/main/resources/archetype-resources/src/main/java/heroku/Main.java
@@ -1,7 +1,7 @@
package ${package}.heroku;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.ee10.webapp.WebAppContext;
/**
* This class launches the web application in an embedded Jetty container. This is the entry point to your application. The Java
@@ -30,7 +30,7 @@
final String webappDirLocation = "src/main/webapp/";
root.setDescriptor(webappDirLocation + "/WEB-INF/web.xml");
- root.setResourceBase(webappDirLocation);
+ root.setBaseResourceAsString(webappDirLocation);
server.setHandler(root);
diff --git a/bom/pom.xml b/bom/pom.xml
index feb6cba..1bcf00e 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -90,6 +90,11 @@
</dependency>
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>jersey-jetty11-connector</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-jdk-connector</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/connectors/jetty-connector/pom.xml b/connectors/jetty-connector/pom.xml
index 9b2ff73..f55209a 100644
--- a/connectors/jetty-connector/pom.xml
+++ b/connectors/jetty-connector/pom.xml
@@ -34,6 +34,10 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <java11.build.outputDirectory>${project.basedir}/target</java11.build.outputDirectory>
+ <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
+ <java17.build.outputDirectory>${project.basedir}/target17</java17.build.outputDirectory>
+ <java17.sourceDirectory>${project.basedir}/src/main/java17</java17.sourceDirectory>
</properties>
<dependencies>
@@ -47,16 +51,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-util</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
@@ -125,4 +119,144 @@
</plugin>
</plugins>
</build>
+
+ <profiles>
+ <profile>
+ <id>JettyExclude</id>
+ <activation>
+ <jdk>[11,17)</jdk>
+ </activation>
+ <properties>
+ <jetty.version>${jetty11.version}</jetty.version>
+ </properties>
+ <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>
+ <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>JettyInclude</id>
+ <activation>
+ <jdk>[17,)</jdk>
+ </activation>
+ <build>
+ <directory>${java17.build.outputDirectory}</directory>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${java17.sourceDirectory}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>copyJDK17FilesToMultiReleaseJar</id>
+ <activation>
+ <file>
+ <!-- ${java17.build.outputDirectory} does not work here -->
+ <exists>target17/classes/org/glassfish/jersey/jetty/connector/JettyConnector.class</exists>
+ </file>
+ <jdk>[11,17)</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-jdk17-classes</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${java11.build.outputDirectory}/classes/META-INF/versions/17</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${java17.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-jdk17-sources</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <property name="sources-jar" value="${java11.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+ <echo>sources-jar: ${sources-jar}</echo>
+ <zip destfile="${sources-jar}" update="true">
+ <zipfileset dir="${java17.sourceDirectory}" prefix="META-INF/versions/17"/>
+ </zip>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
similarity index 61%
copy from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
copy to connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
index dfd3b79..50ec6bd 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
+++ b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,16 +18,10 @@
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.core.Configurable;
import jakarta.ws.rs.core.Configuration;
-
-import org.glassfish.jersey.client.Initializable;
import org.glassfish.jersey.client.spi.Connector;
import org.glassfish.jersey.client.spi.ConnectorProvider;
-import org.eclipse.jetty.client.HttpClient;
-import org.glassfish.jersey.internal.util.JdkVersion;
-
/**
* A {@link ConnectorProvider} for Jersey {@link Connector connector}
* instances that utilize the Jetty HTTP Client to send and receive
@@ -86,43 +80,6 @@
@Override
public Connector getConnector(Client client, Configuration runtimeConfig) {
- if (JdkVersion.getJdkVersion().getMajor() < 11) {
- throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
- }
- return new JettyConnector(client, runtimeConfig);
- }
-
- /**
- * Retrieve the underlying Jetty {@link org.eclipse.jetty.client.HttpClient} instance from
- * {@link org.glassfish.jersey.client.JerseyClient} or {@link org.glassfish.jersey.client.JerseyWebTarget}
- * configured to use {@code JettyConnectorProvider}.
- *
- * @param component {@code JerseyClient} or {@code JerseyWebTarget} instance that is configured to use
- * {@code JettyConnectorProvider}.
- * @return underlying Jetty {@code HttpClient} instance.
- *
- * @throws java.lang.IllegalArgumentException in case the {@code component} is neither {@code JerseyClient}
- * nor {@code JerseyWebTarget} instance or in case the component
- * is not configured to use a {@code JettyConnectorProvider}.
- * @since 2.8
- */
- public static HttpClient getHttpClient(Configurable<?> component) {
- if (!(component instanceof Initializable)) {
- throw new IllegalArgumentException(
- LocalizationMessages.INVALID_CONFIGURABLE_COMPONENT_TYPE(component.getClass().getName()));
- }
-
- final Initializable<?> initializable = (Initializable<?>) component;
- Connector connector = initializable.getConfiguration().getConnector();
- if (connector == null) {
- initializable.preInitialize();
- connector = initializable.getConfiguration().getConnector();
- }
-
- if (connector instanceof JettyConnector) {
- return ((JettyConnector) connector).getHttpClient();
- }
-
- throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED());
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
}
}
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
similarity index 93%
rename from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
rename to connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
index b061ef5..6453521 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
+++ b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
similarity index 96%
rename from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
rename to connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
index dc43fb3..2b9e8b2 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
+++ b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnector.java
similarity index 88%
copy from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
copy to connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnector.java
index 825a231..4ae73dd 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
+++ b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnector.java
@@ -41,20 +41,24 @@
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.core.Configuration;
-import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MultivaluedMap;
import javax.net.ssl.SSLContext;
-import jakarta.ws.rs.ext.RuntimeDelegate;
+import org.eclipse.jetty.client.AuthenticationStore;
+import org.eclipse.jetty.client.BasicAuthentication;
+import org.eclipse.jetty.client.ByteBufferRequestContent;
+import org.eclipse.jetty.client.ContentResponse;
+import org.eclipse.jetty.client.FutureResponseListener;
import org.eclipse.jetty.client.HttpClientTransport;
-import org.eclipse.jetty.client.HttpRequest;
-import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
+import org.eclipse.jetty.client.OutputStreamRequestContent;
+import org.eclipse.jetty.client.Request;
+import org.eclipse.jetty.client.Response;
+import org.eclipse.jetty.client.Result;
+import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
+import org.eclipse.jetty.client.transport.HttpRequest;
+import org.eclipse.jetty.http.HttpCookieStore;
import org.eclipse.jetty.io.ClientConnector;
-import org.eclipse.jetty.client.util.BasicAuthentication;
-import org.eclipse.jetty.client.util.BytesContentProvider;
-import org.eclipse.jetty.client.util.FutureResponseListener;
-import org.eclipse.jetty.client.util.OutputStreamContentProvider;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.ClientRequest;
import org.glassfish.jersey.client.ClientResponse;
@@ -70,16 +74,9 @@
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpProxy;
import org.eclipse.jetty.client.ProxyConfiguration;
-import org.eclipse.jetty.client.api.AuthenticationStore;
-import org.eclipse.jetty.client.api.ContentProvider;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.api.Request;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
-import org.eclipse.jetty.util.HttpCookieStore;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
@@ -138,7 +135,7 @@
private static final Logger LOGGER = Logger.getLogger(JettyConnector.class.getName());
private final HttpClient client;
- private final CookieStore cookieStore;
+ private final HttpCookieStore cookieStore;
private final Configuration configuration;
private final Optional<Integer> syncListenerResponseMaxSize;
@@ -203,7 +200,7 @@
proxy.ifPresent(clientProxy -> {
final ProxyConfiguration proxyConfig = client.getProxyConfiguration();
final URI u = clientProxy.uri();
- proxyConfig.getProxies().add(new HttpProxy(u.getHost(), u.getPort()));
+ proxyConfig.addProxy(new HttpProxy(u.getHost(), u.getPort()));
if (clientProxy.userName() != null) {
auth.addAuthentication(new BasicAuthentication(u, "<<ANY_REALM>>",
@@ -212,13 +209,13 @@
});
if (disableCookies) {
- client.setCookieStore(new HttpCookieStore.Empty());
+ client.setHttpCookieStore(new HttpCookieStore.Empty());
}
final Object slResponseMaxSize = configuration.getProperties()
- .get(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE);
+ .get(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE);
if (slResponseMaxSize != null && slResponseMaxSize instanceof Integer
- && (Integer) slResponseMaxSize > 0) {
+ && (Integer) slResponseMaxSize > 0) {
this.syncListenerResponseMaxSize = Optional.of((Integer) slResponseMaxSize);
}
else {
@@ -230,7 +227,7 @@
} catch (final Exception e) {
throw new ProcessingException("Failed to start the client.", e);
}
- this.cookieStore = client.getCookieStore();
+ this.cookieStore = client.getHttpCookieStore();
}
/**
@@ -249,7 +246,7 @@
* @return the {@link CookieStore} instance or null when
* JettyClientProperties.DISABLE_COOKIES set to true.
*/
- public CookieStore getCookieStore() {
+ public HttpCookieStore getCookieStore() {
return cookieStore;
}
@@ -257,9 +254,9 @@
public ClientResponse apply(final ClientRequest jerseyRequest) throws ProcessingException {
final Request jettyRequest = translateRequest(jerseyRequest);
final Map<String, String> clientHeadersSnapshot = writeOutBoundHeaders(jerseyRequest.getHeaders(), jettyRequest);
- final ContentProvider entity = getBytesProvider(jerseyRequest);
+ final Request.Content entity = getBytesProvider(jerseyRequest);
if (entity != null) {
- jettyRequest.content(entity);
+ jettyRequest.body(entity);
}
try {
@@ -269,12 +266,12 @@
}
else {
final FutureResponseListener listener
- = new FutureResponseListener(jettyRequest, syncListenerResponseMaxSize.get());
+ = new FutureResponseListener(jettyRequest, syncListenerResponseMaxSize.get());
jettyRequest.send(listener);
jettyResponse = listener.get();
}
HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, jerseyRequest.getHeaders(),
- JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
+ JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
final jakarta.ws.rs.core.Response.StatusType status = jettyResponse.getReason() == null
? Statuses.from(jettyResponse.getStatus())
@@ -352,7 +349,7 @@
return stringHeaders;
}
- private ContentProvider getBytesProvider(final ClientRequest clientRequest) {
+ private Request.Content getBytesProvider(final ClientRequest clientRequest) {
final Object entity = clientRequest.getEntity();
if (entity == null) {
@@ -372,17 +369,22 @@
} catch (final IOException e) {
throw new ProcessingException("Failed to write request entity.", e);
}
- return new BytesContentProvider(outputStream.toByteArray());
+ return new ByteBufferRequestContent(ByteBuffer.wrap(outputStream.toByteArray()));
}
- private ContentProvider getStreamProvider(final ClientRequest clientRequest) {
+ private Request.Content getStreamProvider(final ClientRequest clientRequest) {
final Object entity = clientRequest.getEntity();
if (entity == null) {
return null;
}
- final OutputStreamContentProvider streamContentProvider = new OutputStreamContentProvider();
+ String contentTypeHeader = clientRequest.getRequestHeaders()
+ .getFirst(HttpHeader.CONTENT_TYPE.asString());
+
+ String contentType = contentTypeHeader != null ? contentTypeHeader : "application/octet-stream";
+
+ final OutputStreamRequestContent streamContentProvider = new OutputStreamRequestContent(contentType);
clientRequest.setStreamProvider(new OutboundMessageContext.StreamProvider() {
@Override
public OutputStream getOutputStream(final int contentLength) throws IOException {
@@ -392,12 +394,12 @@
return streamContentProvider;
}
- private void processContent(final ClientRequest clientRequest, final ContentProvider entity) throws IOException {
+ private void processContent(final ClientRequest clientRequest, final Request.Content entity) throws IOException {
if (entity == null) {
return;
}
- final OutputStreamContentProvider streamContentProvider = (OutputStreamContentProvider) entity;
+ final OutputStreamRequestContent streamContentProvider = (OutputStreamRequestContent) entity;
try (final OutputStream output = streamContentProvider.getOutputStream()) {
clientRequest.writeEntity();
}
@@ -407,31 +409,31 @@
public Future<?> apply(final ClientRequest jerseyRequest, final AsyncConnectorCallback callback) {
final Request jettyRequest = translateRequest(jerseyRequest);
final Map<String, String> clientHeadersSnapshot = writeOutBoundHeaders(jerseyRequest.getHeaders(), jettyRequest);
- final ContentProvider entity = getStreamProvider(jerseyRequest);
+ final Request.Content entity = getStreamProvider(jerseyRequest);
if (entity != null) {
- jettyRequest.content(entity);
+ jettyRequest.body(entity);
}
final AtomicBoolean callbackInvoked = new AtomicBoolean(false);
final Throwable failure;
try {
final CompletableFuture<ClientResponse> responseFuture = new CompletableFuture<ClientResponse>();
responseFuture.whenComplete(
- (clientResponse, throwable) -> {
- if (throwable != null && throwable instanceof CancellationException) {
- // take care of future cancellation
- jettyRequest.abort(throwable);
+ (clientResponse, throwable) -> {
+ if (throwable != null && throwable instanceof CancellationException) {
+ // take care of future cancellation
+ jettyRequest.abort(throwable);
- }
- });
+ }
+ });
final AtomicReference<ClientResponse> jerseyResponse = new AtomicReference<>();
final ByteBufferInputStream entityStream = new ByteBufferInputStream();
- jettyRequest.send(new Response.Listener.Adapter() {
+ jettyRequest.send(new Response.Listener() {
@Override
public void onHeaders(final Response jettyResponse) {
HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, jerseyRequest.getHeaders(),
- JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
+ JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
if (responseFuture.isDone()) {
if (!callbackInvoked.compareAndSet(false, true)) {
@@ -500,7 +502,7 @@
}
private static ClientResponse translateResponse(final ClientRequest jerseyRequest,
- final org.eclipse.jetty.client.api.Response jettyResponse,
+ final org.eclipse.jetty.client.Response jettyResponse,
final NonBlockingInputStream entityStream) {
final ClientResponse jerseyResponse = new ClientResponse(Statuses.from(jettyResponse.getStatus()), jerseyRequest);
processResponseHeaders(jettyResponse.getHeaders(), jerseyResponse);
@@ -521,4 +523,4 @@
throw new ProcessingException("Failed to stop the client.", e);
}
}
-}
+}
\ No newline at end of file
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
similarity index 94%
rename from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
rename to connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
index dfd3b79..43a08ce 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
+++ b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,7 +16,6 @@
package org.glassfish.jersey.jetty.connector;
-import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.core.Configurable;
import jakarta.ws.rs.core.Configuration;
@@ -26,7 +25,6 @@
import org.glassfish.jersey.client.spi.ConnectorProvider;
import org.eclipse.jetty.client.HttpClient;
-import org.glassfish.jersey.internal.util.JdkVersion;
/**
* A {@link ConnectorProvider} for Jersey {@link Connector connector}
@@ -86,9 +84,6 @@
@Override
public Connector getConnector(Client client, Configuration runtimeConfig) {
- if (JdkVersion.getJdkVersion().getMajor() < 11) {
- throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
- }
return new JettyConnector(client, runtimeConfig);
}
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
similarity index 93%
copy from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
copy to connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
index b061ef5..6453521 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
+++ b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
similarity index 96%
copy from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
copy to connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
index dc43fb3..2b9e8b2 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
+++ b/connectors/jetty-connector/src/main/java17/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/connectors/jetty-connector/src/main/resources/org/glassfish/jersey/jetty/connector/localization.properties b/connectors/jetty-connector/src/main/resources/org/glassfish/jersey/jetty/connector/localization.properties
index 128d40b..6561153 100644
--- a/connectors/jetty-connector/src/main/resources/org/glassfish/jersey/jetty/connector/localization.properties
+++ b/connectors/jetty-connector/src/main/resources/org/glassfish/jersey/jetty/connector/localization.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,4 +18,4 @@
method.not.supported=Method {0} not supported.
invalid.configurable.component.type=The supplied component "{0}" is not assignable from JerseyClient or JerseyWebTarget.
expected.connector.provider.not.used=The supplied component is not configured to use a JettyConnectorProvider.
-not.supported=Jetty connector is not supported on JDK version less than 11.
+not.supported=Jetty connector is not supported on JDK version less than 17.
diff --git a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/AuthTest.java b/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/AuthTest.java
index f0bfb60..16f1b55 100644
--- a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/AuthTest.java
+++ b/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/AuthTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -33,12 +33,12 @@
import jakarta.inject.Singleton;
+import org.eclipse.jetty.client.BasicAuthentication;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
-import org.eclipse.jetty.client.util.BasicAuthentication;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
diff --git a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/CookieTest.java b/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/CookieTest.java
index 2a49c00..782cf40 100644
--- a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/CookieTest.java
+++ b/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/CookieTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -95,7 +95,7 @@
final JettyConnector connector = (JettyConnector) client.getConfiguration().getConnector();
if (connector.getCookieStore() != null) {
- assertTrue(connector.getCookieStore().getCookies().isEmpty());
+ assertTrue(connector.getCookieStore().all().isEmpty());
} else {
assertNull(connector.getCookieStore());
}
@@ -113,9 +113,9 @@
assertEquals("value", r.request().get(String.class));
final JettyConnector connector = (JettyConnector) client.getConfiguration().getConnector();
- assertNotNull(connector.getCookieStore().getCookies());
- assertEquals(1, connector.getCookieStore().getCookies().size());
- assertEquals("value", connector.getCookieStore().getCookies().get(0).getValue());
+ assertNotNull(connector.getCookieStore().all());
+ assertEquals(1, connector.getCookieStore().all().size());
+ assertEquals("value", connector.getCookieStore().all().get(0).getValue());
client.close();
}
}
diff --git a/connectors/jetty11-connector/pom.xml b/connectors/jetty11-connector/pom.xml
new file mode 100644
index 0000000..32b76c4
--- /dev/null
+++ b/connectors/jetty11-connector/pom.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0"?>
+<!--
+
+ Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>project</artifactId>
+ <version>3.1.99-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>jersey-jetty11-connector</artifactId>
+ <packaging>jar</packaging>
+ <name>jersey-connectors-jetty11</name>
+
+ <description>Jersey Client Transport via Jetty 11.x</description>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-client</artifactId>
+ <version>${jetty11.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-util</artifactId>
+ <version>${jetty11.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-jaxb</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-grizzly2-http</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-jackson</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>jakarta.xml.bind</groupId>
+ <artifactId>jakarta.xml.bind-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.xml.bind</groupId>
+ <artifactId>jaxb-osgi</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.sun.istack</groupId>
+ <artifactId>istack-commons-maven-plugin</artifactId>
+ <inherited>true</inherited>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <inherited>true</inherited>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <instructions>
+ <Import-Package>
+ ${jetty.osgi.version},
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git a/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ClientProperties.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ClientProperties.java
new file mode 100644
index 0000000..d2d9986
--- /dev/null
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ClientProperties.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.Map;
+
+import org.glassfish.jersey.internal.util.PropertiesClass;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+
+/**
+ * Configuration options specific to the Client API that utilizes {@link Jetty11ConnectorProvider}.
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+@PropertiesClass
+public final class Jetty11ClientProperties {
+
+ /**
+ * Prevents instantiation.
+ */
+ private Jetty11ClientProperties() {
+ throw new AssertionError("No instances allowed.");
+ }
+
+ /**
+ * A value of {@code false} indicates the client should handle cookies
+ * automatically using HttpClient's default cookie policy. A value
+ * of {@code false} will cause the client to ignore all cookies.
+ * <p/>
+ * The value MUST be an instance of {@link Boolean}.
+ * If the property is absent the default value is {@code false}
+ */
+ public static final String DISABLE_COOKIES =
+ "jersey.config.jetty11.client.disableCookies";
+
+ /**
+ * The credential provider that should be used to retrieve
+ * credentials from a user.
+ *
+ * If an {@link org.eclipse.jetty.client.api.Authentication} mechanism is found,
+ * it is then used for the given request, returning an {@link org.eclipse.jetty.client.api.Authentication.Result},
+ * which is then stored in the {@link org.eclipse.jetty.client.api.AuthenticationStore}
+ * so that subsequent requests can be preemptively authenticated.
+
+ * <p/>
+ * The value MUST be an instance of {@link
+ * org.eclipse.jetty.client.util.BasicAuthentication}. If
+ * the property is absent a default provider will be used.
+ */
+ public static final String PREEMPTIVE_BASIC_AUTHENTICATION =
+ "jersey.config.jetty11.client.preemptiveBasicAuthentication";
+
+ /**
+ * A value of {@code false} indicates the client disable a hostname verification
+ * during SSL Handshake. A client will ignore CN value defined in a certificate
+ * that is stored in a truststore.
+ * <p/>
+ * The value MUST be an instance of {@link Boolean}.
+ * If the property is absent the default value is {@code true}.
+ */
+ public static final String ENABLE_SSL_HOSTNAME_VERIFICATION =
+ "jersey.config.jetty11.client.enableSslHostnameVerification";
+
+ /**
+ * Overrides the default Jetty synchronous listener response max buffer size.
+ * In practise, this allows you to read larger responses.
+ * Size in bytes.
+ * <p/>
+ * If the property is absent, the value is such as specified by Jetty (currently 2MiB).
+ */
+ public static final String SYNC_LISTENER_RESPONSE_MAX_SIZE =
+ "jersey.config.jetty11.client.syncListenerResponseMaxSize";
+
+ /**
+ * Total timeout interval for request/response conversation, in milliseconds.
+ * Opposed to {@link org.glassfish.jersey.client.ClientProperties#READ_TIMEOUT}.
+ * <p>
+ * The value MUST be an instance convertible to {@link Integer}. The
+ * value of zero (0) is equivalent to an interval of infinity.
+ * </p>
+ * <p>
+ * The default value is zero (infinity).
+ * </p>
+ * <p>
+ * The name of the configuration property is <tt>{@value}</tt>.
+ * </p>
+ *
+ * @since 2.37
+ */
+ public static final String TOTAL_TIMEOUT = "jersey.config.jetty11.client.totalTimeout";
+
+ /**
+ * Get the value of the specified property.
+ *
+ * If the property is not set or the real value type is not compatible with the specified value type, returns {@code null}.
+ *
+ * @param properties Map of properties to get the property value from.
+ * @param key Name of the property.
+ * @param type Type to retrieve the value as.
+ * @param <T> Type of the property value.
+ * @return Value of the property or {@code null}.
+ *
+ * @since 2.8
+ */
+ public static <T> T getValue(final Map<String, ?> properties, final String key, final Class<T> type) {
+ return PropertiesHelper.getValue(properties, key, type, null);
+ }
+
+}
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11Connector.java
similarity index 92%
rename from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
rename to connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11Connector.java
index 825a231..24f10fc 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11Connector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,7 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
-package org.glassfish.jersey.jetty.connector;
+package org.glassfish.jersey.jetty11.connector;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -41,12 +41,10 @@
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.core.Configuration;
-import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MultivaluedMap;
import javax.net.ssl.SSLContext;
-import jakarta.ws.rs.ext.RuntimeDelegate;
import org.eclipse.jetty.client.HttpClientTransport;
import org.eclipse.jetty.client.HttpRequest;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
@@ -97,10 +95,10 @@
* <li>{@link ClientProperties#PROXY_USERNAME}</li>
* <li>{@link ClientProperties#PROXY_PASSWORD}</li>
* <li>{@link ClientProperties#PROXY_PASSWORD}</li>
- * <li>{@link JettyClientProperties#DISABLE_COOKIES}</li>*
- * <li>{@link JettyClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
- * <li>{@link JettyClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
- * <li>{@link JettyClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
+ * <li>{@link Jetty11ClientProperties#DISABLE_COOKIES}</li>*
+ * <li>{@link Jetty11ClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
+ * <li>{@link Jetty11ClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
+ * <li>{@link Jetty11ClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
* </ul>
* <p/>
* This transport supports both synchronous and asynchronous processing of client requests.
@@ -133,9 +131,9 @@
* @author Arul Dhesiaseelan (aruld at acm.org)
* @author Marek Potociar
*/
-class JettyConnector implements Connector {
+class Jetty11Connector implements Connector {
- private static final Logger LOGGER = Logger.getLogger(JettyConnector.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(Jetty11Connector.class.getName());
private final HttpClient client;
private final CookieStore cookieStore;
@@ -148,14 +146,14 @@
* @param jaxrsClient JAX-RS client instance, for which the connector is created.
* @param config client configuration.
*/
- JettyConnector(final Client jaxrsClient, final Configuration config) {
+ Jetty11Connector(final Client jaxrsClient, final Configuration config) {
this.configuration = config;
HttpClient httpClient = null;
- if (config.isRegistered(JettyHttpClientSupplier.class)) {
+ if (config.isRegistered(Jetty11HttpClientSupplier.class)) {
Optional<Object> contract = config.getInstances().stream()
- .filter(a-> JettyHttpClientSupplier.class.isInstance(a)).findFirst();
+ .filter(a-> Jetty11HttpClientSupplier.class.isInstance(a)).findFirst();
if (contract.isPresent()) {
- httpClient = ((JettyHttpClientSupplier) contract.get()).getHttpClient();
+ httpClient = ((Jetty11HttpClientSupplier) contract.get()).getHttpClient();
}
}
if (httpClient == null) {
@@ -170,7 +168,7 @@
this.client = httpClient;
Boolean enableHostnameVerification = (Boolean) config.getProperties()
- .get(JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION);
+ .get(Jetty11ClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION);
if (enableHostnameVerification != null) {
final String verificationAlgorithm = enableHostnameVerification ? "HTTPS" : null;
client.getSslContextFactory().setEndpointIdentificationAlgorithm(verificationAlgorithm);
@@ -190,11 +188,11 @@
threadPool.setName(name);
client.setExecutor(threadPool);
}
- Boolean disableCookies = (Boolean) config.getProperties().get(JettyClientProperties.DISABLE_COOKIES);
+ Boolean disableCookies = (Boolean) config.getProperties().get(Jetty11ClientProperties.DISABLE_COOKIES);
disableCookies = (disableCookies != null) ? disableCookies : false;
final AuthenticationStore auth = client.getAuthenticationStore();
- final Object basicAuthProvider = config.getProperty(JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION);
+ final Object basicAuthProvider = config.getProperty(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION);
if (basicAuthProvider != null && (basicAuthProvider instanceof BasicAuthentication)) {
auth.addAuthentication((BasicAuthentication) basicAuthProvider);
}
@@ -216,7 +214,7 @@
}
final Object slResponseMaxSize = configuration.getProperties()
- .get(JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE);
+ .get(Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE);
if (slResponseMaxSize != null && slResponseMaxSize instanceof Integer
&& (Integer) slResponseMaxSize > 0) {
this.syncListenerResponseMaxSize = Optional.of((Integer) slResponseMaxSize);
@@ -274,7 +272,7 @@
jettyResponse = listener.get();
}
HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, jerseyRequest.getHeaders(),
- JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
+ Jetty11Connector.this.getClass().getName(), jerseyRequest.getConfiguration());
final jakarta.ws.rs.core.Response.StatusType status = jettyResponse.getReason() == null
? Statuses.from(jettyResponse.getStatus())
@@ -330,7 +328,7 @@
request.idleTimeout((Integer) readTimeout, TimeUnit.MILLISECONDS);
}
- final Object totalTimeout = clientRequest.resolveProperty(JettyClientProperties.TOTAL_TIMEOUT, -1);
+ final Object totalTimeout = clientRequest.resolveProperty(Jetty11ClientProperties.TOTAL_TIMEOUT, -1);
if (totalTimeout != null && totalTimeout instanceof Integer && (Integer) totalTimeout > 0) {
request.timeout((Integer) totalTimeout, TimeUnit.MILLISECONDS);
}
@@ -431,7 +429,7 @@
@Override
public void onHeaders(final Response jettyResponse) {
HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, jerseyRequest.getHeaders(),
- JettyConnector.this.getClass().getName(), jerseyRequest.getConfiguration());
+ Jetty11Connector.this.getClass().getName(), jerseyRequest.getConfiguration());
if (responseFuture.isDone()) {
if (!callbackInvoked.compareAndSet(false, true)) {
@@ -500,7 +498,7 @@
}
private static ClientResponse translateResponse(final ClientRequest jerseyRequest,
- final org.eclipse.jetty.client.api.Response jettyResponse,
+ final Response jettyResponse,
final NonBlockingInputStream entityStream) {
final ClientResponse jerseyResponse = new ClientResponse(Statuses.from(jettyResponse.getStatus()), jerseyRequest);
processResponseHeaders(jettyResponse.getHeaders(), jerseyResponse);
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ConnectorProvider.java
similarity index 84%
copy from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
copy to connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ConnectorProvider.java
index dfd3b79..de6bc77 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11ConnectorProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,7 +14,7 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
-package org.glassfish.jersey.jetty.connector;
+package org.glassfish.jersey.jetty11.connector;
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.client.Client;
@@ -42,10 +42,10 @@
* <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}</li>
* <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
* <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
- * <li>{@link JettyClientProperties#DISABLE_COOKIES}</li>*
- * <li>{@link JettyClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
- * <li>{@link JettyClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
- * <li>{@link JettyClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
+ * <li>{@link Jetty11ClientProperties#DISABLE_COOKIES}</li>*
+ * <li>{@link Jetty11ClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
+ * <li>{@link Jetty11ClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
+ * <li>{@link Jetty11ClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
* </ul>
* </p>
* <p>
@@ -82,18 +82,18 @@
* @author Marek Potociar
* @since 2.5
*/
-public class JettyConnectorProvider implements ConnectorProvider {
+public class Jetty11ConnectorProvider implements ConnectorProvider {
@Override
public Connector getConnector(Client client, Configuration runtimeConfig) {
if (JdkVersion.getJdkVersion().getMajor() < 11) {
throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
}
- return new JettyConnector(client, runtimeConfig);
+ return new Jetty11Connector(client, runtimeConfig);
}
/**
- * Retrieve the underlying Jetty {@link org.eclipse.jetty.client.HttpClient} instance from
+ * Retrieve the underlying Jetty {@link HttpClient} instance from
* {@link org.glassfish.jersey.client.JerseyClient} or {@link org.glassfish.jersey.client.JerseyWebTarget}
* configured to use {@code JettyConnectorProvider}.
*
@@ -101,7 +101,7 @@
* {@code JettyConnectorProvider}.
* @return underlying Jetty {@code HttpClient} instance.
*
- * @throws java.lang.IllegalArgumentException in case the {@code component} is neither {@code JerseyClient}
+ * @throws IllegalArgumentException in case the {@code component} is neither {@code JerseyClient}
* nor {@code JerseyWebTarget} instance or in case the component
* is not configured to use a {@code JettyConnectorProvider}.
* @since 2.8
@@ -119,8 +119,8 @@
connector = initializable.getConfiguration().getConnector();
}
- if (connector instanceof JettyConnector) {
- return ((JettyConnector) connector).getHttpClient();
+ if (connector instanceof Jetty11Connector) {
+ return ((Jetty11Connector) connector).getHttpClient();
}
throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED());
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientContract.java
similarity index 81%
copy from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
copy to connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientContract.java
index b061ef5..3b0321d 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientContract.java
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientContract.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -14,17 +14,17 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
-package org.glassfish.jersey.jetty.connector;
+package org.glassfish.jersey.jetty11.connector;
import org.eclipse.jetty.client.HttpClient;
import org.glassfish.jersey.spi.Contract;
/**
* A contract that allows for an optional registration of user predefined Jetty {@code HttpClient}
- * that is consequently used by {@link JettyConnector}
+ * that is consequently used by {@link Jetty11Connector}
*/
@Contract
-public interface JettyHttpClientContract {
+public interface Jetty11HttpClientContract {
/**
* Supply a user predefined HttpClient
* @return a user predefined HttpClient
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientSupplier.java
similarity index 80%
copy from connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
copy to connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientSupplier.java
index dc43fb3..b5f1462 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyHttpClientSupplier.java
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/Jetty11HttpClientSupplier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -13,12 +13,12 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
-package org.glassfish.jersey.jetty.connector;
+package org.glassfish.jersey.jetty11.connector;
import org.eclipse.jetty.client.HttpClient;
/**
- * Jetty HttpClient supplier to be registered into Jersey configuration to be used by {@link JettyConnector}.
+ * Jetty HttpClient supplier to be registered into Jersey configuration to be used by {@link Jetty11Connector}.
* Not every possible configuration option is covered by the Jetty Connector and this supplier offers a way to provide
* an HttpClient that has configured the options not covered by the Jetty Connector.
* <p>
@@ -35,17 +35,17 @@
* }
* </pre>
* <p>
- * The {@code HttpClient} is configured as if it was created by {@link JettyConnector} the usual way.
+ * The {@code HttpClient} is configured as if it was created by {@link Jetty11Connector} the usual way.
* </p>
*/
-public class JettyHttpClientSupplier implements JettyHttpClientContract {
+public class Jetty11HttpClientSupplier implements Jetty11HttpClientContract {
private final HttpClient httpClient;
/**
* {@code HttpClient} supplier to be optionally registered to a {@link org.glassfish.jersey.client.ClientConfig}
- * @param httpClient a HttpClient to be supplied when {@link JettyConnector#getHttpClient()} is called.
+ * @param httpClient a HttpClient to be supplied when {@link Jetty11Connector#getHttpClient()} is called.
*/
- public JettyHttpClientSupplier(HttpClient httpClient) {
+ public Jetty11HttpClientSupplier(HttpClient httpClient) {
this.httpClient = httpClient;
}
diff --git a/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/package-info.java b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/package-info.java
new file mode 100644
index 0000000..0f85c4f
--- /dev/null
+++ b/connectors/jetty11-connector/src/main/java/org/glassfish/jersey/jetty11/connector/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/**
+ * Jersey client {@link org.glassfish.jersey.client.spi.Connector connector} based on the
+ * Jetty Client.
+ */
+package org.glassfish.jersey.jetty11.connector;
diff --git a/connectors/jetty11-connector/src/main/resources/org/glassfish/jersey/jetty11/connector/localization.properties b/connectors/jetty11-connector/src/main/resources/org/glassfish/jersey/jetty11/connector/localization.properties
new file mode 100644
index 0000000..aacb267
--- /dev/null
+++ b/connectors/jetty11-connector/src/main/resources/org/glassfish/jersey/jetty11/connector/localization.properties
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+# {0} - HTTP method, e.g. GET, DELETE
+method.not.supported=Method {0} not supported.
+invalid.configurable.component.type=The supplied component "{0}" is not assignable from JerseyClient or JerseyWebTarget.
+expected.connector.provider.not.used=The supplied component is not configured to use a JettyConnectorProvider.
+not.supported=Jetty connector is not supported on JDK version less than 11.
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AsyncTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AsyncTest.java
new file mode 100644
index 0000000..9d0edbc
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AsyncTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+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.Entity;
+import jakarta.ws.rs.container.AsyncResponse;
+import jakarta.ws.rs.container.Suspended;
+import jakarta.ws.rs.container.TimeoutHandler;
+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.hamcrest.Matchers;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * Asynchronous connector test.
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Marek Potociar
+ */
+public class AsyncTest extends JerseyTest {
+ private static final Logger LOGGER = Logger.getLogger(AsyncTest.class.getName());
+ private static final String PATH = "async";
+
+ /**
+ * Asynchronous test resource.
+ */
+ @Path(PATH)
+ public static class AsyncResource {
+ /**
+ * Typical long-running operation duration.
+ */
+ public static final long OPERATION_DURATION = 1000;
+
+ /**
+ * Long-running asynchronous post.
+ *
+ * @param asyncResponse async response.
+ * @param id post request id (received as request payload).
+ */
+ @POST
+ public void asyncPost(@Suspended final AsyncResponse asyncResponse, final String id) {
+ LOGGER.info("Long running post operation called with id " + id + " on thread " + Thread.currentThread().getName());
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ String result = veryExpensiveOperation();
+ asyncResponse.resume(result);
+ }
+
+ private String veryExpensiveOperation() {
+ // ... very expensive operation that typically finishes within 1 seconds, simulated using sleep()
+ try {
+ Thread.sleep(OPERATION_DURATION);
+ return "DONE-" + id;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return "INTERRUPTED-" + id;
+ } finally {
+ LOGGER.info("Long running post operation finished on thread " + Thread.currentThread().getName());
+ }
+ }
+ }, "async-post-runner-" + id).start();
+ }
+
+ /**
+ * Long-running async get request that times out.
+ *
+ * @param asyncResponse async response.
+ */
+ @GET
+ @Path("timeout")
+ public void asyncGetWithTimeout(@Suspended final AsyncResponse asyncResponse) {
+ LOGGER.info("Async long-running get with timeout called on thread " + Thread.currentThread().getName());
+ asyncResponse.setTimeoutHandler(new TimeoutHandler() {
+
+ @Override
+ public void handleTimeout(AsyncResponse asyncResponse) {
+ asyncResponse.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE)
+ .entity("Operation time out.").build());
+ }
+ });
+ asyncResponse.setTimeout(1, TimeUnit.SECONDS);
+ asyncResponse.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE)
+ .entity("Operation time out.").build());
+
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ String result = veryExpensiveOperation();
+ asyncResponse.resume(result);
+ }
+
+ private String veryExpensiveOperation() {
+ // very expensive operation that typically finishes within 1 second but can take up to 5 seconds,
+ // simulated using sleep()
+ try {
+ Thread.sleep(5 * OPERATION_DURATION);
+ return "DONE";
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return "INTERRUPTED";
+ } finally {
+ LOGGER.info("Async long-running get with timeout finished on thread " + Thread.currentThread().getName());
+ }
+ }
+ }).start();
+ }
+
+ }
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig(AsyncResource.class)
+ .register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+ }
+
+ @Override
+ protected void configureClient(ClientConfig config) {
+ // TODO: fails with true on request - should be fixed by resolving JERSEY-2273
+ config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.HEADERS_ONLY));
+ config.connectorProvider(new Jetty11ConnectorProvider());
+ }
+
+ /**
+ * Test asynchronous POST.
+ *
+ * Send 3 async POST requests and wait to receive the responses. Check the response content and
+ * assert that the operation did not take more than twice as long as a single long operation duration
+ * (this ensures async request execution).
+ *
+ * @throws Exception in case of a test error.
+ */
+ @Test
+ public void testAsyncPost() throws Exception {
+ final long tic = System.currentTimeMillis();
+
+ // Submit requests asynchronously.
+ final Future<Response> rf1 = target(PATH).request().async().post(Entity.text("1"));
+ final Future<Response> rf2 = target(PATH).request().async().post(Entity.text("2"));
+ final Future<Response> rf3 = target(PATH).request().async().post(Entity.text("3"));
+ // get() waits for the response
+ final String r1 = rf1.get().readEntity(String.class);
+ final String r2 = rf2.get().readEntity(String.class);
+ final String r3 = rf3.get().readEntity(String.class);
+
+ final long toc = System.currentTimeMillis();
+
+ assertEquals("DONE-1", r1);
+ assertEquals("DONE-2", r2);
+ assertEquals("DONE-3", r3);
+
+ assertThat("Async processing took too long.", toc - tic, Matchers.lessThan(3 * AsyncResource.OPERATION_DURATION));
+ }
+
+ /**
+ * Test accessing an operation that times out on the server.
+ *
+ * @throws Exception in case of a test error.
+ */
+ @Test
+ public void testAsyncGetWithTimeout() throws Exception {
+ final Future<Response> responseFuture = target(PATH).path("timeout").request().async().get();
+ // Request is being processed asynchronously.
+ final Response response = responseFuture.get();
+
+ // get() waits for the response
+ assertEquals(503, response.getStatus());
+ assertEquals("Operation time out.", response.readEntity(String.class));
+ }
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthFilterTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthFilterTest.java
new file mode 100644
index 0000000..1c6cddc
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthFilterTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class AuthFilterTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(AuthFilterTest.class.getName());
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(AuthTest.AuthResource.class);
+ config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+ return config;
+ }
+
+
+ @Override
+ protected void configureClient(ClientConfig config) {
+ config.connectorProvider(new Jetty11ConnectorProvider());
+ }
+
+ @Test
+ public void testAuthGetWithClientFilter() {
+ client().register(HttpAuthenticationFeature.basic("name", "password"));
+ Response response = target("test/filter").request().get();
+ assertEquals("GET", response.readEntity(String.class));
+ }
+
+ @Test
+ public void testAuthPostWithClientFilter() {
+ client().register(HttpAuthenticationFeature.basic("name", "password"));
+ Response response = target("test/filter").request().post(Entity.text("POST"));
+ assertEquals("POST", response.readEntity(String.class));
+ }
+
+
+ @Test
+ public void testAuthDeleteWithClientFilter() {
+ client().register(HttpAuthenticationFeature.basic("name", "password"));
+ Response response = target("test/filter").request().delete();
+ assertEquals(204, response.getStatus());
+ }
+
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthTest.java
new file mode 100644
index 0000000..6b5111b
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/AuthTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.logging.Logger;
+
+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 jakarta.inject.Singleton;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.eclipse.jetty.client.util.BasicAuthentication;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class AuthTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(AuthTest.class.getName());
+ 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(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+ new BasicAuthentication(getBaseUri(), "WallyWorld", "name", "password"));
+ config.connectorProvider(new Jetty11ConnectorProvider());
+ 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(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+ new BasicAuthentication(getBaseUri(), "WallyWorld", "name", "password"));
+ config.connectorProvider(new Jetty11ConnectorProvider());
+ 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(Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION,
+ new BasicAuthentication(getBaseUri(), "WallyWorld", "name", "password"));
+ config.connectorProvider(new Jetty11ConnectorProvider());
+ Client client = ClientBuilder.newClient(config);
+
+ Response response = client.target(getBaseUri()).path(PATH).request().delete();
+ assertEquals(response.getStatus(), 204);
+ client.close();
+ }
+
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CookieTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CookieTest.java
new file mode 100644
index 0000000..0cd585e
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CookieTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.logging.Logger;
+
+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 static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class CookieTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(CookieTest.class.getName());
+
+ @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.connectorProvider(new Jetty11ConnectorProvider());
+ 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() {
+ ClientConfig cc = new ClientConfig();
+ cc.property(Jetty11ClientProperties.DISABLE_COOKIES, true);
+ cc.connectorProvider(new Jetty11ConnectorProvider());
+ JerseyClient client = JerseyClientBuilder.createClient(cc);
+ WebTarget r = client.target(getBaseUri());
+
+ assertEquals("NO-COOKIE", r.request().get(String.class));
+ assertEquals("NO-COOKIE", r.request().get(String.class));
+
+ final Jetty11Connector connector = (Jetty11Connector) client.getConfiguration().getConnector();
+ if (connector.getCookieStore() != null) {
+ assertTrue(connector.getCookieStore().getCookies().isEmpty());
+ } else {
+ assertNull(connector.getCookieStore());
+ }
+ client.close();
+ }
+
+ @Test
+ public void testCookies() {
+ ClientConfig cc = new ClientConfig();
+ cc.connectorProvider(new Jetty11ConnectorProvider());
+ JerseyClient client = JerseyClientBuilder.createClient(cc);
+ WebTarget r = client.target(getBaseUri());
+
+ assertEquals("NO-COOKIE", r.request().get(String.class));
+ assertEquals("value", r.request().get(String.class));
+
+ final Jetty11Connector connector = (Jetty11Connector) client.getConfiguration().getConnector();
+ assertNotNull(connector.getCookieStore().getCookies());
+ assertEquals(1, connector.getCookieStore().getCookies().size());
+ assertEquals("value", connector.getCookieStore().getCookies().get(0).getValue());
+ client.close();
+ }
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CustomLoggingFilter.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CustomLoggingFilter.java
new file mode 100644
index 0000000..386f96e
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/CustomLoggingFilter.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.ClientResponseContext;
+import jakarta.ws.rs.client.ClientResponseFilter;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Custom logging filter.
+ *
+ * @author Santiago Pericas-Geertsen (santiago.pericasgeertsen at oracle.com)
+ */
+public class CustomLoggingFilter implements ContainerRequestFilter, ContainerResponseFilter,
+ ClientRequestFilter, ClientResponseFilter {
+
+ static int preFilterCalled = 0;
+ static int postFilterCalled = 0;
+
+ @Override
+ public void filter(ClientRequestContext context) throws IOException {
+ System.out.println("CustomLoggingFilter.preFilter called");
+ assertEquals("bar", context.getConfiguration().getProperty("foo"));
+ preFilterCalled++;
+ }
+
+ @Override
+ public void filter(ClientRequestContext context, ClientResponseContext clientResponseContext) throws IOException {
+ System.out.println("CustomLoggingFilter.postFilter called");
+ assertEquals("bar", context.getConfiguration().getProperty("foo"));
+ postFilterCalled++;
+ }
+
+ @Override
+ public void filter(ContainerRequestContext context) throws IOException {
+ System.out.println("CustomLoggingFilter.preFilter called");
+ assertEquals("bar", context.getProperty("foo"));
+ preFilterCalled++;
+ }
+
+ @Override
+ public void filter(ContainerRequestContext context, ContainerResponseContext containerResponseContext) throws IOException {
+ System.out.println("CustomLoggingFilter.postFilter called");
+ assertEquals("bar", context.getProperty("foo"));
+ postFilterCalled++;
+ }
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/EntityTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/EntityTest.java
new file mode 100644
index 0000000..e9de353
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/EntityTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+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.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.logging.LoggingFeature;
+// import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Tests the Http content negotiation.
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class EntityTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(EntityTest.class.getName());
+
+ 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() {
+ }
+
+ 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 Jetty11ConnectorProvider());
+ //.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/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ErrorTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ErrorTest.java
new file mode 100644
index 0000000..a8a97e5
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ErrorTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.logging.Logger;
+
+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 static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class ErrorTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(ErrorTest.class.getName());
+
+ @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 Jetty11ConnectorProvider());
+ }
+
+
+ @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() {
+ WebTarget r = target("test");
+
+ for (int i = 0; i < 100; i++) {
+ try {
+ r.request().post(Entity.text("POST"));
+ } catch (ClientErrorException ex) {
+ }
+ }
+ }
+
+ @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() {
+ WebTarget r = target("test");
+
+ for (int i = 0; i < 100; i++) {
+ try {
+ r.request().async().post(Entity.text("POST"));
+ } catch (ClientErrorException ex) {
+ }
+ }
+ }
+
+ @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/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/FollowRedirectsTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/FollowRedirectsTest.java
new file mode 100644
index 0000000..a30efbc
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/FollowRedirectsTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.logging.Logger;
+
+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 static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Jetty connector follow redirect tests.
+ *
+ * @author Martin Matula
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Marek Potociar
+ */
+public class FollowRedirectsTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(FollowRedirectsTest.class.getName());
+
+ @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 Jetty11ConnectorProvider());
+ }
+
+ 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 Jetty11ConnectorProvider());
+ 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 Jetty11ConnectorProvider());
+ 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/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/GZIPContentEncodingTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/GZIPContentEncodingTest.java
new file mode 100644
index 0000000..459eccb
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/GZIPContentEncodingTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.Arrays;
+import java.util.logging.Logger;
+
+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 static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class GZIPContentEncodingTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(EntityTest.class.getName());
+
+ @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 Jetty11ConnectorProvider());
+ }
+
+ @Test
+ public void testPost() {
+ WebTarget r = target();
+ 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.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 Jetty11ConnectorProvider());
+ 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();
+ }
+
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HelloWorldTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HelloWorldTest.java
new file mode 100644
index 0000000..a60719b
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HelloWorldTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.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.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.InvocationCallback;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ *
+ * @author Jakub Podlesak
+ */
+public class HelloWorldTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(HelloWorldTest.class.getName());
+ 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 Jetty11ConnectorProvider());
+ }
+
+ @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();
+ }
+
+ @Test
+ public void testLoggingFilterClientClass() {
+ Client client = client();
+ client.register(CustomLoggingFilter.class).property("foo", "bar");
+ CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+ String s = target().path(ROOT_PATH).request().get(String.class);
+ assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+ assertEquals(1, CustomLoggingFilter.preFilterCalled);
+ assertEquals(1, CustomLoggingFilter.postFilterCalled);
+ client.close();
+ }
+
+ @Test
+ public void testLoggingFilterClientInstance() {
+ Client client = client();
+ client.register(new CustomLoggingFilter()).property("foo", "bar");
+ CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+ String s = target().path(ROOT_PATH).request().get(String.class);
+ assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+ assertEquals(1, CustomLoggingFilter.preFilterCalled);
+ assertEquals(1, CustomLoggingFilter.postFilterCalled);
+ client.close();
+ }
+
+ @Test
+ public void testLoggingFilterTargetClass() {
+ WebTarget target = target().path(ROOT_PATH);
+ target.register(CustomLoggingFilter.class).property("foo", "bar");
+ CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+ String s = target.request().get(String.class);
+ assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+ assertEquals(1, CustomLoggingFilter.preFilterCalled);
+ assertEquals(1, CustomLoggingFilter.postFilterCalled);
+ }
+
+ @Test
+ public void testLoggingFilterTargetInstance() {
+ WebTarget target = target().path(ROOT_PATH);
+ target.register(new CustomLoggingFilter()).property("foo", "bar");
+ CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+ String s = target.request().get(String.class);
+ assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+ assertEquals(1, CustomLoggingFilter.preFilterCalled);
+ assertEquals(1, CustomLoggingFilter.postFilterCalled);
+ }
+
+ @Test
+ public void testConfigurationUpdate() {
+ Client client1 = client();
+ client1.register(CustomLoggingFilter.class).property("foo", "bar");
+
+ Client client = ClientBuilder.newClient(client1.getConfiguration());
+ CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+ String s = target().path(ROOT_PATH).request().get(String.class);
+ assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+ assertEquals(1, CustomLoggingFilter.preFilterCalled);
+ assertEquals(1, CustomLoggingFilter.postFilterCalled);
+ client.close();
+ }
+
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HttpHeadersTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HttpHeadersTest.java
new file mode 100644
index 0000000..3d03872
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/HttpHeadersTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.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.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+
+/**
+ * Tests the headers.
+ *
+ * @author Stepan Kopriva
+ */
+public class HttpHeadersTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(HttpHeadersTest.class.getName());
+
+ @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 Jetty11ConnectorProvider());
+ }
+
+ @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);
+ }
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ManagedClientTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ManagedClientTest.java
new file mode 100644
index 0000000..628af89
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/ManagedClientTest.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.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.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ClientBinding;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.Uri;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Jersey programmatic managed client test
+ *
+ * @author Marek Potociar
+ */
+public class ManagedClientTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(ManagedClientTest.class.getName());
+
+ /**
+ * 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}.
+ */
+ public String headerName();
+
+ /**
+ * Expected custom header value to be validated by the {@link CustomHeaderFilter}.
+ */
+ public 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 Jetty11ConnectorProvider());
+ }
+
+ /**
+ * 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/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/MethodTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/MethodTest.java
new file mode 100644
index 0000000..f62834b
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/MethodTest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.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.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Tests the Http methods.
+ *
+ * @author Stepan Kopriva
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class MethodTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(MethodTest.class.getName());
+
+ 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 Jetty11ConnectorProvider());
+ }
+
+ @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/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/NoEntityTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/NoEntityTest.java
new file mode 100644
index 0000000..f5f754d
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/NoEntityTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.util.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 jakarta.ws.rs.core.Response.Status;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class NoEntityTest extends JerseyTest {
+ private static final Logger LOGGER = Logger.getLogger(NoEntityTest.class.getName());
+
+ @Path("/test")
+ public static class HttpMethodResource {
+ @GET
+ public Response get() {
+ return Response.status(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 Jetty11ConnectorProvider());
+ }
+
+ @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/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/SyncResponseSizeTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/SyncResponseSizeTest.java
new file mode 100644
index 0000000..be67e9a
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/SyncResponseSizeTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
+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 java.net.URI;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Logger;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Default synchronous jetty client implementation has a hard response size limit of 2MiB.
+ * When response is too big, a processing exception is thrown.
+ * The original code path was left to preserve this behaviour but could be removed
+ * and reworked in the future with a custom listener like async path.
+ *
+ * This tests the previous behavior with large payloads (>2MiB), the new size override (4MiB)
+ * and very big payloads (>4MiB).
+ *
+ * @author cen1 (cen.is.imba at gmail.com)
+ */
+public class SyncResponseSizeTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(SyncResponseSizeTest.class.getName());
+
+ private static final int maxBufferSize = 4 * 1024 * 1024; //4 MiB
+
+ @Path("/test")
+ public static class TimeoutResource {
+
+ private static final byte[] data = new byte[maxBufferSize];
+
+ static {
+ Byte b = "a".getBytes()[0];
+ for (int i = 0; i < maxBufferSize; i++) data[i] = b.byteValue();
+ }
+
+ @GET
+ @Path("/small")
+ public String getSmall() {
+ return "GET";
+ }
+
+ @GET
+ @Path("/big")
+ public String getBig() {
+ return new String(data);
+ }
+
+ @GET
+ @Path("/verybig")
+ public String getVeryBig() {
+ return new String(data) + "a";
+ }
+ }
+
+ @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 Jetty11ConnectorProvider());
+ }
+
+ @Test
+ public void testDefaultSmall() {
+ Response r = target("test/small").request().get();
+ assertEquals(200, r.getStatus());
+ assertEquals("GET", r.readEntity(String.class));
+ }
+
+ @Test
+ public void testDefaultTooBig() {
+ final URI u = target().getUri();
+ ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
+ config.connectorProvider(new Jetty11ConnectorProvider());
+
+ Client c = ClientBuilder.newClient(config);
+ WebTarget t = c.target(u);
+ try {
+ t.path("test/big").request().get();
+ fail("Exception expected.");
+ } catch (ProcessingException e) {
+ // Buffering capacity ... exceeded.
+ assertTrue(ExecutionException.class.isInstance(e.getCause()));
+ assertTrue(IllegalArgumentException.class.isInstance(e.getCause().getCause()));
+ } finally {
+ c.close();
+ }
+ }
+
+ @Test
+ public void testCustomBig() {
+ final URI u = target().getUri();
+ ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
+ config.connectorProvider(new Jetty11ConnectorProvider());
+ config.property(Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
+
+ Client c = ClientBuilder.newClient(config);
+ WebTarget t = c.target(u);
+ try {
+ Response r = t.path("test/big").request().get();
+ String p = r.readEntity(String.class);
+ assertEquals(p.length(), maxBufferSize);
+ } catch (ProcessingException e) {
+ assertThat("Unexpected processing exception cause",
+ e.getCause(), instanceOf(TimeoutException.class));
+ } finally {
+ c.close();
+ }
+ }
+
+ @Test
+ public void testCustomTooBig() {
+ final URI u = target().getUri();
+ ClientConfig config = new ClientConfig().property(ClientProperties.READ_TIMEOUT, 1_000);
+ config.connectorProvider(new Jetty11ConnectorProvider());
+ config.property(Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE, maxBufferSize);
+
+ Client c = ClientBuilder.newClient(config);
+ WebTarget t = c.target(u);
+ try {
+ t.path("test/verybig").request().get();
+ fail("Exception expected.");
+ } catch (ProcessingException e) {
+ // Buffering capacity ... exceeded.
+ assertTrue(ExecutionException.class.isInstance(e.getCause()));
+ assertTrue(IllegalArgumentException.class.isInstance(e.getCause().getCause()));
+ } finally {
+ c.close();
+ }
+ }
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TimeoutTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TimeoutTest.java
new file mode 100644
index 0000000..3644262
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TimeoutTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.QueryParam;
+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 jakarta.ws.rs.core.StreamingOutput;
+
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * @author Martin Matula
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class TimeoutTest extends JerseyTest {
+ private static final Logger LOGGER = Logger.getLogger(TimeoutTest.class.getName());
+
+ @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";
+ }
+
+ /**
+ * Long-running streaming request
+ *
+ * @param count number of packets send
+ * @param pauseMillis pause between each packets
+ */
+ @GET
+ @Path("stream")
+ public Response streamsWithDelay(@QueryParam("start") @DefaultValue("0") int startMillis, @QueryParam("count") int count,
+ @QueryParam("pauseMillis") int pauseMillis) {
+ StreamingOutput streamingOutput = streamSlowly(startMillis, count, pauseMillis);
+
+ return Response.ok(streamingOutput)
+ .build();
+ }
+ }
+
+ private static StreamingOutput streamSlowly(int startMillis, int count, int pauseMillis) {
+
+ return output -> {
+ try {
+ TimeUnit.MILLISECONDS.sleep(startMillis);
+ }
+ catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ output.write("begin\n".getBytes(StandardCharsets.UTF_8));
+ output.flush();
+ for (int i = 0; i < count; i++) {
+ try {
+ TimeUnit.MILLISECONDS.sleep(pauseMillis);
+ }
+ catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+
+ output.write(("message " + i + "\n").getBytes(StandardCharsets.UTF_8));
+ output.flush();
+ }
+ output.write("end".getBytes(StandardCharsets.UTF_8));
+ };
+ }
+
+ @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 Jetty11ConnectorProvider());
+ }
+
+ @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 Jetty11ConnectorProvider());
+ Client c = ClientBuilder.newClient(config);
+ WebTarget t = c.target(u);
+ try {
+ t.path("test/timeout").request().get();
+ fail("Timeout expected.");
+ } catch (ProcessingException e) {
+ assertThat("Unexpected processing exception cause",
+ e.getCause(), instanceOf(TimeoutException.class));
+ } finally {
+ c.close();
+ }
+ }
+
+ @Test
+ public void testTimeoutInRequest() {
+ final URI u = target().getUri();
+ ClientConfig config = new ClientConfig();
+ config.connectorProvider(new Jetty11ConnectorProvider());
+ 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) {
+ assertThat("Unexpected processing exception cause",
+ e.getCause(), instanceOf(TimeoutException.class));
+ } finally {
+ c.close();
+ }
+ }
+
+ /**
+ * Test accessing an operation that is streaming slowly
+ *
+ * @throws ProcessingException in case of a test error.
+ */
+ @Test
+ @Disabled("Test fails with grizzly2 container") // TODO: evaluate, why this test fails with grizzly2
+ public void testSlowlyStreamedContentDoesNotReadTimeout() throws Exception {
+
+ int count = 5;
+ int pauseMillis = 50;
+
+ final Response response = target("test")
+ .property(ClientProperties.READ_TIMEOUT, 100L)
+ .property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER, "-1")
+ .path("stream")
+ .queryParam("count", count)
+ .queryParam("pauseMillis", pauseMillis)
+ .request().get();
+
+ assertTrue(response.readEntity(String.class).contains("end"));
+ }
+
+ @Test
+ public void testSlowlyStreamedContentDoesTotalTimeout() throws Exception {
+
+ int count = 5;
+ int pauseMillis = 50;
+
+ try {
+ target("test")
+ .property(Jetty11ClientProperties.TOTAL_TIMEOUT, 100L)
+ .property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER, "-1")
+ .path("stream")
+ .queryParam("count", count)
+ .queryParam("pauseMillis", pauseMillis)
+ .request().get();
+
+ fail("This operation should trigger total timeout");
+ } catch (ProcessingException e) {
+ assertEquals(TimeoutException.class, e.getCause().getClass());
+ }
+ }
+
+ /**
+ * Test accessing an operation that is streaming slowly
+ *
+ * @throws ProcessingException in case of a test error.
+ */
+ @Test
+ public void testSlowToStartStreamedContentDoesReadTimeout() throws Exception {
+
+ int start = 150;
+ int count = 5;
+ int pauseMillis = 50;
+
+ try {
+ target("test")
+ .property(ClientProperties.READ_TIMEOUT, 100L)
+ .property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER, "-1")
+ .path("stream")
+ .queryParam("start", start)
+ .queryParam("count", count)
+ .queryParam("pauseMillis", pauseMillis)
+ .request().get();
+ fail("This operation should trigger idle timeout");
+ } catch (ProcessingException e) {
+ assertEquals(TimeoutException.class, e.getCause().getClass());
+ }
+ }
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TraceSupportTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TraceSupportTest.java
new file mode 100644
index 0000000..751f127
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/TraceSupportTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import java.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.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.process.Inflector;
+import org.glassfish.jersey.server.ContainerRequest;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.model.Resource;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * This very basic resource showcases support of a HTTP TRACE method,
+ * not directly supported by JAX-RS API.
+ *
+ * @author Marek Potociar
+ */
+public class TraceSupportTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(TraceSupportTest.class.getName());
+
+ /**
+ * 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(// toLowerCase - http header field names are case insensitive
+ responseEntity.contains(expectedFragment),
+ "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 Jetty11ConnectorProvider()));
+ }
+
+
+ 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");
+ }
+ }
+ }
+}
diff --git a/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/UnderlyingHttpClientAccessTest.java b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/UnderlyingHttpClientAccessTest.java
new file mode 100644
index 0000000..c1a6470
--- /dev/null
+++ b/connectors/jetty11-connector/src/test/java/org/glassfish/jersey/jetty11/connector/UnderlyingHttpClientAccessTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty11.connector;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+
+import org.glassfish.jersey.client.ClientConfig;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * Test of access to the underlying HTTP client instance used by the connector.
+ *
+ * @author Marek Potociar
+ */
+public class UnderlyingHttpClientAccessTest {
+
+ /**
+ * Verifier of JERSEY-2424 fix.
+ */
+ @Test
+ public void testHttpClientInstanceAccess() {
+ final Client client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new Jetty11ConnectorProvider()));
+ final HttpClient hcOnClient = Jetty11ConnectorProvider.getHttpClient(client);
+ // important: the web target instance in this test must be only created AFTER the client has been pre-initialized
+ // (see org.glassfish.jersey.client.Initializable.preInitialize method). This is here achieved by calling the
+ // connector provider's static getHttpClient method above.
+ final WebTarget target = client.target("http://localhost/");
+ final HttpClient hcOnTarget = Jetty11ConnectorProvider.getHttpClient(target);
+
+ assertNotNull(hcOnClient, "HTTP client instance set on JerseyClient should not be null.");
+ assertNotNull(hcOnTarget, "HTTP client instance set on JerseyWebTarget should not be null.");
+ 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).");
+ }
+
+ @Test
+ public void testGetProvidedClientInstance() {
+ final HttpClient httpClient = new HttpClient();
+ final ClientConfig clientConfig = new ClientConfig()
+ .connectorProvider(new Jetty11ConnectorProvider())
+ .register(new Jetty11HttpClientSupplier(httpClient));
+ final Client client = ClientBuilder.newClient(clientConfig);
+ final WebTarget target = client.target("http://localhost/");
+ final HttpClient hcOnTarget = Jetty11ConnectorProvider.getHttpClient(target);
+
+ assertThat("Instance provided to a ClientConfig differs from instance provided by JettyProvider",
+ httpClient, is(hcOnTarget));
+ }
+}
diff --git a/connectors/pom.xml b/connectors/pom.xml
index 0c2dcb4..3ac6040 100644
--- a/connectors/pom.xml
+++ b/connectors/pom.xml
@@ -40,6 +40,7 @@
<module>helidon-connector</module>
<module>jdk-connector</module>
<module>jetty-connector</module>
+ <module>jetty11-connector</module>
<module>jnh-connector</module>
<module>netty-connector</module>
</modules>
diff --git a/containers/grizzly2-http/pom.xml b/containers/grizzly2-http/pom.xml
index 0acec80..8d3dbd1 100644
--- a/containers/grizzly2-http/pom.xml
+++ b/containers/grizzly2-http/pom.xml
@@ -74,7 +74,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
- <artifactId>http2-http-client-transport</artifactId>
+ <artifactId>jetty-http2-client-transport</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
@@ -150,7 +150,7 @@
<profile>
<id>jdk11</id>
<activation>
- <jdk>[11,)</jdk>
+ <jdk>[11,17)</jdk>
</activation>
<build>
<pluginManagement>
@@ -161,8 +161,7 @@
<execution>
<id>default-testCompile</id>
<configuration>
- <source>11</source>
- <target>11</target>
+ <skip>true</skip>
</configuration>
</execution>
</executions>
diff --git a/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/tools/JettyHttpClientThread.java b/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/tools/JettyHttpClientThread.java
index 6a09e52..ec3f174 100644
--- a/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/tools/JettyHttpClientThread.java
+++ b/containers/grizzly2-http/src/test/java/org/glassfish/jersey/grizzly2/httpserver/test/tools/JettyHttpClientThread.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
@@ -20,12 +20,12 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
+import org.eclipse.jetty.client.ContentResponse;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpClientTransport;
-import org.eclipse.jetty.client.api.ContentResponse;
-import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
+import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
import org.eclipse.jetty.http2.client.HTTP2Client;
-import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
+import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import static org.junit.jupiter.api.Assertions.assertEquals;
diff --git a/containers/jetty-http/pom.xml b/containers/jetty-http/pom.xml
index 79abe32..a8c1a77 100644
--- a/containers/jetty-http/pom.xml
+++ b/containers/jetty-http/pom.xml
@@ -32,6 +32,13 @@
<description>Jetty Http Container</description>
+ <properties>
+ <java11.build.outputDirectory>${project.basedir}/target</java11.build.outputDirectory>
+ <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
+ <java17.build.outputDirectory>${project.basedir}/target17</java17.build.outputDirectory>
+ <java17.sourceDirectory>${project.basedir}/src/main/java17</java17.sourceDirectory>
+ </properties>
+
<dependencies>
<dependency>
<groupId>jakarta.inject</groupId>
@@ -63,7 +70,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-util</artifactId>
+ <artifactId>jetty-security</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -118,4 +125,144 @@
</resources>
</build>
+ <profiles>
+ <profile>
+ <id>JettyExclude</id>
+ <activation>
+ <jdk>[11,17)</jdk>
+ </activation>
+ <properties>
+ <jetty.version>${jetty11.version}</jetty.version>
+ </properties>
+ <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>
+ <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>JettyInclude</id>
+ <activation>
+ <jdk>[17,)</jdk>
+ </activation>
+ <build>
+ <directory>${java17.build.outputDirectory}</directory>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${java17.sourceDirectory}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>copyJDK17FilesToMultiReleaseJar</id>
+ <activation>
+ <file>
+ <!-- ${java17.build.outputDirectory} does not work here -->
+ <exists>target17/classes/org/glassfish/jersey/jetty/JettyHttpContainer.class</exists>
+ </file>
+ <jdk>[11,17)</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-jdk17-classes</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${java11.build.outputDirectory}/classes/META-INF/versions/17</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${java17.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-jdk17-sources</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <property name="sources-jar" value="${java11.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+ <echo>sources-jar: ${sources-jar}</echo>
+ <zip destfile="${sources-jar}" update="true">
+ <zipfileset dir="${java17.sourceDirectory}" prefix="META-INF/versions/17"/>
+ </zip>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
</project>
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerProvider.java b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerProvider.java
index 4b80825..2e8b5c5 100644
--- a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerProvider.java
+++ b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerProvider.java
@@ -34,7 +34,7 @@
public static final String HANDLER_NAME = "org.eclipse.jetty.server.Handler";
@Override
public <T> T createContainer(final Class<T> type, final Application application) throws ProcessingException {
- if (JdkVersion.getJdkVersion().getMajor() < 11) {
+ if (JdkVersion.getJdkVersion().getMajor() < 17) {
throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
}
if (type != null && (HANDLER_NAME.equalsIgnoreCase(type.getCanonicalName()) || JettyHttpContainer.class == type)) {
@@ -45,7 +45,7 @@
public <T> T createContainer(final Class<T> type, final Application application,
Object parentContext) throws ProcessingException {
- if (JdkVersion.getJdkVersion().getMajor() < 11) {
+ if (JdkVersion.getJdkVersion().getMajor() < 17) {
throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
}
if (type != null && (HANDLER_NAME.equalsIgnoreCase(type.getCanonicalName()) || JettyHttpContainer.class == type)) {
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServerProvider.java b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServerProvider.java
index 5122435..5022fee 100644
--- 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
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018 Markus KARG. All rights reserved.
*
* This program and the accompanying materials are made available under the
@@ -17,9 +17,12 @@
package org.glassfish.jersey.jetty;
+import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.SeBootstrap;
import jakarta.ws.rs.core.Application;
+import org.glassfish.jersey.internal.util.JdkVersion;
+import org.glassfish.jersey.jetty.internal.LocalizationMessages;
import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
import org.glassfish.jersey.server.spi.WebServer;
import org.glassfish.jersey.server.spi.WebServerProvider;
@@ -36,6 +39,9 @@
@Override
public <T extends WebServer> T createServer(final Class<T> type, final Application application,
final SeBootstrap.Configuration configuration) {
+ if (JdkVersion.getJdkVersion().getMajor() < 17) {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
return WebServerProvider.isSupportedWebServer(JettyHttpServer.class, type, configuration)
? type.cast(new JettyHttpServer(application, JerseySeBootstrapConfiguration.from(configuration)))
: null;
@@ -44,6 +50,9 @@
@Override
public <T extends WebServer> T createServer(final Class<T> type, final Class<? extends Application> applicationClass,
final SeBootstrap.Configuration configuration) {
+ if (JdkVersion.getJdkVersion().getMajor() < 17) {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
return WebServerProvider.isSupportedWebServer(JettyHttpServer.class, type, configuration)
? type.cast(new JettyHttpServer(applicationClass, JerseySeBootstrapConfiguration.from(configuration)))
: null;
diff --git a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
new file mode 100644
index 0000000..55258ea
--- /dev/null
+++ b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainer.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.Application;
+import org.eclipse.jetty.server.Handler;
+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} implementation based on Jetty {@link Handler}.
+ *
+ * @author Arul Dhesiaseelan (aruld@acm.org)
+ * @author Libor Kramolis
+ * @author Marek Potociar
+ */
+public final class JettyHttpContainer implements Container {
+
+ @Override
+ public ResourceConfig getConfiguration() {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ @Override
+ public void reload() {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ @Override
+ public void reload(final ResourceConfig configuration) {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ @Override
+ public ApplicationHandler getApplicationHandler() {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ /**
+ * Create a new Jetty HTTP container.
+ *
+ * @param application JAX-RS / Jersey application to be deployed on Jetty HTTP container.
+ * @param parentContext DI provider specific context with application's registered bindings.
+ */
+ JettyHttpContainer(final Application application, final Object parentContext) {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ /**
+ * Create a new Jetty HTTP container.
+ *
+ * @param application JAX-RS / Jersey application to be deployed on Jetty HTTP container.
+ */
+ JettyHttpContainer(final Application application) {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ /**
+ * 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) {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+}
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
similarity index 74%
copy from containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
copy to containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
index 3ccb7b8..61e1977 100644
--- a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
+++ b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,32 +16,20 @@
package org.glassfish.jersey.jetty;
-import java.net.URI;
-import java.util.concurrent.ThreadFactory;
-
import jakarta.ws.rs.ProcessingException;
-
-import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.glassfish.jersey.jetty.internal.LocalizationMessages;
-import org.glassfish.jersey.process.JerseyProcessingUncaughtExceptionHandler;
import org.glassfish.jersey.server.ContainerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.spi.Container;
-import org.eclipse.jetty.server.Connector;
-import org.eclipse.jetty.server.HttpConfiguration;
-import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.SecureRequestCustomizer;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.server.SslConnectionFactory;
-import org.eclipse.jetty.util.ssl.SslContextFactory;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
+import java.net.URI;
/**
* Factory for creating and starting Jetty server handlers. This returns
* a handle to the started server as {@link Server} instances, which allows
- * the server to be stopped by invoking the {@link org.eclipse.jetty.server.Server#stop()} method.
+ * the server to be stopped by invoking the {@link Server#stop()} method.
* <p/>
* To start the server in HTTPS mode an {@link SslContextFactory} can be provided.
* This will be used to decrypt and encrypt information sent over the
@@ -91,7 +79,7 @@
* resource configuration.
* <p/>
* This implementation defers to the
- * {@link org.glassfish.jersey.server.ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+ * {@link ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
* for creating an Container that manages the root resources.
*
* @param uri the URI to create the http server. The URI scheme must be
@@ -117,7 +105,7 @@
* resource configuration.
* <p/>
* This implementation defers to the
- * {@link org.glassfish.jersey.server.ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
+ * {@link ContainerFactory#createContainer(Class, jakarta.ws.rs.core.Application)} method
* for creating an Container that manages the root resources.
*
* @param uri URI on which the Jersey web application will be deployed. Only first path segment will be
@@ -196,7 +184,7 @@
* @param uri the URI to create the http server. The URI scheme must be
* equal to {@code https}. The URI user information and host
* are ignored. If the URI port is not present then port
- * {@value org.glassfish.jersey.server.spi.Container#DEFAULT_HTTPS_PORT} will be
+ * {@value Container#DEFAULT_HTTPS_PORT} will be
* used. The URI path, query and fragment components are ignored.
* @param sslContextFactory this is the SSL context factory used to configure SSL connector
* @param config the resource configuration.
@@ -220,7 +208,7 @@
* @param uri the URI to create the http server. The URI scheme must be
* equal to {@code https}. The URI user information and host
* are ignored. If the URI port is not present then port
- * {@value org.glassfish.jersey.server.spi.Container#DEFAULT_HTTPS_PORT} will be
+ * {@value Container#DEFAULT_HTTPS_PORT} will be
* used. The URI path, query and fragment components are ignored.
* @param sslContextFactory this is the SSL context factory used to configure SSL connector
* @param handler the container that handles all HTTP requests
@@ -236,70 +224,6 @@
final SslContextFactory.Server sslContextFactory,
final JettyHttpContainer handler,
final boolean start) {
- if (uri == null) {
- throw new IllegalArgumentException(LocalizationMessages.URI_CANNOT_BE_NULL());
- }
- final String scheme = uri.getScheme();
- int defaultPort = Container.DEFAULT_HTTP_PORT;
-
- if (sslContextFactory == null) {
- if (!"http".equalsIgnoreCase(scheme)) {
- throw new IllegalArgumentException(LocalizationMessages.WRONG_SCHEME_WHEN_USING_HTTP());
- }
- } else {
- if (!"https".equalsIgnoreCase(scheme)) {
- throw new IllegalArgumentException(LocalizationMessages.WRONG_SCHEME_WHEN_USING_HTTPS());
- }
- defaultPort = Container.DEFAULT_HTTPS_PORT;
- }
- final int port = (uri.getPort() == -1) ? defaultPort : uri.getPort();
-
- final Server server = new Server(new JettyConnectorThreadPool());
- final HttpConfiguration config = new HttpConfiguration();
- if (sslContextFactory != null) {
- config.setSecureScheme("https");
- config.setSecurePort(port);
- config.addCustomizer(new SecureRequestCustomizer());
-
- final ServerConnector https = new ServerConnector(server,
- new SslConnectionFactory(sslContextFactory, "http/1.1"),
- new HttpConnectionFactory(config));
- https.setPort(port);
- server.setConnectors(new Connector[]{https});
-
- } else {
- final ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(config));
- http.setPort(port);
- server.setConnectors(new Connector[]{http});
- }
- if (handler != null) {
- server.setHandler(handler);
- }
-
- if (start) {
- try {
- // Start the server.
- server.start();
- } catch (final Exception e) {
- throw new ProcessingException(LocalizationMessages.ERROR_WHEN_CREATING_SERVER(), e);
- }
- }
- return server;
- }
-
- // TODO: Use https://www.eclipse.org/jetty/javadoc/current/org/eclipse/jetty/util/thread/QueuedThreadPool.html
- // #%3Cinit%3E(int,int,int,int,java.util.concurrent.BlockingQueue,java.lang.ThreadGroup,java.util.concurrent.ThreadFactory)
- //
- // Keeping this for backwards compatibility for the time being
- private static final class JettyConnectorThreadPool extends QueuedThreadPool {
- private final ThreadFactory threadFactory = new ThreadFactoryBuilder()
- .setNameFormat("jetty-http-server-%d")
- .setUncaughtExceptionHandler(new JerseyProcessingUncaughtExceptionHandler())
- .build();
-
- @Override
- public Thread newThread(Runnable runnable) {
- return threadFactory.newThread(runnable);
- }
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
}
}
diff --git a/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpServer.java b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpServer.java
new file mode 100644
index 0000000..70fcc56
--- /dev/null
+++ b/containers/jetty-http/src/main/java11/org/glassfish/jersey/jetty/JettyHttpServer.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 Markus KARG. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.jetty;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.Application;
+import org.glassfish.jersey.jetty.internal.LocalizationMessages;
+import org.glassfish.jersey.server.ContainerFactory;
+import org.glassfish.jersey.server.JerseySeBootstrapConfiguration;
+import org.glassfish.jersey.server.spi.WebServer;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Jersey {@code Server} implementation based on Jetty
+ * {@link org.eclipse.jetty.server.Server Server}.
+ *
+ * @author Markus KARG (markus@headcrashing.eu)
+ * @since 3.1.0
+ */
+final class JettyHttpServer implements WebServer {
+
+ private final JettyHttpContainer container;
+
+ private final org.eclipse.jetty.server.Server httpServer;
+
+ JettyHttpServer(final Application application, final JerseySeBootstrapConfiguration configuration) {
+ this(ContainerFactory.createContainer(JettyHttpContainer.class, application), configuration);
+ }
+
+ JettyHttpServer(final Class<? extends Application> applicationClass,
+ final JerseySeBootstrapConfiguration configuration) {
+ this(new JettyHttpContainer(applicationClass), configuration);
+ }
+
+ JettyHttpServer(final JettyHttpContainer container, final JerseySeBootstrapConfiguration configuration) {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ @Override
+ public final JettyHttpContainer container() {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ @Override
+ public final int port() {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ @Override
+ public final CompletableFuture<Void> start() {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ @Override
+ public final CompletableFuture<Void> stop() {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+ @Override
+ public final <T> T unwrap(final Class<T> nativeClass) {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+
+}
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.java b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainer.java
similarity index 70%
rename from containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.java
rename to containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainer.java
index 36be72d..dfe20f2 100644
--- a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.java
+++ b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainer.java
@@ -16,40 +16,38 @@
package org.glassfish.jersey.jetty;
-import java.io.IOException;
import java.io.OutputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.Principal;
-import java.util.Enumeration;
import java.util.List;
import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
-import jakarta.servlet.AsyncContext;
-import jakarta.servlet.AsyncEvent;
-import jakarta.servlet.AsyncListener;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.GenericType;
import jakarta.ws.rs.core.SecurityContext;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
+import org.eclipse.jetty.http.HttpField;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.io.Content;
+import org.eclipse.jetty.security.AuthenticationState;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.util.Callback;
import org.glassfish.jersey.internal.MapPropertiesDelegate;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.internal.inject.ReferencingFactory;
import org.glassfish.jersey.internal.util.ExtendedLogger;
import org.glassfish.jersey.internal.util.collection.Ref;
-import org.glassfish.jersey.jetty.internal.LocalizationMessages;
import org.glassfish.jersey.process.internal.RequestScoped;
import org.glassfish.jersey.server.ApplicationHandler;
import org.glassfish.jersey.server.ContainerException;
@@ -61,10 +59,8 @@
import org.glassfish.jersey.server.spi.Container;
import org.glassfish.jersey.server.spi.ContainerResponseWriter;
-import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
-import org.eclipse.jetty.server.handler.AbstractHandler;
/**
* Jersey {@code Container} implementation based on Jetty {@link org.eclipse.jetty.server.Handler}.
@@ -73,7 +69,7 @@
* @author Libor Kramolis
* @author Marek Potociar
*/
-public final class JettyHttpContainer extends AbstractHandler implements Container {
+public final class JettyHttpContainer extends Handler.Abstract implements Container {
private static final ExtendedLogger LOGGER =
new ExtendedLogger(Logger.getLogger(JettyHttpContainer.class.getName()), Level.FINEST);
@@ -87,7 +83,7 @@
/**
* Cached value of configuration property
* {@link org.glassfish.jersey.server.ServerProperties#RESPONSE_SET_STATUS_OVER_SEND_ERROR}.
- * If {@code true} method {@link HttpServletResponse#setStatus} is used over {@link HttpServletResponse#sendError}.
+ * If {@code true} method {@link Response#setStatus(int)} is used over {@link Response#writeError(Request, Response, Callback, int)}
*/
private boolean configSetStatusOverSendError;
@@ -137,15 +133,9 @@
private volatile ApplicationHandler appHandler;
@Override
- public void handle(final String target, final Request request, final HttpServletRequest httpServletRequest,
- final HttpServletResponse httpServletResponse) throws IOException, ServletException {
+ public boolean handle(Request request, Response response, Callback callback) throws Exception {
- if (request.isHandled()) {
- return;
- }
-
- final Response response = request.getResponse();
- final ResponseWriter responseWriter = new ResponseWriter(request, response, configSetStatusOverSendError);
+ final ResponseWriter responseWriter = new ResponseWriter(request, response, callback, configSetStatusOverSendError);
try {
final URI baseUri = getBaseUri(request);
final URI requestUri = getRequestUri(request, baseUri);
@@ -156,34 +146,31 @@
getSecurityContext(request),
new MapPropertiesDelegate(),
appHandler.getConfiguration());
- requestContext.setEntityStream(request.getInputStream());
- final Enumeration<String> headerNames = request.getHeaderNames();
- while (headerNames.hasMoreElements()) {
- final String headerName = headerNames.nextElement();
- String headerValue = request.getHeader(headerName);
- requestContext.headers(headerName, headerValue == null ? "" : headerValue);
- }
+ requestContext.setEntityStream(Request.asInputStream(request));
+ request.getHeaders().forEach(httpField ->
+ requestContext.headers(httpField.getName(), httpField.getValue() == null ? "" : httpField.getValue()));
requestContext.setWriter(responseWriter);
requestContext.setRequestScopedInitializer(injectionManager -> {
injectionManager.<Ref<Request>>getInstance(REQUEST_TYPE).set(request);
injectionManager.<Ref<Response>>getInstance(RESPONSE_TYPE).set(response);
});
- // Mark the request as handled before generating the body of the response
- request.setHandled(true);
appHandler.handle(requestContext);
+ return true;
} catch (URISyntaxException e) {
- setResponseForInvalidUri(response, e);
+ setResponseForInvalidUri(request, response, callback, e);
+ return true;
} catch (final Exception ex) {
+ callback.failed(ex);
throw new RuntimeException(ex);
}
}
private URI getRequestUri(final Request request, final URI baseUri) throws URISyntaxException {
final String serverAddress = getServerAddress(baseUri);
- String uri = request.getRequestURI();
+ String uri = request.getHttpURI().getPath();
- final String queryString = request.getQueryString();
+ final String queryString = request.getHttpURI().getQuery();
if (queryString != null) {
uri = uri + "?" + ContainerUtils.encodeUnsafeCharacters(queryString);
}
@@ -191,15 +178,17 @@
return new URI(serverAddress + uri);
}
- private void setResponseForInvalidUri(final HttpServletResponse response, final Throwable throwable) throws IOException {
+ private void setResponseForInvalidUri(final Request request, final Response response,
+ final Callback callback, final Throwable throwable) {
LOGGER.log(Level.FINER, "Error while processing request.", throwable);
if (configSetStatusOverSendError) {
response.reset();
- //noinspection deprecation
response.setStatus(BAD_REQUEST_STATUS.getStatusCode());
+ callback.failed(throwable);
} else {
- response.sendError(BAD_REQUEST_STATUS.getStatusCode(), BAD_REQUEST_STATUS.getReasonPhrase());
+ Response.writeError(request, response, callback, BAD_REQUEST_STATUS.getStatusCode(),
+ BAD_REQUEST_STATUS.getReasonPhrase(), throwable);
}
}
@@ -212,11 +201,14 @@
}
private SecurityContext getSecurityContext(final Request request) {
+
+ AuthenticationState.Succeeded authenticationState = AuthenticationState.authenticate(request);
+
return new SecurityContext() {
@Override
public boolean isUserInRole(final String role) {
- return request.isUserInRole(role);
+ return authenticationState != null && authenticationState.isUserInRole(role);
}
@Override
@@ -226,24 +218,24 @@
@Override
public Principal getUserPrincipal() {
- return request.getUserPrincipal();
+ return authenticationState != null ? authenticationState.getUserIdentity().getUserPrincipal() : null;
}
@Override
public String getAuthenticationScheme() {
- return request.getAuthType();
+ return authenticationState != null ? authenticationState.getAuthenticationType() : null;
}
};
}
private URI getBaseUri(final Request request) throws URISyntaxException {
- return new URI(request.getScheme(), null, request.getServerName(),
- request.getServerPort(), getBasePath(request), null, null);
+ return new URI(request.getHttpURI().getScheme(), null, Request.getServerName(request),
+ Request.getServerPort(request), getBasePath(request), null, null);
}
private String getBasePath(final Request request) {
- final String contextPath = request.getContextPath();
+ final String contextPath = Request.getContextPath(request);
if (contextPath == null || contextPath.isEmpty()) {
return "/";
@@ -256,16 +248,38 @@
private static final class ResponseWriter implements ContainerResponseWriter {
+ private final Request request;
private final Response response;
- private final AsyncContext context;
+ private final Callback callback;
private final boolean configSetStatusOverSendError;
+ private final Timer timer = new Timer();
+ private final long asyncStartTimeMillis;
+ private final ConcurrentLinkedQueue<TimeoutHandler> timeoutHandlerQueue = new ConcurrentLinkedQueue<>();
+ private TimerTask currentTimerTask;
- ResponseWriter(final Request request, final Response response, final boolean configSetStatusOverSendError) {
+ ResponseWriter(final Request request, final Response response, final Callback callback,
+ final boolean configSetStatusOverSendError) {
+ this.request = request;
this.response = response;
- this.context = request.startAsync();
+ this.callback = callback;
+ this.asyncStartTimeMillis = System.currentTimeMillis();
this.configSetStatusOverSendError = configSetStatusOverSendError;
}
+ private synchronized void setNewTimeout(long timeOut, TimeUnit timeUnit) {
+ long timeOutMillis = timeUnit.toMillis(timeOut);
+ if (currentTimerTask != null) {
+ currentTimerTask.cancel();
+ }
+ currentTimerTask = new TimerTask() {
+ @Override
+ public void run() {
+ timeoutHandlerQueue.forEach(timeoutHandler -> timeoutHandler.onTimeout(ResponseWriter.this));
+ }
+ };
+ timer.schedule(currentTimerTask, Math.max(0, timeOutMillis + asyncStartTimeMillis - System.currentTimeMillis()));
+ }
+
@Override
public OutputStream writeResponseStatusAndHeaders(final long contentLength, final ContainerResponse context)
throws ContainerException {
@@ -273,99 +287,43 @@
final jakarta.ws.rs.core.Response.StatusType statusInfo = context.getStatusInfo();
final int code = statusInfo.getStatusCode();
- final String reason = statusInfo.getReasonPhrase() == null
- ? HttpStatus.getMessage(code) : statusInfo.getReasonPhrase();
- response.setStatusWithReason(code, reason);
+ response.setStatus(code);
- if (contentLength != -1 && contentLength < Integer.MAX_VALUE) {
- response.setContentLength((int) contentLength);
+ if (contentLength != -1 && contentLength < Integer.MAX_VALUE && !"HEAD".equals(request.getMethod())) {
+ response.getHeaders().add(new HttpField(HttpHeader.CONTENT_LENGTH, String.valueOf((int) contentLength)));
}
for (final Map.Entry<String, List<String>> e : context.getStringHeaders().entrySet()) {
for (final String value : e.getValue()) {
- response.addHeader(e.getKey(), value);
+ response.getHeaders().add(new HttpField(e.getKey(), value));
}
}
- try {
- return response.getOutputStream();
- } catch (final IOException ioe) {
- throw new ContainerException("Error during writing out the response headers.", ioe);
- }
+ return Content.Sink.asOutputStream(response);
}
@Override
public boolean suspend(final long timeOut, final TimeUnit timeUnit, final TimeoutHandler timeoutHandler) {
- try {
- if (timeOut > 0) {
- final long timeoutMillis = TimeUnit.MILLISECONDS.convert(timeOut, timeUnit);
- context.setTimeout(timeoutMillis);
- }
- context.addListener(new AsyncListener() {
- @Override
- public void onComplete(AsyncEvent asyncEvent) throws IOException {
-
- }
-
- @Override
- public void onTimeout(AsyncEvent asyncEvent) throws IOException {
- if (timeoutHandler != null) {
- timeoutHandler.onTimeout(ResponseWriter.this);
- }
- }
-
- @Override
- public void onError(AsyncEvent asyncEvent) throws IOException {
-
- }
-
- @Override
- public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
-
- }
- });
- return true;
- } catch (final Exception ex) {
- return false;
+ if (timeOut > 0) {
+ setNewTimeout(timeOut, timeUnit);
}
+ if (timeoutHandler != null) {
+ timeoutHandlerQueue.add(timeoutHandler);
+ }
+ return true;
}
@Override
public void setSuspendTimeout(final long timeOut, final TimeUnit timeUnit) throws IllegalStateException {
if (timeOut > 0) {
- final long timeoutMillis = TimeUnit.MILLISECONDS.convert(timeOut, timeUnit);
- context.setTimeout(timeoutMillis);
+ setNewTimeout(timeOut, timeUnit);
}
}
@Override
public void commit() {
- try {
- closeOutput(response);
- } catch (final IOException e) {
- LOGGER.log(Level.WARNING, LocalizationMessages.UNABLE_TO_CLOSE_RESPONSE(), e);
- } finally {
- if (context.getRequest().isAsyncStarted()) {
- context.complete();
- }
- LOGGER.log(Level.FINEST, "commit() called");
- }
- }
-
- private void closeOutput(Response response) throws IOException {
- try {
- response.completeOutput();
- } catch (final IOException e) {
- throw e;
- } catch (NoSuchMethodError e) {
- // try older Jetty Response#closeOutput
- try {
- Method method = response.getClass().getMethod("closeOutput");
- method.invoke(response);
- } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
- throw new IOException(ex);
- }
- }
+ callback.succeeded();
+ LOGGER.log(Level.FINEST, "commit() called");
}
@Override
@@ -375,22 +333,18 @@
try {
if (configSetStatusOverSendError) {
response.reset();
- //noinspection deprecation
- response.setStatus(INTERNAL_SERVER_ERROR, "Request failed.");
+ response.setStatus(INTERNAL_SERVER_ERROR);
+ callback.failed(error);
} else {
- response.sendError(INTERNAL_SERVER_ERROR, "Request failed.");
+ Response.writeError(request, response, callback, INTERNAL_SERVER_ERROR, "Request failed.", error);
}
} catch (final IllegalStateException ex) {
// a race condition externally committing the response can still occur...
LOGGER.log(Level.FINER, "Unable to reset failed response.", ex);
- } catch (final IOException ex) {
- throw new ContainerException(LocalizationMessages.EXCEPTION_SENDING_ERROR_RESPONSE(INTERNAL_SERVER_ERROR,
- "Request failed."), ex);
}
}
} finally {
LOGGER.log(Level.FINEST, "failure(...) called");
- commit();
rethrow(error);
}
}
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
similarity index 99%
rename from containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
rename to containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
index 3ccb7b8..26a4b79 100644
--- a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
+++ b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpContainerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServer.java b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpServer.java
similarity index 98%
rename from containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServer.java
rename to containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpServer.java
index 64af030..9734342 100644
--- a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpServer.java
+++ b/containers/jetty-http/src/main/java17/org/glassfish/jersey/jetty/JettyHttpServer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018 Markus KARG. All rights reserved.
*
* This program and the accompanying materials are made available under the
diff --git a/containers/jetty-http/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties b/containers/jetty-http/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
index 6d0d06c..8d507d5 100644
--- a/containers/jetty-http/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
+++ b/containers/jetty-http/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -21,4 +21,4 @@
uri.cannot.be.null=The URI must not be null.
wrong.scheme.when.using.http=The URI scheme should be 'http' when not using SSL.
wrong.scheme.when.using.https=The URI scheme should be 'https' when using SSL.
-not.supported=Jetty container is not supported on JDK version less than 11.
+not.supported=Jetty container is not supported on JDK version less than 17.
diff --git a/containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties b/containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties
index 9807184..ba290bd 100644
--- a/containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties
+++ b/containers/jetty-http2/src/main/resources/org/glassfish/jersey/jetty/http2/localization.properties
@@ -16,4 +16,4 @@
# {0} - status code; {1} - status reason message
error.when.creating.server=Exception thrown when trying to create jetty server.
-not.supported=Jetty container is not supported on JDK version less than 11.
\ No newline at end of file
+not.supported=Jetty container is not supported on JDK version less than 17.
\ No newline at end of file
diff --git a/containers/jetty-servlet/pom.xml b/containers/jetty-servlet/pom.xml
index 1ead1f2..1f3c4db 100644
--- a/containers/jetty-servlet/pom.xml
+++ b/containers/jetty-servlet/pom.xml
@@ -32,6 +32,13 @@
<description>Jetty Servlet Container</description>
+ <properties>
+ <java11.build.outputDirectory>${project.basedir}/target</java11.build.outputDirectory>
+ <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
+ <java17.build.outputDirectory>${project.basedir}/target17</java17.build.outputDirectory>
+ <java17.sourceDirectory>${project.basedir}/src/main/java17</java17.sourceDirectory>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
@@ -48,8 +55,8 @@
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
<dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-webapp</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-webapp</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -90,4 +97,175 @@
</plugins>
</build>
+ <profiles>
+ <profile>
+ <id>JettyExclude</id>
+ <activation>
+ <jdk>[11,17)</jdk>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-webapp</artifactId>
+ <version>${jetty11.version}</version>
+ <scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-webapp</artifactId>
+ <scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>${jetty11.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-jetty-http</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ </exclusion>
+ </exclusions>
+ </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>JettyInclude</id>
+ <activation>
+ <jdk>[17,)</jdk>
+ </activation>
+ <build>
+ <directory>${java17.build.outputDirectory}</directory>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${java17.sourceDirectory}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>copyJDK17FilesToMultiReleaseJar</id>
+ <activation>
+ <file>
+ <!-- ${java17.build.outputDirectory} does not work here -->
+ <exists>target17/classes/org/glassfish/jersey/jetty/JettyWebContainerFactory.class</exists>
+ </file>
+ <jdk>[11,17)</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-jdk17-classes</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${java11.build.outputDirectory}/classes/META-INF/versions/17</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${java17.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-jdk17-sources</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <property name="sources-jar" value="${java11.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+ <echo>sources-jar: ${sources-jar}</echo>
+ <zip destfile="${sources-jar}" update="true">
+ <zipfileset dir="${java17.sourceDirectory}" prefix="META-INF/versions/17"/>
+ </zip>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
</project>
diff --git a/containers/jetty-servlet/src/main/java/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java b/containers/jetty-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
similarity index 84%
copy from containers/jetty-servlet/src/main/java/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
copy to containers/jetty-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
index a663a50..afbec62 100644
--- a/containers/jetty-servlet/src/main/java/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
+++ b/containers/jetty-servlet/src/main/java11/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,21 +16,15 @@
package org.glassfish.jersey.jetty.servlet;
+import jakarta.servlet.Servlet;
+import jakarta.ws.rs.ProcessingException;
+import org.eclipse.jetty.server.Server;
+import org.glassfish.jersey.jetty.internal.LocalizationMessages;
+import org.glassfish.jersey.servlet.ServletContainer;
+
import java.net.URI;
import java.util.Map;
-import jakarta.servlet.Servlet;
-
-import org.glassfish.jersey.jetty.JettyHttpContainerFactory;
-import org.glassfish.jersey.servlet.ServletContainer;
-import org.glassfish.jersey.uri.UriComponent;
-
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.webapp.Configuration;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.webapp.WebXmlConfiguration;
-
/**
* Factory for creating and starting Jetty {@link Server} instances
* for deploying a Servlet.
@@ -216,46 +210,7 @@
private static Server create(URI u, Class<? extends Servlet> c, Servlet servlet,
Map<String, String> initParams, Map<String, String> contextInitParams)
throws Exception {
- if (u == null) {
- throw new IllegalArgumentException("The URI must not be null");
- }
-
- String path = u.getPath();
- if (path == null) {
- throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be non-null");
- } else if (path.isEmpty()) {
- throw new IllegalArgumentException("The URI path, of the URI " + u + ", must be present");
- } else if (path.charAt(0) != '/') {
- throw new IllegalArgumentException("The URI path, of the URI " + u + ". must start with a '/'");
- }
-
- path = String.format("/%s", UriComponent.decodePath(u.getPath(), true).get(1).toString());
- WebAppContext context = new WebAppContext();
- context.setDisplayName("JettyContext");
- context.setContextPath(path);
- context.setConfigurations(new Configuration[]{new WebXmlConfiguration()});
- ServletHolder holder;
- if (c != null) {
- holder = context.addServlet(c, "/*");
- } else {
- holder = new ServletHolder(servlet);
- context.addServlet(holder, "/*");
- }
-
- if (contextInitParams != null) {
- for (Map.Entry<String, String> e : contextInitParams.entrySet()) {
- context.setInitParameter(e.getKey(), e.getValue());
- }
- }
-
- if (initParams != null) {
- holder.setInitParameters(initParams);
- }
-
- Server server = JettyHttpContainerFactory.createServer(u, false);
- server.setHandler(context);
- server.start();
- return server;
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
}
/**
@@ -281,4 +236,4 @@
}
return create(u, null, servlet, initParams, contextInitParams);
}
-}
+}
\ No newline at end of file
diff --git a/containers/jetty-servlet/src/main/java/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java b/containers/jetty-servlet/src/main/java17/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
similarity index 97%
rename from containers/jetty-servlet/src/main/java/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
rename to containers/jetty-servlet/src/main/java17/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
index a663a50..5ada3ed 100644
--- a/containers/jetty-servlet/src/main/java/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
+++ b/containers/jetty-servlet/src/main/java17/org/glassfish/jersey/jetty/servlet/JettyWebContainerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -26,10 +26,10 @@
import org.glassfish.jersey.uri.UriComponent;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.webapp.Configuration;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.eclipse.jetty.ee10.servlet.ServletHolder;
+import org.eclipse.jetty.ee10.webapp.Configuration;
+import org.eclipse.jetty.ee10.webapp.WebAppContext;
+import org.eclipse.jetty.ee10.webapp.WebXmlConfiguration;
/**
* Factory for creating and starting Jetty {@link Server} instances
@@ -281,4 +281,4 @@
}
return create(u, null, servlet, initParams, contextInitParams);
}
-}
+}
\ No newline at end of file
diff --git a/containers/jetty-servlet/src/main/resources/org/glassfish/jersey/jetty/servlet/internal/localization.properties b/containers/jetty-servlet/src/main/resources/org/glassfish/jersey/jetty/servlet/internal/localization.properties
index c362bf0..6504f0e 100644
--- a/containers/jetty-servlet/src/main/resources/org/glassfish/jersey/jetty/servlet/internal/localization.properties
+++ b/containers/jetty-servlet/src/main/resources/org/glassfish/jersey/jetty/servlet/internal/localization.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2020, 2023 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,4 +15,4 @@
#
# {0} - status code; {1} - status reason message
-not.supported=Jetty container is not supported on JDK version less than 11.
+not.supported=Jetty container is not supported on JDK version less than 17.
diff --git a/docs/src/main/docbook/appendix-properties.xml b/docs/src/main/docbook/appendix-properties.xml
index 78bfb96..d7c19e2 100644
--- a/docs/src/main/docbook/appendix-properties.xml
+++ b/docs/src/main/docbook/appendix-properties.xml
@@ -1121,7 +1121,8 @@
&jersey.apache5.Apache5ConnectorProvider;,
&jersey.grizzly.GrizzlyConnectorProvider;,
&jersey.helidon.HelidonConnectorProvider;,
- &jersey.netty.NettyConnectorProvider;, and
+ &jersey.netty.NettyConnectorProvider;,
+ &jersey.jetty11.Jetty11ConnectorProvider;, and
&jersey.jetty.JettyConnectorProvider; only.</emphasis>
</para>
</entry>
diff --git a/docs/src/main/docbook/client.xml b/docs/src/main/docbook/client.xml
index 4db3010..fb449e2 100644
--- a/docs/src/main/docbook/client.xml
+++ b/docs/src/main/docbook/client.xml
@@ -656,11 +656,16 @@
<entry><literal>org.glassfish.jersey.connectors:jersey-helidon-connector</literal></entry>
</row>
<row>
- <entry>Jetty HTTP client</entry>
+ <entry>Jetty HTTP client (JDK 17+)</entry>
<entry>&jersey.jetty.JettyConnectorProvider;</entry>
<entry><literal>org.glassfish.jersey.connectors:jersey-jetty-connector</literal></entry>
</row>
<row>
+ <entry>Jetty 11.x HTTP client</entry>
+ <entry>&jersey.jetty11.Jetty11ConnectorProvider;</entry>
+ <entry><literal>org.glassfish.jersey.connectors:jersey-jetty11-connector</literal></entry>
+ </row>
+ <row>
<entry>Netty NIO framework</entry>
<entry>&jersey.netty.NettyConnectorProvider;</entry>
<entry><literal>org.glassfish.jersey.connectors:jersey-netty-connector</literal></entry>
@@ -858,6 +863,21 @@
</programlisting>
</para>
</section>
+ <section>
+ <title>Jetty 11.x HttpClient Configuration</title>
+ <para>
+ For Jetty Connector, an &jersey.jetty11.Jetty11HttpClientSupplier; SPI allows for providing a configured instance
+ of <literal>org.eclipse.jetty.client.HttpClient</literal>:
+ <programlisting language="java" linenumbering="numbered">
+ HttpClient httpClient = new HttpClient(...);
+ ClientConfig clientConfig = new ClientConfig()
+ .connectorProvider(new Jetty11ConnectorProvider())
+ .register(new Jetty11HttpClientSupplier(httpClient));
+ Client client = ClientBuilder.newClient(clientConfig);
+ ...
+ </programlisting>
+ </para>
+ </section>
</section>
</section>
@@ -1008,9 +1028,9 @@
revalidate URL using a custom implementation of &lit.jdk6.HostnameVerifier; and go on in a handshake processing.
&lit.jersey.jetty.JettyConnectorProvider; and &lit.jersey.grizzly.GrizzlyConnectorProvider; provide only host URL verification
and throw a &lit.jdk6.CertificateException; without any possibility to use custom &lit.jdk6.HostnameVerifier;.
- Moreover, in case of &lit.jersey.jetty.JettyConnectorProvider; there is a property
- &jersey.jetty.JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION; to disable an entire host URL verification
- mechanism in a handshake.
+ Moreover, in case of &lit.jersey.jetty.JettyConnectorProvider; and &lit.jersey.jetty11.Jetty11ConnectorProvider; there are the properties
+ &jersey.jetty.JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION; and &jersey.jetty11.Jetty11ClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION;
+ to disable an entire host URL verification mechanism in a handshake.
</para>
</important>
diff --git a/docs/src/main/docbook/dependencies.xml b/docs/src/main/docbook/dependencies.xml
index 53bdfae..176fe08 100644
--- a/docs/src/main/docbook/dependencies.xml
+++ b/docs/src/main/docbook/dependencies.xml
@@ -175,7 +175,12 @@
<artifactId>jersey-apache-connector</artifactId>
<version>&version;</version>
</dependency>
-<!-- Requires JDK 11+ -->
+<dependency>
+ <groupId>org.glassfish.jersey.connectory</groupId>
+ <artifactId>jersey-jetty11-connector</artifactId>
+ <version>&version;</version>
+</dependency>
+<!-- Requires JDK 17+ -->
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-jetty-connector</artifactId>
diff --git a/docs/src/main/docbook/jersey.ent b/docs/src/main/docbook/jersey.ent
index ab13afb..cae4245 100644
--- a/docs/src/main/docbook/jersey.ent
+++ b/docs/src/main/docbook/jersey.ent
@@ -487,6 +487,14 @@
<!ENTITY jersey.jetty.JettyHttpContainerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/JettyHttpContainerFactory.html'>JettyHttpContainerFactory</link>">
<!ENTITY jersey.jetty.JettyHttpContainerProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/JettyHttpContainerProvider.html'>JettyHttpContainerProvider</link>">
<!ENTITY jersey.jetty.JettyWebContainerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/servlet/JettyWebContainerFactory.html'>JettyWebContainerFactory</link>">
+<!ENTITY jersey.jetty11.Jetty11ClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html'>Jetty11ClientProperties</link>" >
+<!ENTITY jersey.jetty11.Jetty11HttpClientSupplier "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11HttpClientSupplier.html'>Jetty11HttpClientSupplier</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#ENABLE_SSL_HOSTNAME_VERIFICATION'>Jetty11ClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.DISABLE_COOKIES "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#DISABLE_COOKIES'>Jetty11ClientProperties.DISABLE_COOKIES</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#PREEMPTIVE_BASIC_AUTHENTICATION'>Jetty11ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#SYNC_LISTENER_RESPONSE_MAX_SIZE'>Jetty11ClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE</link>" >
+<!ENTITY jersey.jetty11.Jetty11ClientProperties.TOTAL_TIMEOUT "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ClientProperties.html#TOTAL_TIMEOUT'>Jetty11ClientProperties.TOTAL_TIMEOUT</link>" >
+<!ENTITY jersey.jetty11.Jetty11ConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty11/connector/Jetty11ConnectorProvider.html'>Jetty11ConnectorProvider</link>">
<!ENTITY jersey.jnh.JavaNetHttpConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpConnectorProvider.html'>JavaNetHttpConnectorProvider</link>">
<!ENTITY jersey.jnh.JavaNetHttpClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html'>JavaNetHttpClientProperties</link>">
<!ENTITY jersey.jnh.JavaNetHttpClientProperties.COOKIE_HANDLER "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#COOKIE_HANDLER'>JavaNetHttpClientProperties.COOKIE_HANDLER</link>">
@@ -997,6 +1005,7 @@
<!ENTITY lit.jersey.jetty.JettyHttpContainerFactory "<literal>JettyHttpContainerFactory</literal>">
<!ENTITY lit.jersey.jetty.JettyHttpContainerProvider "<literal>JettyHttpContainerProvider</literal>">
<!ENTITY lit.jersey.jetty.JettyWebContainerFactory "<literal>JettyWebContainerFactory</literal>">
+<!ENTITY lit.jersey.jetty11.Jetty11ConnectorProvider "<literal>Jetty11ConnectorProvider</literal>">
<!ENTITY lit.jersey.linking.DeclarativeLinkingFeature "<literal>DeclarativeLinkingFeature</literal>">
<!ENTITY lit.jersey.logging.LoggingFeature "<literal>LoggingFeature</literal>">
<!ENTITY lit.jersey.logging.LoggingFeature.DEFAULT_LOGGER_NAME "<literal>LoggingFeature.DEFAULT_LOGGER_NAME</literal>">
diff --git a/docs/src/main/docbook/modules.xml b/docs/src/main/docbook/modules.xml
index c7deae9..e83fbd4 100644
--- a/docs/src/main/docbook/modules.xml
+++ b/docs/src/main/docbook/modules.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
@@ -206,7 +206,15 @@
jersey-jetty-connector
</link>
</entry>
-<entry>Jersey Client Transport via Jetty (for JDK 11+)</entry>
+<entry>Jersey Client Transport via Jetty (for JDK 17+)</entry>
+</row>
+<row>
+<entry>
+<link xlink:href="https://eclipse-ee4j.github.io/jersey.github.io/project-info/&version;/jersey/project/jersey-jetty11-connector/dependencies.html">
+ jersey-jetty11-connector
+</link>
+</entry>
+<entry>Jersey Client Transport via Jetty 11.x</entry>
</row>
<row>
<entry>
diff --git a/ext/microprofile/mp-config/pom.xml b/ext/microprofile/mp-config/pom.xml
index 4409ecd..7e7aa30 100644
--- a/ext/microprofile/mp-config/pom.xml
+++ b/ext/microprofile/mp-config/pom.xml
@@ -95,7 +95,7 @@
<profile>
<id>JettyExclude</id>
<activation>
- <jdk>1.8</jdk>
+ <jdk>[11,17)</jdk>
</activation>
<build>
<plugins>
@@ -112,9 +112,9 @@
</build>
</profile>
<profile>
- <id>Jetty11</id>
+ <id>Jetty17</id>
<activation>
- <jdk>[11,)</jdk>
+ <jdk>[17,)</jdk>
</activation>
<dependencies>
<dependency>
diff --git a/media/multipart/pom.xml b/media/multipart/pom.xml
index b3c7adc..79d4d86 100644
--- a/media/multipart/pom.xml
+++ b/media/multipart/pom.xml
@@ -92,12 +92,6 @@
<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>
@@ -106,4 +100,39 @@
</dependency>
</dependencies>
+ <profiles>
+ <profile>
+ <id>JettyExclude</id>
+ <activation>
+ <jdk>[11,17)</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>[17,)</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/pom.xml b/pom.xml
index e5f9807..76bc376 100644
--- a/pom.xml
+++ b/pom.xml
@@ -734,8 +734,8 @@
<version>8.1.8.v20121106</version>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
<version>${jetty.plugin.version}</version>
</plugin>
<plugin>
@@ -1746,7 +1746,7 @@
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-webapp</artifactId>
+ <artifactId>jetty-security</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
@@ -1759,6 +1759,11 @@
<artifactId>jetty-alpn-conscrypt-server</artifactId>
<version>${jetty.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-webapp</artifactId>
+ <version>${jetty.version}</version>
+ </dependency>
<dependency>
<groupId>org.simpleframework</groupId>
@@ -2356,9 +2361,10 @@
<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.15</jetty.version>
+ <jetty.version>12.0.0</jetty.version>
<jetty9.version>9.4.51.v20230217</jetty9.version>
- <jetty.plugin.version>11.0.14</jetty.plugin.version>
+ <jetty11.version>11.0.15</jetty11.version>
+ <jetty.plugin.version>12.0.0</jetty.plugin.version>
<jsonb.api.version>3.0.0</jsonb.api.version>
<jsonp.ri.version>1.1.1</jsonp.ri.version>
<jsonp.jaxrs.version>1.1.1</jsonp.jaxrs.version>
diff --git a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties b/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
index 2886c72..f10b03c 100644
--- a/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
+++ b/test-framework/providers/jetty-http2/src/main/resources/org/glassfish/jersey/test/jetty/http2/localization.properties
@@ -15,4 +15,4 @@
#
# {0} - status code; {1} - status reason message
-not.supported=Jetty container is not supported on JDK version less than 11.
+not.supported=Jetty container is not supported on JDK version less than 17.
diff --git a/test-framework/providers/jetty/pom.xml b/test-framework/providers/jetty/pom.xml
index 7e6ed8e..ea1bb3a 100644
--- a/test-framework/providers/jetty/pom.xml
+++ b/test-framework/providers/jetty/pom.xml
@@ -42,6 +42,158 @@
<artifactId>jersey-container-jetty-http</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
</dependencies>
+ <properties>
+ <java11.build.outputDirectory>${project.basedir}/target</java11.build.outputDirectory>
+ <java11.sourceDirectory>${project.basedir}/src/main/java11</java11.sourceDirectory>
+ <java17.build.outputDirectory>${project.basedir}/target17</java17.build.outputDirectory>
+ <java17.sourceDirectory>${project.basedir}/src/main/java17</java17.sourceDirectory>
+ </properties>
+
+ <profiles>
+ <profile>
+ <id>JettyExclude</id>
+ <activation>
+ <jdk>[11,17)</jdk>
+ </activation>
+ <properties>
+ <jetty.version>${jetty11.version}</jetty.version>
+ </properties>
+ <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>
+ <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>Jetty17</id>
+ <activation>
+ <jdk>[17,)</jdk>
+ </activation>
+ <build>
+ <directory>${java17.build.outputDirectory}</directory>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${java17.sourceDirectory}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>copyJDK17FilesToMultiReleaseJar</id>
+ <activation>
+ <file>
+ <!-- ${java11.build.outputDirectory} does not work here -->
+ <exists>target17/classes/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.class</exists>
+ </file>
+ <jdk>[11,17)</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-jdk17-classes</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${java11.build.outputDirectory}/classes/META-INF/versions/17</outputDirectory>
+ <resources>
+ <resource>
+ <directory>${java17.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-jdk17-sources</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <property name="sources-jar" value="${java11.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+ <echo>sources-jar: ${sources-jar}</echo>
+ <zip destfile="${sources-jar}" update="true">
+ <zipfileset dir="${java17.sourceDirectory}" prefix="META-INF/versions/17"/>
+ </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/java11/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
new file mode 100644
index 0000000..1632869
--- /dev/null
+++ b/test-framework/providers/jetty/src/main/java11/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.test.jetty;
+
+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;
+
+public class JettyTestContainerFactory implements TestContainerFactory {
+
+ @Override
+ public TestContainer create(final URI baseUri, final DeploymentContext context) throws IllegalArgumentException {
+ throw new ProcessingException(LocalizationMessages.NOT_SUPPORTED());
+ }
+}
diff --git a/test-framework/providers/jetty/src/main/java/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java b/test-framework/providers/jetty/src/main/java17/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
similarity index 98%
rename from test-framework/providers/jetty/src/main/java/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
rename to test-framework/providers/jetty/src/main/java17/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
index 2ce4577..de1ba2c 100644
--- a/test-framework/providers/jetty/src/main/java/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
+++ b/test-framework/providers/jetty/src/main/java17/org/glassfish/jersey/test/jetty/JettyTestContainerFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/test-framework/providers/jetty/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties b/test-framework/providers/jetty/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
index c362bf0..6504f0e 100644
--- a/test-framework/providers/jetty/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
+++ b/test-framework/providers/jetty/src/main/resources/org/glassfish/jersey/jetty/internal/localization.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2020, 2023 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -15,4 +15,4 @@
#
# {0} - status code; {1} - status reason message
-not.supported=Jetty container is not supported on JDK version less than 11.
+not.supported=Jetty container is not supported on JDK version less than 17.
diff --git a/tests/e2e-client/pom.xml b/tests/e2e-client/pom.xml
index 90ddafe..7855c3a 100644
--- a/tests/e2e-client/pom.xml
+++ b/tests/e2e-client/pom.xml
@@ -222,6 +222,34 @@
<profiles>
<profile>
+ <id>JettyTestExclude</id>
+ <activation>
+ <jdk>[11,17)</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>xdk</id>
<properties>
<!-- do not use security manager for xdk -->
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 3d5fb1d..3bbc161 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java
@@ -63,15 +63,17 @@
private static final Logger LOGGER = Logger.getLogger(RequestHeaderModificationsTest.class.getName());
public static List<ConnectorProvider> testData() {
- int size = 7;
+ int size = JdkVersion.getJdkVersion().getMajor() < 17 ? 6 : 7;
final ConnectorProvider[] providers = new ConnectorProvider[size];
providers[0] = new JdkConnectorProvider();
providers[1] = new GrizzlyConnectorProvider();
- providers[2] = new JettyConnectorProvider();
- providers[3] = new ApacheConnectorProvider();
- providers[4] = new Apache5ConnectorProvider();
- providers[5] = new NettyConnectorProvider();
- providers[6] = new JavaNetHttpConnectorProvider();
+ providers[2] = new ApacheConnectorProvider();
+ providers[3] = new Apache5ConnectorProvider();
+ providers[4] = new NettyConnectorProvider();
+ providers[5] = new JavaNetHttpConnectorProvider();
+ if (size == 7) {
+ providers[6] = new JettyConnectorProvider();
+ }
return Arrays.asList(providers);
}
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java
index 697165f..e9ec309 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
@@ -58,6 +58,7 @@
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;
@@ -121,6 +122,10 @@
public Collection<DynamicContainer> generateTests() {
Collection<DynamicContainer> tests = new ArrayList<>();
testData().forEach(arr -> {
+ if (JdkVersion.getJdkVersion().getMajor() < 17
+ && 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/proxy/ProxySelectorTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxySelectorTest.java
index 8c3bdc4..3bfc47a 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxySelectorTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxySelectorTest.java
@@ -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.
* Copyright (c) 2019 Banco do Brasil S/A. All rights reserved.
*
* This program and the accompanying materials are made available under the
@@ -17,10 +17,11 @@
package org.glassfish.jersey.tests.e2e.client.connector.proxy;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.netty.connector.NettyConnectorProvider;
import org.junit.jupiter.api.AfterAll;
@@ -29,8 +30,6 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
@@ -112,21 +111,20 @@
return client().target("http://eclipse.org:9998").path(path);
}
- static class ProxyHandler extends AbstractHandler {
+ static class ProxyHandler extends Handler.Abstract {
Set<HttpChannel> httpConnect = new HashSet<>();
+
@Override
- public void handle(String target,
- Request baseRequest,
- HttpServletRequest request,
- HttpServletResponse response) {
- if (request.getHeader(NO_PASS) != null) {
- response.setStatus(Integer.parseInt(request.getHeader(NO_PASS)));
+ public boolean handle(Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception {
+ if (request.getHeaders().get(NO_PASS) != null) {
+ response.setStatus(Integer.parseInt(request.getHeaders().get(NO_PASS)));
} else {
response.setStatus(407);
- response.addHeader("Proxy-Authenticate", "Basic");
+ response.getHeaders().add("Proxy-Authenticate", "Basic");
}
- baseRequest.setHandled(true);
+ callback.succeeded();
+ return true;
}
}
}
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java
index efaf2ce..65693b5 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java
@@ -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.
* Copyright (c) 2019 Banco do Brasil S/A. All rights reserved.
*
* This program and the accompanying materials are made available under the
@@ -17,10 +17,12 @@
package org.glassfish.jersey.tests.e2e.client.connector.proxy;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.internal.HttpChannelState;
+import org.eclipse.jetty.util.Callback;
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
@@ -38,8 +40,6 @@
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
@@ -202,17 +202,14 @@
}
}
- static class ProxyHandler extends AbstractHandler {
+ static class ProxyHandler extends Handler.Abstract {
Set<HttpChannel> httpConnect = new HashSet<>();
@Override
- public void handle(String target,
- Request baseRequest,
- HttpServletRequest request,
- HttpServletResponse response) {
- if (request.getHeader(NO_PASS) != null) {
- response.setStatus(Integer.parseInt(request.getHeader(NO_PASS)));
- } else if (request.getHeader("Proxy-Authorization") != null) {
- String proxyAuthorization = request.getHeader("Proxy-Authorization");
+ public boolean handle(Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception {
+ if (request.getHeaders().get(NO_PASS) != null) {
+ response.setStatus(Integer.parseInt(request.getHeaders().get(NO_PASS)));
+ } else if (request.getHeaders().get("Proxy-Authorization") != null) {
+ String proxyAuthorization = request.getHeaders().get("Proxy-Authorization");
String decoded = new String(Base64.getDecoder().decode(proxyAuthorization.substring(6).getBytes()),
CHARACTER_SET);
final String[] split = decoded.split(":");
@@ -231,21 +228,36 @@
if (response.getStatus() != 400) {
response.setStatus(200);
- if ("CONNECT".equalsIgnoreCase(baseRequest.getMethod())) { // NETTY way of doing proxy
- httpConnect.add(baseRequest.getHttpChannel());
+ if ("CONNECT".equalsIgnoreCase(request.getMethod())) { // NETTY way of doing proxy
+ if (!(request.getComponents() instanceof HttpChannelState)) {
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ callback.failed(new IllegalStateException(
+ "Expecting request.getComponents() to be an instance of HttpChannelState"));
+ return true;
+ }
+ HttpChannel httpChannel = (HttpChannel) request.getComponents();
+ httpConnect.add(httpChannel);
}
}
//TODO Add redirect to requestURI
} else {
- if (httpConnect.contains(baseRequest.getHttpChannel())) {
+ if (!(request.getComponents() instanceof HttpChannelState)) {
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ callback.failed(new IllegalStateException(
+ "Expecting request.getComponents() to be an instance of HttpChannelState"));
+ return true;
+ }
+ HttpChannel httpChannel = (HttpChannel) request.getComponents();
+ if (httpConnect.contains(httpChannel)) {
response.setStatus(200);
} else {
response.setStatus(407);
- response.addHeader("Proxy-Authenticate", "Basic");
+ response.getHeaders().add("Proxy-Authenticate", "Basic");
}
}
- baseRequest.setHandled(true);
+ callback.succeeded();
+ return true;
}
}
}
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
index 6d9b144..690faa4 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
@@ -55,14 +55,16 @@
* @return test parameters.
*/
public static Stream<ConnectorProvider> testData() {
- int size = 6;
+ int size = JdkVersion.getJdkVersion().getMajor() < 17 ? 5 : 6;
final ConnectorProvider[] providers = new ConnectorProvider[size];
providers[0] = new HttpUrlConnectorProvider();
providers[1] = new GrizzlyConnectorProvider();
- providers[2] = new JettyConnectorProvider();
- providers[3] = new ApacheConnectorProvider();
- providers[4] = new Apache5ConnectorProvider();
- providers[5] = new JavaNetHttpConnectorProvider();
+ providers[2] = new ApacheConnectorProvider();
+ providers[3] = new Apache5ConnectorProvider();
+ providers[4] = new JavaNetHttpConnectorProvider();
+ if (size == 6) {
+ providers[5] = new JettyConnectorProvider();
+ }
return Stream.of(providers);
}
diff --git a/tests/e2e/pom.xml b/tests/e2e/pom.xml
index 834484f..2871c03 100644
--- a/tests/e2e/pom.xml
+++ b/tests/e2e/pom.xml
@@ -198,6 +198,26 @@
</properties>
</profile>
<profile>
+ <id>JettyExclude</id>
+ <activation>
+ <jdk>[11,17)</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/e2e/container/Jersey2462Test.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/Jersey2462Test.java
index f67d538..54bbf12 100644
--- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/Jersey2462Test.java
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/Jersey2462Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -174,13 +174,13 @@
// let's also test some method calls
int flags = 0;
- if ("/echo".equals(jettyRequest.get().getPathInfo())) {
+ if ("/echo".equals(jettyRequest.get().getHttpURI().getPath())) {
flags += 1;
}
if (!jettyResponse.get().isCommitted()) {
flags += 10;
}
- final String header = jettyRequest.get().getHeader(REQUEST_NUMBER);
+ final String header = jettyRequest.get().getHeaders().get(REQUEST_NUMBER);
ctx.setEntityStream(new ByteArrayInputStream(("filtered-" + flags + "-" + header).getBytes()));
}
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java
index b1f5cfc..f6bb0b7 100644
--- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/JerseyContainerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -54,10 +54,10 @@
protected static List<TestContainerFactory> listContainerFactories(TestContainerFactory... factories) {
final JdkVersion version = JdkVersion.getJdkVersion();
- boolean isJDK8 = version.getMajor() == 1;
+ boolean isJDKGreaterThanOrEqualTo17 = version.getMajor() >= 17;
final List<TestContainerFactory> filtered = new LinkedList<>();
for (TestContainerFactory factory : factories) {
- if (!isJDK8 || !JettyTestContainerFactory.class.isInstance(factory)) {
+ if (isJDKGreaterThanOrEqualTo17 || !JettyTestContainerFactory.class.isInstance(factory)) {
filtered.add(factory);
}
}
diff --git a/tests/integration/async-jersey-filter/pom.xml b/tests/integration/async-jersey-filter/pom.xml
index c257162..50db49d 100644
--- a/tests/integration/async-jersey-filter/pom.xml
+++ b/tests/integration/async-jersey-filter/pom.xml
@@ -64,8 +64,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/externalproperties/src/test/java/org/glassfish/jersey/tests/externalproperties/HttpProxyTest.java b/tests/integration/externalproperties/src/test/java/org/glassfish/jersey/tests/externalproperties/HttpProxyTest.java
index c6ecc29..84edb0f 100644
--- a/tests/integration/externalproperties/src/test/java/org/glassfish/jersey/tests/externalproperties/HttpProxyTest.java
+++ b/tests/integration/externalproperties/src/test/java/org/glassfish/jersey/tests/externalproperties/HttpProxyTest.java
@@ -16,9 +16,10 @@
package org.glassfish.jersey.tests.externalproperties;
+import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.Callback;
import org.glassfish.jersey.ExternalProperties;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
@@ -30,8 +31,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Application;
@@ -99,15 +98,13 @@
Assertions.assertFalse(proxyHit);
}
- class ProxyHandler extends AbstractHandler {
+ class ProxyHandler extends Handler.Abstract {
@Override
- public void handle(String target,
- Request baseRequest,
- HttpServletRequest request,
- HttpServletResponse response) {
+ public boolean handle(Request request, org.eclipse.jetty.server.Response response, Callback callback) throws Exception {
proxyHit = true;
response.setStatus(407);
- baseRequest.setHandled(true);
+ callback.succeeded();
+ return true;
}
ProxyHandler(boolean pProxyHit) {
@@ -117,4 +114,3 @@
}
}
-
diff --git a/tests/integration/jaxrs-component-inject/pom.xml b/tests/integration/jaxrs-component-inject/pom.xml
index a4861bd..8dae71d 100644
--- a/tests/integration/jaxrs-component-inject/pom.xml
+++ b/tests/integration/jaxrs-component-inject/pom.xml
@@ -54,8 +54,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-1107/pom.xml b/tests/integration/jersey-1107/pom.xml
index 4d6cb66..092d754 100644
--- a/tests/integration/jersey-1107/pom.xml
+++ b/tests/integration/jersey-1107/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-1223/pom.xml b/tests/integration/jersey-1223/pom.xml
index 5d02d7a..7366006 100644
--- a/tests/integration/jersey-1223/pom.xml
+++ b/tests/integration/jersey-1223/pom.xml
@@ -58,8 +58,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-1604/pom.xml b/tests/integration/jersey-1604/pom.xml
index 91fa17d..a2fd82f 100644
--- a/tests/integration/jersey-1604/pom.xml
+++ b/tests/integration/jersey-1604/pom.xml
@@ -61,8 +61,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-1667/pom.xml b/tests/integration/jersey-1667/pom.xml
index 67a5ea3..4aba42f 100644
--- a/tests/integration/jersey-1667/pom.xml
+++ b/tests/integration/jersey-1667/pom.xml
@@ -60,8 +60,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-1883/pom.xml b/tests/integration/jersey-1883/pom.xml
index 892e1a6..74eaca9 100644
--- a/tests/integration/jersey-1883/pom.xml
+++ b/tests/integration/jersey-1883/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-1928/pom.xml b/tests/integration/jersey-1928/pom.xml
index f855c70..a686f5b 100644
--- a/tests/integration/jersey-1928/pom.xml
+++ b/tests/integration/jersey-1928/pom.xml
@@ -57,8 +57,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-1960/pom.xml b/tests/integration/jersey-1960/pom.xml
index e8898f3..da35a12 100644
--- a/tests/integration/jersey-1960/pom.xml
+++ b/tests/integration/jersey-1960/pom.xml
@@ -62,8 +62,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-1964/pom.xml b/tests/integration/jersey-1964/pom.xml
index fbb9c24..bdb930f 100644
--- a/tests/integration/jersey-1964/pom.xml
+++ b/tests/integration/jersey-1964/pom.xml
@@ -69,8 +69,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2031/pom.xml b/tests/integration/jersey-2031/pom.xml
index f075558..4f953ee 100644
--- a/tests/integration/jersey-2031/pom.xml
+++ b/tests/integration/jersey-2031/pom.xml
@@ -66,8 +66,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee9</groupId>
+ <artifactId>jetty-ee9-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
diff --git a/tests/integration/jersey-2160/pom.xml b/tests/integration/jersey-2160/pom.xml
index 8a76b08..a698d69 100644
--- a/tests/integration/jersey-2160/pom.xml
+++ b/tests/integration/jersey-2160/pom.xml
@@ -62,8 +62,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2164/pom.xml b/tests/integration/jersey-2164/pom.xml
index 7f7380f..344de9b 100644
--- a/tests/integration/jersey-2164/pom.xml
+++ b/tests/integration/jersey-2164/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2167/pom.xml b/tests/integration/jersey-2167/pom.xml
index 7d93a9e..4693ff7 100644
--- a/tests/integration/jersey-2167/pom.xml
+++ b/tests/integration/jersey-2167/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2176/pom.xml b/tests/integration/jersey-2176/pom.xml
index 53e5a76..2b1f799 100644
--- a/tests/integration/jersey-2176/pom.xml
+++ b/tests/integration/jersey-2176/pom.xml
@@ -62,8 +62,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee9</groupId>
+ <artifactId>jetty-ee9-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2184/pom.xml b/tests/integration/jersey-2184/pom.xml
index a8dbc2d..0431ff2 100644
--- a/tests/integration/jersey-2184/pom.xml
+++ b/tests/integration/jersey-2184/pom.xml
@@ -63,8 +63,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2255/pom.xml b/tests/integration/jersey-2255/pom.xml
index 81c8435..4944f35 100644
--- a/tests/integration/jersey-2255/pom.xml
+++ b/tests/integration/jersey-2255/pom.xml
@@ -64,8 +64,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2322/pom.xml b/tests/integration/jersey-2322/pom.xml
index 59460b1..fe74066 100644
--- a/tests/integration/jersey-2322/pom.xml
+++ b/tests/integration/jersey-2322/pom.xml
@@ -64,8 +64,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2335/pom.xml b/tests/integration/jersey-2335/pom.xml
index 25d3646..e584ec5 100644
--- a/tests/integration/jersey-2335/pom.xml
+++ b/tests/integration/jersey-2335/pom.xml
@@ -60,8 +60,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2551/pom.xml b/tests/integration/jersey-2551/pom.xml
index e3b182e..e88d21c 100644
--- a/tests/integration/jersey-2551/pom.xml
+++ b/tests/integration/jersey-2551/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2612/pom.xml b/tests/integration/jersey-2612/pom.xml
index c637e87..ca46c5b 100644
--- a/tests/integration/jersey-2612/pom.xml
+++ b/tests/integration/jersey-2612/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2637/pom.xml b/tests/integration/jersey-2637/pom.xml
index 692a268..b873eb8 100644
--- a/tests/integration/jersey-2637/pom.xml
+++ b/tests/integration/jersey-2637/pom.xml
@@ -63,8 +63,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2654/pom.xml b/tests/integration/jersey-2654/pom.xml
index 6586fc3..6933ca0 100644
--- a/tests/integration/jersey-2654/pom.xml
+++ b/tests/integration/jersey-2654/pom.xml
@@ -55,8 +55,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2673/pom.xml b/tests/integration/jersey-2673/pom.xml
index 8563e75..403a67a 100644
--- a/tests/integration/jersey-2673/pom.xml
+++ b/tests/integration/jersey-2673/pom.xml
@@ -74,8 +74,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2689/pom.xml b/tests/integration/jersey-2689/pom.xml
index 56e5822..b2288a8 100644
--- a/tests/integration/jersey-2689/pom.xml
+++ b/tests/integration/jersey-2689/pom.xml
@@ -96,8 +96,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2704/pom.xml b/tests/integration/jersey-2704/pom.xml
index a3b3123..a6aae38 100644
--- a/tests/integration/jersey-2704/pom.xml
+++ b/tests/integration/jersey-2704/pom.xml
@@ -63,8 +63,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2794/pom.xml b/tests/integration/jersey-2794/pom.xml
index 579495c..99610e2 100644
--- a/tests/integration/jersey-2794/pom.xml
+++ b/tests/integration/jersey-2794/pom.xml
@@ -63,8 +63,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2846/pom.xml b/tests/integration/jersey-2846/pom.xml
index f682da1..ce24404 100644
--- a/tests/integration/jersey-2846/pom.xml
+++ b/tests/integration/jersey-2846/pom.xml
@@ -63,8 +63,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2878/pom.xml b/tests/integration/jersey-2878/pom.xml
index 3c5fb91..38fe5fe 100644
--- a/tests/integration/jersey-2878/pom.xml
+++ b/tests/integration/jersey-2878/pom.xml
@@ -64,8 +64,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-2892/pom.xml b/tests/integration/jersey-2892/pom.xml
index 40d31c8..c053453 100644
--- a/tests/integration/jersey-2892/pom.xml
+++ b/tests/integration/jersey-2892/pom.xml
@@ -70,8 +70,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-3796/pom.xml b/tests/integration/jersey-3796/pom.xml
index b66d29b..85b8089 100644
--- a/tests/integration/jersey-3796/pom.xml
+++ b/tests/integration/jersey-3796/pom.xml
@@ -75,8 +75,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/jersey-4949/pom.xml b/tests/integration/jersey-4949/pom.xml
index 3505996..9c43419 100644
--- a/tests/integration/jersey-4949/pom.xml
+++ b/tests/integration/jersey-4949/pom.xml
@@ -60,8 +60,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
<configuration>
<scan>10</scan>
<webApp>
diff --git a/tests/integration/jersey-780/pom.xml b/tests/integration/jersey-780/pom.xml
index 6014048..39b8f7e 100644
--- a/tests/integration/jersey-780/pom.xml
+++ b/tests/integration/jersey-780/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/microprofile/rest-client-tck/pom.xml b/tests/integration/microprofile/rest-client-tck/pom.xml
index 0eff387..aa7c7ca 100644
--- a/tests/integration/microprofile/rest-client-tck/pom.xml
+++ b/tests/integration/microprofile/rest-client-tck/pom.xml
@@ -190,7 +190,7 @@
<name>skipTests</name>
<value>!true</value>
</property>
- <jdk>[11,)</jdk>
+ <jdk>[17,)</jdk>
</activation>
<build>
<plugins>
diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml
index 3f2a60b..f1b8753 100644
--- a/tests/integration/pom.xml
+++ b/tests/integration/pom.xml
@@ -34,55 +34,22 @@
<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>
@@ -91,54 +58,16 @@
<module>jersey-4542</module>
<module>jersey-4697</module>
<module>jersey-4722</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>
@@ -191,12 +120,83 @@
</build>
</profile>
<profile>
- <id>spring6-jdk17</id>
+ <id>jdk17</id>
<activation>
<jdk>[17,)</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-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>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-3-async</module>
+ <module>servlet-3-chunked-io</module>
+ <module>servlet-3-filter</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-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>spring6</module>
+ <module>tracing-support</module>
</modules>
</profile>
</profiles>
@@ -246,8 +246,8 @@
</executions>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee9</groupId>
+ <artifactId>jetty-ee9-maven-plugin</artifactId>
<version>${jetty.plugin.version}</version>
<configuration>
<skip>${skip.tests}</skip>
@@ -270,9 +270,45 @@
<goals>
<goal>start</goal>
</goals>
- <configuration>
- <scanIntervalSeconds>0</scanIntervalSeconds>
- </configuration>
+ </execution>
+ <execution>
+ <id>stop-jetty</id>
+ <phase>post-integration-test</phase>
+ <goals>
+ <goal>stop</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
+ <version>${jetty.plugin.version}</version>
+ <configuration>
+ <skip>${skip.tests}</skip>
+ <stopPort>9999</stopPort>
+ <stopKey>STOP</stopKey>
+ <stopWait>10</stopWait>
+ <webApp>
+ <contextPath>/</contextPath>
+ <webInfIncludeJarPattern>.*/.*jersey-[^/]\.jar$</webInfIncludeJarPattern>
+ </webApp>
+ <httpConnector>
+ <port>${jersey.config.test.container.port}</port>
+ <idleTimeout>60000</idleTimeout>
+ </httpConnector>
+ <systemProperties>
+ <PORT>${jersey.config.test.container.port}</PORT>
+ <IDLE_TIMEOUT>60000</IDLE_TIMEOUT>
+ </systemProperties>
+ </configuration>
+ <executions>
+ <execution>
+ <id>start-jetty</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>start</goal>
+ </goals>
</execution>
<execution>
<id>stop-jetty</id>
diff --git a/tests/integration/security-digest/pom.xml b/tests/integration/security-digest/pom.xml
index b33f41b..0de0655 100644
--- a/tests/integration/security-digest/pom.xml
+++ b/tests/integration/security-digest/pom.xml
@@ -58,15 +58,20 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
<configuration>
+ <webApp>
+ <parentLoaderPriority>true</parentLoaderPriority>
+ </webApp>
<!-- define login service for jetty and the realm to be used -->
<loginServices>
<loginService implementation="org.eclipse.jetty.security.HashLoginService">
<name>my-realm</name>
- <config>${basedir}/src/main/resources/jetty/realm.properties</config>
+ <config implementation="org.eclipse.jetty.ee10.maven.plugin.MavenResource">
+ <resourceAsString>${basedir}/src/main/resources/jetty/realm.properties</resourceAsString>
+ </config>
</loginService>
</loginServices>
</configuration>
diff --git a/tests/integration/servlet-2.5-autodiscovery-1/pom.xml b/tests/integration/servlet-2.5-autodiscovery-1/pom.xml
index 032ca7a..98c1fff 100644
--- a/tests/integration/servlet-2.5-autodiscovery-1/pom.xml
+++ b/tests/integration/servlet-2.5-autodiscovery-1/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-autodiscovery-2/pom.xml b/tests/integration/servlet-2.5-autodiscovery-2/pom.xml
index db70dcd..ebfda2d 100644
--- a/tests/integration/servlet-2.5-autodiscovery-2/pom.xml
+++ b/tests/integration/servlet-2.5-autodiscovery-2/pom.xml
@@ -67,8 +67,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-filter/pom.xml b/tests/integration/servlet-2.5-filter/pom.xml
index 911927b..0f16723 100644
--- a/tests/integration/servlet-2.5-filter/pom.xml
+++ b/tests/integration/servlet-2.5-filter/pom.xml
@@ -60,8 +60,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-inflector-1/pom.xml b/tests/integration/servlet-2.5-inflector-1/pom.xml
index 98ff984..ed1c161 100644
--- a/tests/integration/servlet-2.5-inflector-1/pom.xml
+++ b/tests/integration/servlet-2.5-inflector-1/pom.xml
@@ -64,8 +64,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-init-1/pom.xml b/tests/integration/servlet-2.5-init-1/pom.xml
index 83adf6a..72fcdde 100644
--- a/tests/integration/servlet-2.5-init-1/pom.xml
+++ b/tests/integration/servlet-2.5-init-1/pom.xml
@@ -62,8 +62,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-init-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_init_1/Servlet25Init1ITCase.java b/tests/integration/servlet-2.5-init-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_init_1/Servlet25Init1ITCase.java
index c44f34a..d3c0e0e 100644
--- a/tests/integration/servlet-2.5-init-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_init_1/Servlet25Init1ITCase.java
+++ b/tests/integration/servlet-2.5-init-1/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_init_1/Servlet25Init1ITCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -87,7 +87,7 @@
@Test
public void testInjection() {
String s = target().path("servlet_path/helloworld/injection").request().get(String.class);
- assertEquals("GETtruetestServlet1testServlet1/", s);
+ assertEquals("GETtruetestServlet1testServlet1ROOT", s);
}
// Reproducer for JERSEY-1801
diff --git a/tests/integration/servlet-2.5-init-2/pom.xml b/tests/integration/servlet-2.5-init-2/pom.xml
index fe1bff8..813ba49 100644
--- a/tests/integration/servlet-2.5-init-2/pom.xml
+++ b/tests/integration/servlet-2.5-init-2/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-init-3/pom.xml b/tests/integration/servlet-2.5-init-3/pom.xml
index 3623e99..cad9526 100644
--- a/tests/integration/servlet-2.5-init-3/pom.xml
+++ b/tests/integration/servlet-2.5-init-3/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-init-4/pom.xml b/tests/integration/servlet-2.5-init-4/pom.xml
index 16dbc42..fdc1410 100644
--- a/tests/integration/servlet-2.5-init-4/pom.xml
+++ b/tests/integration/servlet-2.5-init-4/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-init-5/pom.xml b/tests/integration/servlet-2.5-init-5/pom.xml
index f9d9dcd..35b5618 100644
--- a/tests/integration/servlet-2.5-init-5/pom.xml
+++ b/tests/integration/servlet-2.5-init-5/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-init-6/pom.xml b/tests/integration/servlet-2.5-init-6/pom.xml
index 44af411..0870ccb 100644
--- a/tests/integration/servlet-2.5-init-6/pom.xml
+++ b/tests/integration/servlet-2.5-init-6/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-init-7/pom.xml b/tests/integration/servlet-2.5-init-7/pom.xml
index dff3108..bfeb54d 100644
--- a/tests/integration/servlet-2.5-init-7/pom.xml
+++ b/tests/integration/servlet-2.5-init-7/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-init-8/pom.xml b/tests/integration/servlet-2.5-init-8/pom.xml
index 7c9ded4..f7dc189 100644
--- a/tests/integration/servlet-2.5-init-8/pom.xml
+++ b/tests/integration/servlet-2.5-init-8/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-mvc-1/pom.xml b/tests/integration/servlet-2.5-mvc-1/pom.xml
index ecdae06..0009436 100644
--- a/tests/integration/servlet-2.5-mvc-1/pom.xml
+++ b/tests/integration/servlet-2.5-mvc-1/pom.xml
@@ -77,8 +77,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee9</groupId>
+ <artifactId>jetty-ee9-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
diff --git a/tests/integration/servlet-2.5-mvc-2/pom.xml b/tests/integration/servlet-2.5-mvc-2/pom.xml
index cff9992..fb26eaf 100644
--- a/tests/integration/servlet-2.5-mvc-2/pom.xml
+++ b/tests/integration/servlet-2.5-mvc-2/pom.xml
@@ -77,8 +77,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-mvc-3/pom.xml b/tests/integration/servlet-2.5-mvc-3/pom.xml
index 453a58c..57074de 100644
--- a/tests/integration/servlet-2.5-mvc-3/pom.xml
+++ b/tests/integration/servlet-2.5-mvc-3/pom.xml
@@ -77,8 +77,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee9</groupId>
+ <artifactId>jetty-ee9-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
diff --git a/tests/integration/servlet-3-async/pom.xml b/tests/integration/servlet-3-async/pom.xml
index bc52292..f27c3e2 100644
--- a/tests/integration/servlet-3-async/pom.xml
+++ b/tests/integration/servlet-3-async/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-chunked-io/pom.xml b/tests/integration/servlet-3-chunked-io/pom.xml
index de086d4..e16f934 100644
--- a/tests/integration/servlet-3-chunked-io/pom.xml
+++ b/tests/integration/servlet-3-chunked-io/pom.xml
@@ -65,8 +65,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-filter/pom.xml b/tests/integration/servlet-3-filter/pom.xml
index 2778521..410dff6 100644
--- a/tests/integration/servlet-3-filter/pom.xml
+++ b/tests/integration/servlet-3-filter/pom.xml
@@ -61,8 +61,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-inflector-1/pom.xml b/tests/integration/servlet-3-inflector-1/pom.xml
index 3eaca79..88f8b3e 100644
--- a/tests/integration/servlet-3-inflector-1/pom.xml
+++ b/tests/integration/servlet-3-inflector-1/pom.xml
@@ -64,8 +64,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-1/pom.xml b/tests/integration/servlet-3-init-1/pom.xml
index 286d63f..d9cf871 100644
--- a/tests/integration/servlet-3-init-1/pom.xml
+++ b/tests/integration/servlet-3-init-1/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-2/pom.xml b/tests/integration/servlet-3-init-2/pom.xml
index 025afca..26bbbea 100644
--- a/tests/integration/servlet-3-init-2/pom.xml
+++ b/tests/integration/servlet-3-init-2/pom.xml
@@ -64,8 +64,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-3/pom.xml b/tests/integration/servlet-3-init-3/pom.xml
index 15d3802..4344768 100644
--- a/tests/integration/servlet-3-init-3/pom.xml
+++ b/tests/integration/servlet-3-init-3/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-4/pom.xml b/tests/integration/servlet-3-init-4/pom.xml
index ed282aa..6c836c3 100644
--- a/tests/integration/servlet-3-init-4/pom.xml
+++ b/tests/integration/servlet-3-init-4/pom.xml
@@ -59,8 +59,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-5/pom.xml b/tests/integration/servlet-3-init-5/pom.xml
index 5404797..5cd699b 100644
--- a/tests/integration/servlet-3-init-5/pom.xml
+++ b/tests/integration/servlet-3-init-5/pom.xml
@@ -56,8 +56,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-6/pom.xml b/tests/integration/servlet-3-init-6/pom.xml
index e67e339..0399614 100644
--- a/tests/integration/servlet-3-init-6/pom.xml
+++ b/tests/integration/servlet-3-init-6/pom.xml
@@ -57,8 +57,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-7/pom.xml b/tests/integration/servlet-3-init-7/pom.xml
index 58cf49e..ba2db59 100644
--- a/tests/integration/servlet-3-init-7/pom.xml
+++ b/tests/integration/servlet-3-init-7/pom.xml
@@ -58,8 +58,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-8/pom.xml b/tests/integration/servlet-3-init-8/pom.xml
index a7127d4..b6ac348 100644
--- a/tests/integration/servlet-3-init-8/pom.xml
+++ b/tests/integration/servlet-3-init-8/pom.xml
@@ -58,8 +58,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-9/pom.xml b/tests/integration/servlet-3-init-9/pom.xml
index 4f9341b..aaba59f 100644
--- a/tests/integration/servlet-3-init-9/pom.xml
+++ b/tests/integration/servlet-3-init-9/pom.xml
@@ -63,8 +63,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-init-provider/pom.xml b/tests/integration/servlet-3-init-provider/pom.xml
index 723b03b..0aeedc3 100644
--- a/tests/integration/servlet-3-init-provider/pom.xml
+++ b/tests/integration/servlet-3-init-provider/pom.xml
@@ -67,8 +67,8 @@
</configuration>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-3-params/pom.xml b/tests/integration/servlet-3-params/pom.xml
index e820f67..a1d5315 100644
--- a/tests/integration/servlet-3-params/pom.xml
+++ b/tests/integration/servlet-3-params/pom.xml
@@ -61,8 +61,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-4.0-mvc-1/pom.xml b/tests/integration/servlet-4.0-mvc-1/pom.xml
index c995f1d..3bc56bc 100644
--- a/tests/integration/servlet-4.0-mvc-1/pom.xml
+++ b/tests/integration/servlet-4.0-mvc-1/pom.xml
@@ -82,8 +82,8 @@
</configuration>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
diff --git a/tests/integration/servlet-request-wrapper-binding-2/pom.xml b/tests/integration/servlet-request-wrapper-binding-2/pom.xml
index d1c38f3..245cc82 100644
--- a/tests/integration/servlet-request-wrapper-binding-2/pom.xml
+++ b/tests/integration/servlet-request-wrapper-binding-2/pom.xml
@@ -68,8 +68,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-request-wrapper-binding/pom.xml b/tests/integration/servlet-request-wrapper-binding/pom.xml
index 873c076..7c22226 100644
--- a/tests/integration/servlet-request-wrapper-binding/pom.xml
+++ b/tests/integration/servlet-request-wrapper-binding/pom.xml
@@ -67,8 +67,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/servlet-tests/pom.xml b/tests/integration/servlet-tests/pom.xml
index 5dc5479..6a002e0 100644
--- a/tests/integration/servlet-tests/pom.xml
+++ b/tests/integration/servlet-tests/pom.xml
@@ -62,8 +62,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/sonar-test/pom.xml b/tests/integration/sonar-test/pom.xml
index cf34796..bb68319 100644
--- a/tests/integration/sonar-test/pom.xml
+++ b/tests/integration/sonar-test/pom.xml
@@ -58,8 +58,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
diff --git a/tests/integration/spring6/pom.xml b/tests/integration/spring6/pom.xml
index ec6c690..9c005c2 100644
--- a/tests/integration/spring6/pom.xml
+++ b/tests/integration/spring6/pom.xml
@@ -133,9 +133,8 @@
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
- <version>11.0.14</version>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
<configuration>
<webApp>
<contextPath>/</contextPath>
diff --git a/tests/integration/tracing-support/pom.xml b/tests/integration/tracing-support/pom.xml
index 03d3045..1e1b03a 100644
--- a/tests/integration/tracing-support/pom.xml
+++ b/tests/integration/tracing-support/pom.xml
@@ -63,14 +63,16 @@
</configuration>
</plugin>
<plugin>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
+ <groupId>org.eclipse.jetty.ee10</groupId>
+ <artifactId>jetty-ee10-maven-plugin</artifactId>
<configuration>
- <connectors>
- <connector>
- <responseHeaderSize>16192</responseHeaderSize>
- </connector>
- </connectors>
+ <httpConnector combine.self="override"/>
+ <jettyXmls>
+ <jettyXml>${basedir}/src/test/resources/jetty.xml</jettyXml>
+ </jettyXmls>
+ <systemProperties>
+ <RESPONSE_HEADER_SIZE>16192</RESPONSE_HEADER_SIZE>
+ </systemProperties>
<!-- server side config does not fork with jetty:run goal - it uses same jvm
use maven '-D' option instead:
mvn _goal_ -Djava.util.logging.config.file=target/test-classes/logging.properties
diff --git a/tests/integration/tracing-support/src/test/resources/jetty.xml b/tests/integration/tracing-support/src/test/resources/jetty.xml
new file mode 100644
index 0000000..dc8582c
--- /dev/null
+++ b/tests/integration/tracing-support/src/test/resources/jetty.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+
+ Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
+
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
+ <New id="HttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
+ <Set name="responseHeaderSize"><SystemProperty name="RESPONSE_HEADER_SIZE"/></Set>
+ </New>
+
+ <Call name="addConnector">
+ <Arg>
+ <New class="org.eclipse.jetty.server.ServerConnector">
+ <Arg name="server"><Ref refid="Server" /></Arg>
+ <Arg name="factories">
+ <Array type="org.eclipse.jetty.server.ConnectionFactory">
+ <Item>
+ <New class="org.eclipse.jetty.server.HttpConnectionFactory">
+ <Arg name="config"><Ref refid="HttpConfig" /></Arg>
+ </New>
+ </Item>
+ </Array>
+ </Arg>
+ <Set name="port"><SystemProperty name="PORT"/></Set>
+ <Set name="idleTimeout"><SystemProperty name="IDLE_TIMEOUT"/></Set>
+ </New>
+ </Arg>
+ </Call>
+</Configure>
\ No newline at end of file
diff --git a/tests/pom.xml b/tests/pom.xml
index 6b35eba..1fc9c20 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -121,6 +121,14 @@
</activation>
<modules>
<module>release-test</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>JDK17+</id>
+ <activation>
+ <jdk>[17,)</jdk>
+ </activation>
+ <modules>
<module>version-agnostic</module>
</modules>
</profile>