Merge remote-tracking branch 'upstream/3.x' into 3.1
Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
diff --git a/bom/pom.xml b/bom/pom.xml
index 8584f51..c5393d2 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -290,6 +290,11 @@
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-gson</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/connectors/apache-connector/pom.xml b/connectors/apache-connector/pom.xml
index f366855..258ef18 100644
--- a/connectors/apache-connector/pom.xml
+++ b/connectors/apache-connector/pom.xml
@@ -40,6 +40,18 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>${commons.codec.version}</version>
+ <scope>test</scope>
</dependency>
<dependency>
diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
index 0b08871..fdfbccf 100644
--- a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
+++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
@@ -29,6 +29,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicLong;
@@ -51,6 +52,7 @@
import org.glassfish.jersey.client.ClientRequest;
import org.glassfish.jersey.client.ClientResponse;
import org.glassfish.jersey.client.RequestEntityProcessing;
+import org.glassfish.jersey.client.innate.ClientProxy;
import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
import org.glassfish.jersey.client.spi.Connector;
import org.glassfish.jersey.internal.util.PropertiesHelper;
@@ -279,28 +281,20 @@
clientBuilder.setRetryHandler((HttpRequestRetryHandler) retryHandler);
}
- final Object proxyUri;
- proxyUri = config.getProperty(ClientProperties.PROXY_URI);
- if (proxyUri != null) {
- final URI u = getProxyUri(proxyUri);
- final HttpHost proxy = new HttpHost(u.getHost(), u.getPort(), u.getScheme());
- final String userName;
- userName = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_USERNAME, String.class);
- if (userName != null) {
- final String password;
- password = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
-
- if (password != null) {
- final CredentialsProvider credsProvider = new BasicCredentialsProvider();
- credsProvider.setCredentials(
- new AuthScope(u.getHost(), u.getPort()),
- new UsernamePasswordCredentials(userName, password)
- );
- clientBuilder.setDefaultCredentialsProvider(credsProvider);
- }
+ final Optional<ClientProxy> proxy = ClientProxy.proxyFromConfiguration(config);
+ proxy.ifPresent(clientProxy -> {
+ final URI u = clientProxy.uri();
+ final HttpHost proxyHost = new HttpHost(u.getHost(), u.getPort(), u.getScheme());
+ if (clientProxy.userName() != null && clientProxy.password() != null) {
+ final CredentialsProvider credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(
+ new AuthScope(u.getHost(), u.getPort()),
+ new UsernamePasswordCredentials(clientProxy.userName(), clientProxy.password())
+ );
+ clientBuilder.setDefaultCredentialsProvider(credsProvider);
}
- clientBuilder.setProxy(proxy);
- }
+ clientBuilder.setProxy(proxyHost);
+ });
final Boolean preemptiveBasicAuthProperty = (Boolean) config.getProperties()
.get(ApacheClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION);
@@ -452,16 +446,6 @@
return cookieStore;
}
- private static URI getProxyUri(final Object proxy) {
- if (proxy instanceof URI) {
- return (URI) proxy;
- } else if (proxy instanceof String) {
- return URI.create((String) proxy);
- } else {
- throw new ProcessingException(LocalizationMessages.WRONG_PROXY_URI_TYPE(ClientProperties.PROXY_URI));
- }
- }
-
@Override
public ClientResponse apply(final ClientRequest clientRequest) throws ProcessingException {
final HttpUriRequest request = getUriHttpRequest(clientRequest);
diff --git a/connectors/apache-connector/src/main/resources/org/glassfish/jersey/apache/connector/localization.properties b/connectors/apache-connector/src/main/resources/org/glassfish/jersey/apache/connector/localization.properties
index f0cc55b..3b06461 100644
--- a/connectors/apache-connector/src/main/resources/org/glassfish/jersey/apache/connector/localization.properties
+++ b/connectors/apache-connector/src/main/resources/org/glassfish/jersey/apache/connector/localization.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,7 +19,5 @@
failed.to.stop.client=Failed to stop the client.
# {0} - property name, e.g. jersey.config.client.httpclient.connectionManager; {1}, {2} - full class name
ignoring.value.of.property=Ignoring value of property "{0}" ("{1}") - not instance of "{2}".
-# {0} - property name - jersey.config.client.httpclient.proxyUri
-wrong.proxy.uri.type=The proxy URI ("{0}") property MUST be an instance of String or URI.
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 ApacheConnectorProvider.
diff --git a/connectors/apache5-connector/pom.xml b/connectors/apache5-connector/pom.xml
index 6e24418..9d08082 100644
--- a/connectors/apache5-connector/pom.xml
+++ b/connectors/apache5-connector/pom.xml
@@ -40,9 +40,21 @@
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
+ <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.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<version>${project.version}</version>
diff --git a/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java
index 5cc2e63..9e4e9ac 100644
--- a/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java
+++ b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java
@@ -30,6 +30,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.logging.Level;
@@ -93,6 +94,7 @@
import org.glassfish.jersey.client.ClientRequest;
import org.glassfish.jersey.client.ClientResponse;
import org.glassfish.jersey.client.RequestEntityProcessing;
+import org.glassfish.jersey.client.innate.ClientProxy;
import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
import org.glassfish.jersey.client.spi.Connector;
import org.glassfish.jersey.internal.util.PropertiesHelper;
@@ -280,28 +282,20 @@
clientBuilder.setRetryStrategy((HttpRequestRetryStrategy) retryHandler);
}
- final Object proxyUri;
- proxyUri = config.getProperty(ClientProperties.PROXY_URI);
- if (proxyUri != null) {
- final URI u = getProxyUri(proxyUri);
- final HttpHost proxy = new HttpHost(u.getScheme(), u.getHost(), u.getPort());
- final String userName;
- userName = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_USERNAME, String.class);
- if (userName != null) {
- final String password;
- password = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
-
- if (password != null) {
- final CredentialsStore credsProvider = new BasicCredentialsProvider();
- credsProvider.setCredentials(
- new AuthScope(u.getHost(), u.getPort()),
- new UsernamePasswordCredentials(userName, password.toCharArray())
- );
- clientBuilder.setDefaultCredentialsProvider(credsProvider);
- }
+ final Optional<ClientProxy> proxy = ClientProxy.proxyFromConfiguration(config);
+ proxy.ifPresent(clientProxy -> {
+ final URI u = clientProxy.uri();
+ final HttpHost proxyHost = new HttpHost(u.getScheme(), u.getHost(), u.getPort());
+ if (clientProxy.userName() != null && clientProxy.password() != null) {
+ final CredentialsStore credsProvider = new BasicCredentialsProvider();
+ credsProvider.setCredentials(
+ new AuthScope(u.getHost(), u.getPort()),
+ new UsernamePasswordCredentials(clientProxy.userName(), clientProxy.password().toCharArray())
+ );
+ clientBuilder.setDefaultCredentialsProvider(credsProvider);
}
- clientBuilder.setProxy(proxy);
- }
+ clientBuilder.setProxy(proxyHost);
+ });
final Boolean preemptiveBasicAuthProperty = (Boolean) config.getProperties()
.get(Apache5ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION);
@@ -456,16 +450,6 @@
return cookieStore;
}
- private static URI getProxyUri(final Object proxy) {
- if (proxy instanceof URI) {
- return (URI) proxy;
- } else if (proxy instanceof String) {
- return URI.create((String) proxy);
- } else {
- throw new ProcessingException(LocalizationMessages.WRONG_PROXY_URI_TYPE(ClientProperties.PROXY_URI));
- }
- }
-
@Override
public ClientResponse apply(final ClientRequest clientRequest) throws ProcessingException {
final HttpUriRequest request = getUriHttpRequest(clientRequest);
diff --git a/connectors/apache5-connector/src/main/resources/org/glassfish/jersey/apache5/connector/localization.properties b/connectors/apache5-connector/src/main/resources/org/glassfish/jersey/apache5/connector/localization.properties
index 16dbc30..1f6e4a6 100644
--- a/connectors/apache5-connector/src/main/resources/org/glassfish/jersey/apache5/connector/localization.properties
+++ b/connectors/apache5-connector/src/main/resources/org/glassfish/jersey/apache5/connector/localization.properties
@@ -19,7 +19,5 @@
failed.to.stop.client=Failed to stop the client.
# {0} - property name, e.g. jersey.config.client.httpclient.connectionManager; {1}, {2} - full class name
ignoring.value.of.property=Ignoring value of property "{0}" ("{1}") - not instance of "{2}".
-# {0} - property name - jersey.config.client.httpclient.proxyUri
-wrong.proxy.uri.type=The proxy URI ("{0}") property MUST be an instance of String or URI.
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 ApacheConnectorProvider.
diff --git a/connectors/grizzly-connector/pom.xml b/connectors/grizzly-connector/pom.xml
index a9327a5..ba96bfd 100644
--- a/connectors/grizzly-connector/pom.xml
+++ b/connectors/grizzly-connector/pom.xml
@@ -49,9 +49,18 @@
<groupId>org.glassfish.grizzly</groupId>
<artifactId>connection-pool</artifactId>
</exclusion>
+ <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>
+ </dependency>
+ <dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>grizzly-websockets</artifactId>
</dependency>
diff --git a/connectors/grizzly-connector/src/main/java/org/glassfish/jersey/grizzly/connector/GrizzlyConnector.java b/connectors/grizzly-connector/src/main/java/org/glassfish/jersey/grizzly/connector/GrizzlyConnector.java
index c1ff43d..f39e216 100644
--- a/connectors/grizzly-connector/src/main/java/org/glassfish/jersey/grizzly/connector/GrizzlyConnector.java
+++ b/connectors/grizzly-connector/src/main/java/org/glassfish/jersey/grizzly/connector/GrizzlyConnector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,6 +22,7 @@
import java.net.URI;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -39,6 +40,7 @@
import org.glassfish.jersey.client.ClientRequest;
import org.glassfish.jersey.client.ClientResponse;
import org.glassfish.jersey.client.RequestEntityProcessing;
+import org.glassfish.jersey.client.innate.ClientProxy;
import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
import org.glassfish.jersey.client.spi.Connector;
import org.glassfish.jersey.internal.Version;
@@ -83,7 +85,7 @@
GrizzlyConnector(final Client client,
final Configuration config,
final GrizzlyConnectorProvider.AsyncClientCustomizer asyncClientCustomizer) {
- AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
+ final AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
ExecutorService executorService;
if (config != null) {
@@ -95,7 +97,7 @@
executorService = Executors.newCachedThreadPool();
}
- builder = builder.setExecutorService(executorService);
+ builder.setExecutorService(executorService);
builder.setConnectTimeout(ClientProperties.getValue(config.getProperties(),
ClientProperties.CONNECT_TIMEOUT, 10000));
@@ -103,29 +105,23 @@
builder.setRequestTimeout(ClientProperties.getValue(config.getProperties(),
ClientProperties.READ_TIMEOUT, 10000));
- Object proxyUri;
- proxyUri = config.getProperty(ClientProperties.PROXY_URI);
- if (proxyUri != null) {
- final URI u = getProxyUri(proxyUri);
+ final Optional<ClientProxy> proxy = ClientProxy.proxyFromConfiguration(config);
+ proxy.ifPresent(clientProxy -> {
+ final URI u = clientProxy.uri();
final Properties proxyProperties = new Properties();
proxyProperties.setProperty(ProxyUtils.PROXY_PROTOCOL, u.getScheme());
proxyProperties.setProperty(ProxyUtils.PROXY_HOST, u.getHost());
proxyProperties.setProperty(ProxyUtils.PROXY_PORT, String.valueOf(u.getPort()));
- final String userName = ClientProperties.getValue(
- config.getProperties(), ClientProperties.PROXY_USERNAME, String.class);
- if (userName != null) {
- proxyProperties.setProperty(ProxyUtils.PROXY_USER, userName);
-
- final String password = ClientProperties.getValue(
- config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
- if (password != null) {
- proxyProperties.setProperty(ProxyUtils.PROXY_PASSWORD, password);
+ if (clientProxy.userName() != null) {
+ proxyProperties.setProperty(ProxyUtils.PROXY_USER, clientProxy.userName());
+ if (clientProxy.password() != null) {
+ proxyProperties.setProperty(ProxyUtils.PROXY_PASSWORD, clientProxy.password());
}
}
ProxyServerSelector proxyServerSelector = ProxyUtils.createProxyServerSelector(proxyProperties);
builder.setProxyServerSelector(proxyServerSelector);
- }
+ });
} else {
executorService = Executors.newCachedThreadPool();
builder.setExecutorService(executorService);
@@ -140,7 +136,7 @@
}
if (asyncClientCustomizer != null) {
- builder = asyncClientCustomizer.customize(client, config, builder);
+ asyncClientCustomizer.customize(client, config, builder);
}
AsyncHttpClientConfig asyncClientConfig = builder.build();
@@ -148,17 +144,6 @@
this.grizzlyClient = new AsyncHttpClient(new GrizzlyAsyncHttpProvider(asyncClientConfig), asyncClientConfig);
}
- @SuppressWarnings("ChainOfInstanceofChecks")
- private static URI getProxyUri(final Object proxy) {
- if (proxy instanceof URI) {
- return (URI) proxy;
- } else if (proxy instanceof String) {
- return URI.create((String) proxy);
- } else {
- throw new ProcessingException(LocalizationMessages.WRONG_PROXY_URI_TYPE(ClientProperties.PROXY_URI));
- }
- }
-
/**
* Get the underlying Grizzly {@link com.ning.http.client.AsyncHttpClient} instance.
*
diff --git a/connectors/grizzly-connector/src/main/resources/org/glassfish/jersey/grizzly/connector/localization.properties b/connectors/grizzly-connector/src/main/resources/org/glassfish/jersey/grizzly/connector/localization.properties
index 7fb050e..2d577c6 100644
--- a/connectors/grizzly-connector/src/main/resources/org/glassfish/jersey/grizzly/connector/localization.properties
+++ b/connectors/grizzly-connector/src/main/resources/org/glassfish/jersey/grizzly/connector/localization.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,5 +16,4 @@
error.buffering.entity=Error buffering the entity.
expected.connector.provider.not.used=The supplied component is not configured to use a GrizzlyConnectorProvider.
-invalid.configurable.component.type=The supplied component "{0}" is not assignable from JerseyClient or JerseyWebTarget.
-wrong.proxy.uri.type=The proxy URI ("{0}") property MUST be an instance of String or URI.
+invalid.configurable.component.type=The supplied component "{0}" is not assignable from JerseyClient or JerseyWebTarget.
\ No newline at end of file
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
index 655a203..504fb0e 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
+++ b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
@@ -57,6 +57,7 @@
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.ClientRequest;
import org.glassfish.jersey.client.ClientResponse;
+import org.glassfish.jersey.client.innate.ClientProxy;
import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
import org.glassfish.jersey.client.spi.Connector;
import org.glassfish.jersey.internal.util.collection.ByteBufferInputStream;
@@ -193,19 +194,17 @@
auth.addAuthentication((BasicAuthentication) basicAuthProvider);
}
- final Object proxyUri = config.getProperties().get(ClientProperties.PROXY_URI);
- if (proxyUri != null) {
- final URI u = getProxyUri(proxyUri);
+ final Optional<ClientProxy> proxy = ClientProxy.proxyFromConfiguration(config);
+ proxy.ifPresent(clientProxy -> {
final ProxyConfiguration proxyConfig = client.getProxyConfiguration();
+ final URI u = clientProxy.uri();
proxyConfig.getProxies().add(new HttpProxy(u.getHost(), u.getPort()));
- final Object proxyUsername = config.getProperties().get(ClientProperties.PROXY_USERNAME);
- if (proxyUsername != null) {
- final Object proxyPassword = config.getProperties().get(ClientProperties.PROXY_PASSWORD);
+ if (clientProxy.userName() != null) {
auth.addAuthentication(new BasicAuthentication(u, "<<ANY_REALM>>",
- String.valueOf(proxyUsername), String.valueOf(proxyPassword)));
+ clientProxy.userName(), clientProxy.password()));
}
- }
+ });
if (disableCookies) {
client.setCookieStore(new HttpCookieStore.Empty());
@@ -229,17 +228,6 @@
this.cookieStore = client.getCookieStore();
}
- @SuppressWarnings("ChainOfInstanceofChecks")
- private static URI getProxyUri(final Object proxy) {
- if (proxy instanceof URI) {
- return (URI) proxy;
- } else if (proxy instanceof String) {
- return URI.create((String) proxy);
- } else {
- throw new ProcessingException(LocalizationMessages.WRONG_PROXY_URI_TYPE(ClientProperties.PROXY_URI));
- }
- }
-
/**
* Get the {@link HttpClient}.
*
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 af11518..128d40b 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, 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,8 +16,6 @@
# {0} - HTTP method, e.g. GET, DELETE
method.not.supported=Method {0} not supported.
-# {0} - property name - jersey.config.client.proxyUri
-wrong.proxy.uri.type=The proxy URI ("{0}") property MUST be an instance of String or URI.
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/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
index 77d0d27..5d52e76 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
@@ -19,8 +19,6 @@
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.ArrayList;
@@ -29,6 +27,7 @@
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@@ -48,7 +47,6 @@
import io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
@@ -69,7 +67,6 @@
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.proxy.HttpProxyHandler;
-import io.netty.handler.proxy.ProxyConnectionEvent;
import io.netty.handler.proxy.ProxyHandler;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.ClientAuth;
@@ -80,10 +77,12 @@
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
+import io.netty.resolver.NoopAddressResolverGroup;
import io.netty.util.concurrent.GenericFutureListener;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.ClientRequest;
import org.glassfish.jersey.client.ClientResponse;
+import org.glassfish.jersey.client.innate.ClientProxy;
import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
import org.glassfish.jersey.client.spi.Connector;
import org.glassfish.jersey.message.internal.OutboundMessageContext;
@@ -235,6 +234,18 @@
if (chan == null) {
Bootstrap b = new Bootstrap();
+
+ // http proxy
+ Optional<ClientProxy> proxy = ClientProxy.proxyFromRequest(jerseyRequest);
+ if (!proxy.isPresent()) {
+ proxy = ClientProxy.proxyFromProperties(requestUri);
+ }
+ proxy.ifPresent(clientProxy -> {
+ b.resolver(NoopAddressResolverGroup.INSTANCE); // request hostname resolved by the HTTP proxy
+ });
+
+ final Optional<ClientProxy> handlerProxy = proxy;
+
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@@ -245,41 +256,14 @@
Configuration config = jerseyRequest.getConfiguration();
// http proxy
- final Object proxyUri = config.getProperties().get(ClientProperties.PROXY_URI);
- if (proxyUri != null) {
- final URI u = getProxyUri(proxyUri);
-
- final String userName = ClientProperties.getValue(
- config.getProperties(), ClientProperties.PROXY_USERNAME, String.class);
- final String password = ClientProperties.getValue(
- config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
-
+ handlerProxy.ifPresent(clientProxy -> {
+ final URI u = clientProxy.uri();
InetSocketAddress proxyAddr = new InetSocketAddress(u.getHost(),
- u.getPort() == -1 ? 8080 : u.getPort());
- ProxyHandler proxy = createProxyHandler(jerseyRequest, proxyAddr, userName, password, connectTimeout);
- p.addLast(proxy);
- } else {
- ProxySelector sel = ProxySelector.getDefault();
- for (Proxy proxy: sel.select(requestUri)) {
- if (Proxy.Type.HTTP.equals(proxy.type())) {
- SocketAddress proxyAddress = proxy.address();
- if (InetSocketAddress.class.isInstance(proxy.address())) {
- InetSocketAddress proxyAddr = (InetSocketAddress) proxyAddress;
- if (proxyAddr.isUnresolved()
- && proxyAddr.getHostName() != null
- && proxyAddr.getHostName().startsWith("http://")) {
- proxyAddress = new InetSocketAddress(
- proxyAddr.getHostString().substring(7), proxyAddr.getPort()
- );
- }
- }
- ProxyHandler proxyHandler
- = createProxyHandler(jerseyRequest, proxyAddress, null, null, connectTimeout);
- p.addLast(proxyHandler);
- break;
- }
- }
- }
+ u.getPort() == -1 ? 8080 : u.getPort());
+ ProxyHandler proxy1 = createProxyHandler(jerseyRequest, proxyAddr,
+ clientProxy.userName(), clientProxy.password(), connectTimeout);
+ p.addLast(proxy1);
+ });
// Enable HTTPS if necessary.
if ("https".equals(requestUri.getScheme())) {
@@ -471,17 +455,6 @@
executorService.shutdown();
}
- @SuppressWarnings("ChainOfInstanceofChecks")
- private static URI getProxyUri(final Object proxy) {
- if (proxy instanceof URI) {
- return (URI) proxy;
- } else if (proxy instanceof String) {
- return URI.create((String) proxy);
- } else {
- throw new ProcessingException(LocalizationMessages.WRONG_PROXY_URI_TYPE(ClientProperties.PROXY_URI));
- }
- }
-
protected static class PruneIdlePool extends ChannelDuplexHandler {
HashMap<String, ArrayList<Channel>> connections;
String key;
diff --git a/connectors/netty-connector/src/main/resources/org/glassfish/jersey/netty/connector/localization.properties b/connectors/netty-connector/src/main/resources/org/glassfish/jersey/netty/connector/localization.properties
index 9055d62..ba91c4f 100644
--- a/connectors/netty-connector/src/main/resources/org/glassfish/jersey/netty/connector/localization.properties
+++ b/connectors/netty-connector/src/main/resources/org/glassfish/jersey/netty/connector/localization.properties
@@ -14,7 +14,6 @@
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
#
-wrong.proxy.uri.type=The proxy URI ("{0}") property MUST be an instance of String or URI.
wrong.read.timeout=Unexpected ("{0}") READ_TIMEOUT.
wrong.max.pool.size=Unexpected ("{0}") maximum number of connections per destination.
wrong.max.pool.total=Unexpected ("{0}") maximum number of connections total.
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java
index 411100b..909af8d 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnectorProvider.java b/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnectorProvider.java
index 5a07bc1..056f474 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnectorProvider.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnectorProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -18,6 +18,7 @@
import java.io.IOException;
import java.net.HttpURLConnection;
+import java.net.Proxy;
import java.net.URL;
import java.util.Map;
import java.util.logging.Logger;
@@ -267,6 +268,23 @@
* @throws java.io.IOException in case the connection cannot be provided.
*/
public HttpURLConnection getConnection(URL url) throws IOException;
+
+ /**
+ * Get a {@link java.net.HttpURLConnection} for a given URL.
+ * <p>
+ * Implementation of the method MUST be thread-safe and MUST ensure that
+ * a dedicated {@link java.net.HttpURLConnection} instance is returned for concurrent
+ * requests.
+ * </p>
+ *
+ * @param url the endpoint URL.
+ * @param proxy the configured proxy or null.
+ * @return the {@link java.net.HttpURLConnection}.
+ * @throws java.io.IOException in case the connection cannot be provided.
+ */
+ default HttpURLConnection getConnection(URL url, Proxy proxy) throws IOException {
+ return (proxy == null) ? getConnection(url) : (HttpURLConnection) url.openConnection(proxy);
+ }
}
private static class DefaultConnectionFactory implements ConnectionFactory {
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/innate/ClientProxy.java b/core-client/src/main/java/org/glassfish/jersey/client/innate/ClientProxy.java
new file mode 100644
index 0000000..68ab324
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/innate/ClientProxy.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+package org.glassfish.jersey.client.innate;
+
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientRequest;
+import org.glassfish.jersey.client.internal.LocalizationMessages;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.MultivaluedMap;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Locale;
+import java.util.Optional;
+
+/**
+ * Default client Proxy information internal object. It is used for parsing the proxy information in all connectors.
+ */
+public abstract class ClientProxy {
+
+ private ClientProxy() {
+ // do not instantiate
+ };
+
+ public static Optional<ClientProxy> proxyFromRequest(ClientRequest request) {
+ return getProxy(request);
+ }
+
+ public static Optional<ClientProxy> proxyFromProperties(URI requestUri) {
+ return getSystemPropertiesProxy(requestUri);
+ }
+
+ public static Optional<ClientProxy> proxyFromConfiguration(Configuration configuration) {
+ return getProxy(configuration);
+ }
+
+ public static ClientProxy proxy(Proxy proxy) {
+ return new ProxyClientProxy(proxy);
+ }
+
+ public static void setBasicAuthorizationHeader(MultivaluedMap<String, Object> headers, ClientProxy proxy) {
+ if (proxy.userName() != null) {
+ StringBuilder auth = new StringBuilder().append(proxy.userName()).append(":");
+ if (proxy.password() != null) {
+ auth.append(proxy.password());
+ }
+ String encoded = "Basic " + Base64.getEncoder().encodeToString(auth.toString().getBytes());
+ headers.put("Proxy-Authorization", Arrays.asList(encoded));
+ }
+ }
+
+ protected String userName;
+ protected String password;
+
+ private static ClientProxy toProxy(Object proxy) {
+ if (proxy instanceof String) {
+ return new UriClientProxy(URI.create((String) proxy));
+ } else if (proxy instanceof URI) {
+ return new UriClientProxy((URI) proxy);
+ } else if (Proxy.class.isInstance(proxy)) {
+ Proxy netProxy = Proxy.class.cast(proxy);
+ if (Proxy.Type.HTTP.equals(netProxy.type())) {
+ return new ProxyClientProxy(Proxy.class.cast(proxy));
+ } else {
+ return null;
+ }
+ } else {
+ throw new ProcessingException(LocalizationMessages.WRONG_PROXY_URI_TYPE(ClientProperties.PROXY_URI));
+ }
+ }
+
+ public abstract Proxy proxy();
+
+ public abstract URI uri();
+
+ public abstract Proxy.Type type();
+
+ public String password() {
+ return password;
+ }
+
+ public String userName() {
+ return userName;
+ };
+
+ private static Optional<ClientProxy> getProxy(ClientRequest request) {
+ Object proxyUri = request.resolveProperty(ClientProperties.PROXY_URI, Object.class);
+ if (proxyUri != null) {
+ ClientProxy proxy = toProxy(proxyUri);
+ if (proxy != null) {
+ proxy.userName = request.resolveProperty(ClientProperties.PROXY_USERNAME, String.class);
+ proxy.password = request.resolveProperty(ClientProperties.PROXY_PASSWORD, String.class);
+ return Optional.of(proxy);
+ } else {
+ return Optional.empty();
+ }
+ }
+ return Optional.empty();
+ }
+
+ private static Optional<ClientProxy> getProxy(Configuration config) {
+ Object proxyUri = config.getProperties().get(ClientProperties.PROXY_URI);
+ if (proxyUri != null) {
+ ClientProxy proxy = toProxy(proxyUri);
+ if (proxy != null) {
+ proxy.userName = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_USERNAME, String.class);
+ proxy.password = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
+ return Optional.of(proxy);
+ } else {
+ return Optional.empty();
+ }
+ }
+ return Optional.empty();
+ }
+
+ private static Optional<ClientProxy> getSystemPropertiesProxy(URI requestUri) {
+ ProxySelector sel = ProxySelector.getDefault();
+ for (Proxy proxy: sel.select(requestUri)) {
+ if (Proxy.Type.HTTP.equals(proxy.type())) {
+ return Optional.of(new ProxyClientProxy(proxy));
+ }
+ }
+ return Optional.empty();
+ }
+
+ private static final class ProxyClientProxy extends ClientProxy {
+
+ private final Proxy proxy;
+
+ private ProxyClientProxy(Proxy proxy) {
+ this.proxy = proxy;
+ }
+
+ @Override
+ public Proxy proxy() {
+ return proxy;
+ }
+
+ @Override
+ public Proxy.Type type() {
+ return proxy.type();
+ }
+
+ @Override
+ public URI uri() {
+ URI uri = null;
+ if (Proxy.Type.HTTP.equals(proxy.type())) {
+ SocketAddress proxyAddress = proxy.address();
+ if (InetSocketAddress.class.isInstance(proxy.address())) {
+ InetSocketAddress proxyAddr = (InetSocketAddress) proxyAddress;
+ try {
+ if (proxyAddr.isUnresolved()
+ && proxyAddr.getHostName() != null
+ && proxyAddr.getHostName().toLowerCase(Locale.ROOT).startsWith("http://")) {
+ String hostString = proxyAddr.getHostString().substring(7);
+ uri = new URI("http", null, hostString, proxyAddr.getPort(), null, null, null);
+ } else {
+ uri = new URI("http", null, proxyAddr.getHostString(), proxyAddr.getPort(), null, null, null);
+ }
+ } catch (URISyntaxException e) {
+ throw new ProcessingException(e);
+ }
+ }
+ }
+ return uri;
+ }
+ }
+
+ private static final class UriClientProxy extends ClientProxy {
+ private final URI uri;
+
+ private UriClientProxy(URI uri) {
+ this.uri = uri;
+ }
+
+ @Override
+ public Proxy proxy() {
+ return new Proxy(type(), new InetSocketAddress(uri.getHost(), uri.getPort()));
+ }
+
+ @Override
+ public Proxy.Type type() {
+ return Proxy.Type.HTTP;
+ }
+
+ @Override
+ public URI uri() {
+ return uri;
+ }
+ }
+}
+
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/innate/package-info.java b/core-client/src/main/java/org/glassfish/jersey/client/innate/package-info.java
new file mode 100644
index 0000000..016eea7
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/innate/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/**
+ * Jersey client MOST INTERNAL classes/interfaces.
+ * Shall not be used outside of Jersey.
+ */
+package org.glassfish.jersey.client.innate;
\ No newline at end of file
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java
index 10f2387..31a3583 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -32,6 +32,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
@@ -39,21 +40,21 @@
import java.util.logging.Logger;
import java.util.stream.Collectors;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSocketFactory;
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.Response;
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
-
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.ClientRequest;
import org.glassfish.jersey.client.ClientResponse;
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
import org.glassfish.jersey.client.JerseyClient;
import org.glassfish.jersey.client.RequestEntityProcessing;
+import org.glassfish.jersey.client.innate.ClientProxy;
import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
import org.glassfish.jersey.client.spi.Connector;
import org.glassfish.jersey.internal.util.PropertiesHelper;
@@ -316,8 +317,9 @@
private ClientResponse _apply(final ClientRequest request) throws IOException {
final HttpURLConnection uc;
-
- uc = this.connectionFactory.getConnection(request.getUri().toURL());
+ Optional<ClientProxy> proxy = ClientProxy.proxyFromRequest(request);
+ proxy.ifPresent(clientProxy -> ClientProxy.setBasicAuthorizationHeader(request.getHeaders(), proxy.get()));
+ uc = this.connectionFactory.getConnection(request.getUri().toURL(), proxy.isPresent() ? proxy.get().proxy() : null);
uc.setDoInput(true);
final String httpMethod = request.getMethod();
diff --git a/core-client/src/main/resources/org/glassfish/jersey/client/internal/localization.properties b/core-client/src/main/resources/org/glassfish/jersey/client/internal/localization.properties
index 4bc0ae8..e66ceab 100644
--- a/core-client/src/main/resources/org/glassfish/jersey/client/internal/localization.properties
+++ b/core-client/src/main/resources/org/glassfish/jersey/client/internal/localization.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -84,3 +84,5 @@
error.listener.init=ClientLifecycleListener {0} failed to initialize properly.
error.listener.close=ClientLifecycleListener {0} failed to close properly.
error.shutdownhook.close=Client shutdown hook {0} failed.
+# {0} - property name - jersey.config.client.httpclient.proxyUri
+wrong.proxy.uri.type=The proxy URI ("{0}") property MUST be an instance of String or URI.
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/HttpUrlConnectorTest.java b/core-client/src/test/java/org/glassfish/jersey/client/HttpUrlConnectorTest.java
index 5204144..7a00f1f 100644
--- a/core-client/src/test/java/org/glassfish/jersey/client/HttpUrlConnectorTest.java
+++ b/core-client/src/test/java/org/glassfish/jersey/client/HttpUrlConnectorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/core-common/src/main/java/org/glassfish/jersey/ExternalProperties.java b/core-common/src/main/java/org/glassfish/jersey/ExternalProperties.java
index 04ef1bd..a8f6ec6 100644
--- a/core-common/src/main/java/org/glassfish/jersey/ExternalProperties.java
+++ b/core-common/src/main/java/org/glassfish/jersey/ExternalProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -32,12 +32,22 @@
public static final String HTTP_PROXY_PORT = "http.proxyPort";
/**
- * Property used to indicates the hosts that should be accessed
+ * Property used to indicate the hosts that should be accessed
* without going through the proxy.
*/
public static final String HTTP_NON_PROXY_HOSTS = "http.nonProxyHosts";
/**
+ * Property used to specify the user name to authenticate with the proxy.
+ */
+ public static final String HTTP_PROXY_USER = "http.proxyUser";
+
+ /**
+ * Property used to specify the password to authenticate with the proxy.
+ */
+ public static final String HTTP_PROXY_PASSWORD = "http.proxyPassword";
+
+ /**
* Prevent instantiation.
*/
private ExternalProperties() {
diff --git a/examples/groovy/pom.xml b/examples/groovy/pom.xml
index c3cb714..49a7051 100644
--- a/examples/groovy/pom.xml
+++ b/examples/groovy/pom.xml
@@ -77,7 +77,7 @@
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
- <version>1.12.1</version>
+ <version>${org.codehaus.gmavenplus.version}</version>
<executions>
<execution>
<id>1</id>
diff --git a/examples/open-tracing/pom.xml b/examples/open-tracing/pom.xml
index 21f246e..cc01f99 100644
--- a/examples/open-tracing/pom.xml
+++ b/examples/open-tracing/pom.xml
@@ -52,7 +52,17 @@
<dependency>
<groupId>com.uber.jaeger</groupId>
<artifactId>jaeger-core</artifactId>
- <version>0.20.0</version>
+ <version>${com.uber.jaeger.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
diff --git a/ext/cdi/jersey-weld2-se/pom.xml b/ext/cdi/jersey-weld2-se/pom.xml
index 17e5f20..18eddfb 100644
--- a/ext/cdi/jersey-weld2-se/pom.xml
+++ b/ext/cdi/jersey-weld2-se/pom.xml
@@ -36,6 +36,12 @@
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>jakarta.interceptor</groupId>
+ <artifactId>jakarta.interceptor-api</artifactId>
+ </exclusion>
+ </exclusions>
<scope>provided</scope>
</dependency>
<dependency>
@@ -51,6 +57,12 @@
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>jakarta.interceptor</groupId>
+ <artifactId>jakarta.interceptor-api</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
</dependencies>
diff --git a/ext/mvc-mustache/pom.xml b/ext/mvc-mustache/pom.xml
index 8a14f5c..c409a7c 100644
--- a/ext/mvc-mustache/pom.xml
+++ b/ext/mvc-mustache/pom.xml
@@ -66,6 +66,17 @@
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>${mustache.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${guava.version}</version>
</dependency>
</dependencies>
diff --git a/ext/rx/rx-client-rxjava2/pom.xml b/ext/rx/rx-client-rxjava2/pom.xml
index d0f8bb2..f859654 100644
--- a/ext/rx/rx-client-rxjava2/pom.xml
+++ b/ext/rx/rx-client-rxjava2/pom.xml
@@ -42,11 +42,17 @@
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>${rxjava2.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.reactivestreams</groupId>
+ <artifactId>reactive-streams</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.reactivestreams</groupId>
<artifactId>reactive-streams</artifactId>
- <version>1.0.0</version>
+ <version>${reactive.streams.version}</version>
</dependency>
</dependencies>
</project>
diff --git a/ext/spring6/pom.xml b/ext/spring6/pom.xml
index 2cfbff6..4f28e94 100644
--- a/ext/spring6/pom.xml
+++ b/ext/spring6/pom.xml
@@ -89,6 +89,12 @@
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2</artifactId>
<version>${hk2.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
diff --git a/incubator/html-json/pom.xml b/incubator/html-json/pom.xml
index 086d6e3..3ad5b9e 100644
--- a/incubator/html-json/pom.xml
+++ b/incubator/html-json/pom.xml
@@ -40,6 +40,7 @@
<properties>
<net.java.html.version>1.5.1</net.java.html.version>
+ <enforcer.skip>true</enforcer.skip>
</properties>
<dependencies>
diff --git a/incubator/kryo/pom.xml b/incubator/kryo/pom.xml
index 7c09b33..36b1f1b 100644
--- a/incubator/kryo/pom.xml
+++ b/incubator/kryo/pom.xml
@@ -48,6 +48,17 @@
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm</artifactId>
+ <version>${asm.version}</version>
</dependency>
<dependency>
diff --git a/inject/hk2/pom.xml b/inject/hk2/pom.xml
index fd0875b..0f9eacb 100644
--- a/inject/hk2/pom.xml
+++ b/inject/hk2/pom.xml
@@ -51,6 +51,10 @@
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>jakarta.inject</groupId>
+ <artifactId>jakarta.inject-api</artifactId>
+ </exclusion>
</exclusions>
</dependency>
diff --git a/media/json-gson/pom.xml b/media/json-gson/pom.xml
new file mode 100644
index 0000000..8b2c2c5
--- /dev/null
+++ b/media/json-gson/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<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.media</groupId>
+ <artifactId>project</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>jersey-media-json-gson</artifactId>
+ <packaging>jar</packaging>
+ <name>jersey-media-json-gson</name>
+
+ <description>
+ Jersey GSON support module.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.sun.istack</groupId>
+ <artifactId>istack-commons-maven-plugin</artifactId>
+ <inherited>true</inherited>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <inherited>true</inherited>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <inherited>true</inherited>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>org.glassfish.jersey.gson.*</Export-Package>
+ <Import-Package>${javax.annotation.osgi.version},*</Import-Package>
+ </instructions>
+ <unpackBundle>true</unpackBundle>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/media/json-gson/src/main/java/org/glassfish/jersey/gson/JsonGsonFeature.java b/media/json-gson/src/main/java/org/glassfish/jersey/gson/JsonGsonFeature.java
new file mode 100644
index 0000000..498f958
--- /dev/null
+++ b/media/json-gson/src/main/java/org/glassfish/jersey/gson/JsonGsonFeature.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.gson;
+
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Feature;
+import jakarta.ws.rs.core.FeatureContext;
+
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.gson.internal.JsonGsonAutoDiscoverable;
+import org.glassfish.jersey.gson.internal.JsonGsonProvider;
+import org.glassfish.jersey.internal.InternalProperties;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+/**
+ * Feature used to register Gson providers.
+ * <p>
+ * The Feature is automatically enabled when {@link JsonGsonAutoDiscoverable} is on classpath.
+ * Default GSON configuration obtained by calling {@code GsonBuilder.create()} is used.
+ * <p>
+ * Custom configuration, if required, can be achieved by implementing custom {@link jakarta.ws.rs.ext.ContextResolver} and
+ * registering it as a provider into JAX-RS runtime:
+ * <pre>
+ * @Provider
+ * @class GsonContextResolver implements ContextResolver<Gson> {
+ * @Override
+ * public Gson getContext(Class<?> type) {
+ * GsonBuilder builder = new GsonBuilder();
+ * // add custom configuration
+ * return builder.create();
+ * }
+ * }
+ * </pre>
+ *
+ */
+public class JsonGsonFeature implements Feature {
+
+ private static final String JSON_FEATURE = JsonGsonFeature.class.getSimpleName();
+
+ @Override
+ public boolean configure(final FeatureContext context) {
+ final Configuration config = context.getConfiguration();
+
+ final String jsonFeature = CommonProperties.getValue(
+ config.getProperties(),
+ config.getRuntimeType(),
+ InternalProperties.JSON_FEATURE, JSON_FEATURE, String.class);
+
+ // Other JSON providers registered.
+ if (!JSON_FEATURE.equalsIgnoreCase(jsonFeature)) {
+ return false;
+ }
+
+ // Disable other JSON providers.
+ context.property(PropertiesHelper.getPropertyNameForRuntime(
+ InternalProperties.JSON_FEATURE, config.getRuntimeType()), JSON_FEATURE);
+
+ context.register(JsonGsonProvider.class);
+
+ return true;
+ }
+}
diff --git a/media/json-gson/src/main/java/org/glassfish/jersey/gson/internal/JsonGsonAutoDiscoverable.java b/media/json-gson/src/main/java/org/glassfish/jersey/gson/internal/JsonGsonAutoDiscoverable.java
new file mode 100644
index 0000000..f532953
--- /dev/null
+++ b/media/json-gson/src/main/java/org/glassfish/jersey/gson/internal/JsonGsonAutoDiscoverable.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.gson.internal;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.core.FeatureContext;
+
+import org.glassfish.jersey.gson.JsonGsonFeature;
+import org.glassfish.jersey.internal.spi.AutoDiscoverable;
+import org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable;
+
+/**
+ * {@link ForcedAutoDiscoverable} registering {@link JsonGsonFeature} if the feature is not already registered.
+ * <p>
+ *
+ * @see JsonGsonFeature
+ */
+@Priority(AutoDiscoverable.DEFAULT_PRIORITY)
+public class JsonGsonAutoDiscoverable implements ForcedAutoDiscoverable {
+
+ @Override
+ public void configure(FeatureContext context) {
+ if (!context.getConfiguration().isRegistered(JsonGsonFeature.class)) {
+ context.register(JsonGsonFeature.class);
+ }
+ }
+}
diff --git a/media/json-gson/src/main/java/org/glassfish/jersey/gson/internal/JsonGsonProvider.java b/media/json-gson/src/main/java/org/glassfish/jersey/gson/internal/JsonGsonProvider.java
new file mode 100644
index 0000000..a35dfad
--- /dev/null
+++ b/media/json-gson/src/main/java/org/glassfish/jersey/gson/internal/JsonGsonProvider.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.gson.internal;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.NoContentException;
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.Providers;
+
+import org.glassfish.jersey.gson.LocalizationMessages;
+import org.glassfish.jersey.message.internal.AbstractMessageReaderWriterProvider;
+import org.glassfish.jersey.message.internal.EntityInputStream;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * Entity provider (reader and writer) for Gson.
+ *
+ */
+@Provider
+@Produces({"application/json", "text/json", "*/*"})
+@Consumes({"application/json", "text/json", "*/*"})
+public class JsonGsonProvider extends AbstractMessageReaderWriterProvider<Object> {
+
+ private static final String JSON = "json";
+ private static final String PLUS_JSON = "+json";
+
+ private Providers providers;
+
+ public JsonGsonProvider(@Context Providers providers) {
+ this.providers = providers;
+ }
+
+ @Override
+ public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return supportsMediaType(mediaType);
+ }
+
+ @Override
+ public Object readFrom(Class<Object> type, Type genericType,
+ Annotation[] annotations,
+ MediaType mediaType,
+ MultivaluedMap<String, String> httpHeaders,
+ InputStream entityStream) throws IOException, WebApplicationException {
+ EntityInputStream entityInputStream = new EntityInputStream(entityStream);
+ entityStream = entityInputStream;
+ if (entityInputStream.isEmpty()) {
+ throw new NoContentException(LocalizationMessages.ERROR_GSON_EMPTYSTREAM());
+ }
+ Gson gson = getGson(type);
+ try {
+ return gson.fromJson(new InputStreamReader(entityInputStream,
+ AbstractMessageReaderWriterProvider.getCharset(mediaType)), genericType);
+ } catch (Exception e) {
+ throw new ProcessingException(LocalizationMessages.ERROR_GSON_DESERIALIZATION(), e);
+ }
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+ return supportsMediaType(mediaType);
+ }
+
+ @Override
+ public void writeTo(Object o, Class<?> type, Type genericType,
+ Annotation[] annotations,
+ MediaType mediaType,
+ MultivaluedMap<String, Object> httpHeaders,
+ OutputStream entityStream) throws IOException, WebApplicationException {
+ Gson gson = getGson(type);
+ try {
+ entityStream.write(gson.toJson(o).getBytes(AbstractMessageReaderWriterProvider.getCharset(mediaType)));
+ entityStream.flush();
+ } catch (Exception e) {
+ throw new ProcessingException(LocalizationMessages.ERROR_GSON_SERIALIZATION(), e);
+ }
+ }
+
+ private Gson getGson(Class<?> type) {
+ final ContextResolver<Gson> contextResolver = providers.getContextResolver(Gson.class, MediaType.APPLICATION_JSON_TYPE);
+ if (contextResolver != null) {
+ return contextResolver.getContext(type);
+ } else {
+ return GsonSingleton.INSTANCE.getInstance();
+ }
+ }
+
+ /**
+ * @return true for all media types of the pattern */json and
+ * */*+json.
+ */
+ private static boolean supportsMediaType(final MediaType mediaType) {
+ return mediaType.getSubtype().equals(JSON) || mediaType.getSubtype().endsWith(PLUS_JSON);
+ }
+
+ private enum GsonSingleton {
+ INSTANCE;
+
+ // Thread-safe
+ private Gson gsonInstance;
+
+ Gson getInstance() {
+ return gsonInstance;
+ }
+
+ GsonSingleton() {
+ this.gsonInstance = new GsonBuilder().create();
+ }
+ }
+}
diff --git a/media/json-gson/src/main/java/org/glassfish/jersey/gson/package-info.java b/media/json-gson/src/main/java/org/glassfish/jersey/gson/package-info.java
new file mode 100644
index 0000000..12e6b90
--- /dev/null
+++ b/media/json-gson/src/main/java/org/glassfish/jersey/gson/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/**
+ * Jersey classes supporting JSON marshalling and unmarshalling using GSON.
+ */
+package org.glassfish.jersey.gson;
diff --git a/media/json-gson/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable b/media/json-gson/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable
new file mode 100644
index 0000000..7f4e0ee
--- /dev/null
+++ b/media/json-gson/src/main/resources/META-INF/services/org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable
@@ -0,0 +1 @@
+org.glassfish.jersey.gson.internal.JsonGsonAutoDiscoverable
diff --git a/media/json-gson/src/main/resources/org/glassfish/jersey/gson/localization.properties b/media/json-gson/src/main/resources/org/glassfish/jersey/gson/localization.properties
new file mode 100644
index 0000000..b2ea26a
--- /dev/null
+++ b/media/json-gson/src/main/resources/org/glassfish/jersey/gson/localization.properties
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v. 2.0, which is available at
+# http://www.eclipse.org/legal/epl-2.0.
+#
+# This Source Code may also be made available under the following Secondary
+# Licenses when the conditions for such availability set forth in the
+# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+# version 2 with the GNU Classpath Exception, which is available at
+# https://www.gnu.org/software/classpath/license.html.
+#
+# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+#
+
+error.gson.serialization=Error writing GSON serialized object.
+error.gson.deserialization=Error deserializing object from entity stream.
+error.gson.emptystream=GSON cannot parse empty input stream.
diff --git a/media/json-gson/src/test/java/org/glassfish/jersey/gson/internal/JsonGsonProviderTest.java b/media/json-gson/src/test/java/org/glassfish/jersey/gson/internal/JsonGsonProviderTest.java
new file mode 100644
index 0000000..7aa403e
--- /dev/null
+++ b/media/json-gson/src/test/java/org/glassfish/jersey/gson/internal/JsonGsonProviderTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.gson.internal;
+
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedHashMap;
+import jakarta.ws.rs.core.NoContentException;
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Providers;
+
+import org.junit.Test;
+
+public class JsonGsonProviderTest {
+
+ @Test(expected = NoContentException.class)
+ public void shouldThrowNoContentException() throws IOException {
+ Providers providers = new EmptyProviders();
+ MessageBodyReader<Foo> mbr = (MessageBodyReader) new JsonGsonProvider(providers);
+ mbr.readFrom(Foo.class, Foo.class, new Annotation[0], APPLICATION_JSON_TYPE,
+ new MultivaluedHashMap<>(), new ByteArrayInputStream(new byte[0]));
+ }
+
+ private static final class Foo {
+ // no members
+ }
+
+ private static final class EmptyProviders implements Providers {
+
+ @Override
+ public final <T> MessageBodyReader<T> getMessageBodyReader(final Class<T> type, final Type genericType,
+ final Annotation[] annotations, final MediaType mediaType) {
+ return null;
+ }
+
+ @Override
+ public final <T> MessageBodyWriter<T> getMessageBodyWriter(final Class<T> type, final Type genericType,
+ final Annotation[] annotations, final MediaType mediaType) {
+ return null;
+ }
+
+ @Override
+ public final <T extends Throwable> ExceptionMapper<T> getExceptionMapper(final Class<T> type) {
+ return null;
+ }
+
+ @Override
+ public final <T> ContextResolver<T> getContextResolver(final Class<T> contextType, final MediaType mediaType) {
+ return null;
+ }
+
+ }
+
+}
diff --git a/media/pom.xml b/media/pom.xml
index 68daa76..e738eb1 100644
--- a/media/pom.xml
+++ b/media/pom.xml
@@ -38,6 +38,7 @@
<modules>
<module>jaxb</module>
<module>json-binding</module>
+ <module>json-gson</module>
<module>json-jackson</module>
<module>json-jettison</module>
<module>json-processing</module>
diff --git a/pom.xml b/pom.xml
index c010f31..e66d89d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -236,7 +236,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
- <version>3.0.0-M2</version>
+ <version>${enforcer.version}</version>
<executions>
<execution>
<id>enforce-versions</id>
@@ -248,6 +248,7 @@
<requireJavaVersion>
<version>${java.version}</version>
</requireJavaVersion>
+ <dependencyConvergence/>
</rules>
</configuration>
</execution>
@@ -2063,6 +2064,12 @@
</dependency>
<dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>${gson.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-api</artifactId>
<version>${opentracing.version}</version>
@@ -2124,6 +2131,15 @@
<freemarker.version>2.3.27-incubating</freemarker.version>
<gae.version>1.9.59</gae.version>
<grizzly.client.version>1.16</grizzly.client.version>
+ <enforcer.version>3.1.0</enforcer.version>
+
+ <!--versions, extracted here due to maven-enforcer-plugin -->
+ <slf4j.version>2.0.0-alpha6</slf4j.version>
+ <commons.codec.version>1.15</commons.codec.version>
+ <reactive.streams.version>1.0.3</reactive.streams.version>
+ <com.uber.jaeger.version>0.27.0</com.uber.jaeger.version>
+ <org.codehaus.gmavenplus.version>1.13.1</org.codehaus.gmavenplus.version>
+ <!-- end of versions extracted here due to maven-enforcer-plugin -->
<!-- microprofile -->
<microprofile.config.version>3.0</microprofile.config.version>
@@ -2148,7 +2164,7 @@
<jmh.version>1.10.2</jmh.version>
<jmockit.version>1.44</jmockit.version>
<junit5.version>5.6.0</junit5.version>
- <kryo.version>4.0.1</kryo.version>
+ <kryo.version>4.0.2</kryo.version>
<mockito.version>3.9.0</mockito.version> <!-- CQ 17673 -->
<mustache.version>0.8.17</mustache.version>
<netty.version>4.1.75.Final</netty.version>
@@ -2169,9 +2185,9 @@
<simple.version>6.0.1</simple.version>
<skip.e2e>false</skip.e2e>
- <slf4j.version>1.7.21</slf4j.version>
<spring6.version>6.0.0-M3</spring6.version>
<surefire.version>3.0.0-M6</surefire.version>
+ <gson.version>2.9.0</gson.version>
<!-- Jakartified, eligible for CQ -->
<weld.version>5.0.0.SP2</weld.version>
diff --git a/test-framework/maven/container-runner-maven-plugin/pom.xml b/test-framework/maven/container-runner-maven-plugin/pom.xml
index 1f75a57..710dab3 100644
--- a/test-framework/maven/container-runner-maven-plugin/pom.xml
+++ b/test-framework/maven/container-runner-maven-plugin/pom.xml
@@ -36,9 +36,9 @@
</description>
<properties>
- <groovy.version>3.0.2</groovy.version>
- <groovy-eclipse-compiler.version>3.6.0-03</groovy-eclipse-compiler.version>
- <groovy-eclipse-batch.version>3.0.2-02</groovy-eclipse-batch.version>
+ <groovy.version>3.0.9</groovy.version>
+ <groovy-eclipse-compiler.version>3.7.0</groovy-eclipse-compiler.version>
+ <groovy-eclipse-batch.version>3.0.8-01</groovy-eclipse-batch.version>
<maven.version>3.6.0</maven.version>
<maven-plugin.version>3.6.0</maven-plugin.version>
</properties>
@@ -49,6 +49,28 @@
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${maven.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-sec-dispatcher</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
@@ -59,6 +81,12 @@
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${maven.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
@@ -89,16 +117,31 @@
</dependency>
<dependency>
- <groupId>org.apache.maven</groupId>
- <artifactId>maven-project</artifactId>
- <version>2.2.1</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
- <version>1.7.0</version>
+ <version>${org.codehaus.gmavenplus.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>file-management</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
@@ -111,6 +154,16 @@
<artifactId>groovy-all</artifactId>
<type>pom</type>
<version>${groovy.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-launcher</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
diff --git a/test-framework/maven/custom-enforcer-rules/pom.xml b/test-framework/maven/custom-enforcer-rules/pom.xml
index 909d37d..454813d 100644
--- a/test-framework/maven/custom-enforcer-rules/pom.xml
+++ b/test-framework/maven/custom-enforcer-rules/pom.xml
@@ -34,12 +34,32 @@
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
- <version>1.4.1</version>
+ <version>${enforcer.version}</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-util</artifactId>
+ </exclusion>
</exclusions>
</dependency>
diff --git a/tests/e2e-client/pom.xml b/tests/e2e-client/pom.xml
index e58048f..729a433 100644
--- a/tests/e2e-client/pom.xml
+++ b/tests/e2e-client/pom.xml
@@ -187,6 +187,11 @@
<artifactId>xmlunit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>${commons.io.version}</version>
+ </dependency>
</dependencies>
<profiles>
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/ChunkedInputStreamClosedPrematurelyTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/ChunkedInputStreamClosedPrematurelyTest.java
index 33b1fbb..3298e5d 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/ChunkedInputStreamClosedPrematurelyTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/ChunkedInputStreamClosedPrematurelyTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,6 +22,7 @@
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
@@ -57,8 +58,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import com.google.common.util.concurrent.SettableFuture;
-
/**
* Reproducer for JERSEY-2705. Client side entity InputStream exception
* in chunked mode should not lead to the same behavior on the server side,
@@ -80,7 +79,7 @@
@SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "JavaDoc"})
public static class TestResource {
- private static final ConcurrentMap<String, SettableFuture<Exception>> REQUEST_MAP = new ConcurrentHashMap<>();
+ private static final ConcurrentMap<String, CompletableFuture<Exception>> REQUEST_MAP = new ConcurrentHashMap<>();
@QueryParam(REQ_ID_PARAM_NAME)
private String reqId;
@@ -100,7 +99,7 @@
thrown = ex;
}
- if (!getFutureFor(reqId).set(thrown)) {
+ if (!getFutureFor(reqId).complete(thrown)) {
LOGGER.log(Level.WARNING,
"Unable to set stream processing exception into the settable future instance for request id " + reqId,
thrown);
@@ -113,7 +112,7 @@
@GET
public Boolean getRequestWasMade() {
// add a new future for the request if not there yet to avoid race conditions with POST processing
- final SettableFuture<Exception> esf = getFutureFor(reqId);
+ final CompletableFuture<Exception> esf = getFutureFor(reqId);
try {
// wait for up to three second for a request to be made;
// there is always a value, if set...
@@ -126,7 +125,7 @@
@Path("/requestCausedException")
@GET
public Boolean getRequestCausedException() {
- final SettableFuture<Exception> esf = getFutureFor(reqId);
+ final CompletableFuture<Exception> esf = getFutureFor(reqId);
try {
return esf.get(3, TimeUnit.SECONDS) != NO_EXCEPTION;
} catch (InterruptedException | ExecutionException | TimeoutException e) {
@@ -134,9 +133,9 @@
}
}
- private SettableFuture<Exception> getFutureFor(String key) {
- final SettableFuture<Exception> esf = SettableFuture.create();
- final SettableFuture<Exception> oldEsf = REQUEST_MAP.putIfAbsent(key, esf);
+ private CompletableFuture<Exception> getFutureFor(String key) {
+ final CompletableFuture<Exception> esf = new CompletableFuture();
+ final CompletableFuture<Exception> oldEsf = REQUEST_MAP.putIfAbsent(key, esf);
return (oldEsf != null) ? oldEsf : esf;
}
}
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 1741a66..91ea1b1 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
@@ -61,9 +61,8 @@
@Parameterized.Parameters(name = "{index}: {0}")
public static List<Object[]> testData() {
return Arrays.asList(new Object[][]{
-// {ApacheConnectorProvider.class},
-// {Apache5ConnectorProvider.class},
-// {JettyConnectorProvider.class},
+ // Apache, Grizzly, Jetty have the proxy set on constructor, i.e. ProxySelector cannot choose based on URI.
+ // HttpUrlConnector ignores proxy on localhost.
{NettyConnectorProvider.class},
});
}
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 1ae437b..f3006e2 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
@@ -25,7 +25,9 @@
import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.HttpUrlConnectorProvider;
import org.glassfish.jersey.client.spi.ConnectorProvider;
+import org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider;
import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
import org.glassfish.jersey.netty.connector.NettyConnectorProvider;
import org.junit.AfterClass;
@@ -70,8 +72,10 @@
return Arrays.asList(new Object[][]{
{ApacheConnectorProvider.class},
{Apache5ConnectorProvider.class},
+ {GrizzlyConnectorProvider.class},
{JettyConnectorProvider.class},
{NettyConnectorProvider.class},
+ {HttpUrlConnectorProvider.class},
});
}
@@ -96,9 +100,11 @@
@Test
public void testGet407() {
+ // Grizzly sends (String)null password and username
+ int expected = GrizzlyConnectorProvider.class.isInstance(connectorProvider) ? 400 : 407;
client().property(ClientProperties.PROXY_URI, ProxyTest.PROXY_URI);
try (Response response = target("proxyTest").request().get()) {
- assertEquals(407, response.getStatus());
+ assertEquals(expected, response.getStatus());
} catch (ProcessingException pe) {
Assert.assertTrue(pe.getMessage().contains("407")); // netty
}
@@ -110,7 +116,8 @@
client().property(ClientProperties.PROXY_USERNAME, ProxyTest.PROXY_USERNAME);
client().property(ClientProperties.PROXY_PASSWORD, ProxyTest.PROXY_PASSWORD);
Response response = target("proxyTest").request().get();
- assertEquals(200, response.getStatus());
+ response.bufferEntity();
+ assertEquals(response.readEntity(String.class), 200, response.getStatus());
}
private static Server server;
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 79d944d..8219d6b 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
@@ -37,7 +37,7 @@
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
-import com.google.common.io.ByteStreams;
+import org.apache.commons.io.IOUtils;
/**
* SSL connector hostname verification tests.
@@ -101,9 +101,9 @@
final InputStream trustStore = SslConnectorConfigurationTest.class.getResourceAsStream(clientTrustStore());
final InputStream keyStore = SslConnectorConfigurationTest.class.getResourceAsStream(CLIENT_KEY_STORE);
return SslConfigurator.newInstance()
- .trustStoreBytes(ByteStreams.toByteArray(trustStore))
+ .trustStoreBytes(IOUtils.toByteArray(trustStore))
.trustStorePassword("asdfgh")
- .keyStoreBytes(ByteStreams.toByteArray(keyStore))
+ .keyStoreBytes(IOUtils.toByteArray(keyStore))
.keyPassword("asdfgh")
.createSSLContext();
}
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/Server.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/Server.java
index c986c2c..20795c3 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/Server.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/Server.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -23,6 +23,7 @@
import jakarta.ws.rs.core.UriBuilder;
+import org.apache.commons.io.IOUtils;
import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
@@ -31,8 +32,6 @@
import org.glassfish.grizzly.ssl.SSLContextConfigurator;
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
-import com.google.common.io.ByteStreams;
-
/**
* A simple SSL-secured HTTP server for testing purposes.
*
@@ -87,9 +86,9 @@
SSLContextConfigurator sslContext = new SSLContextConfigurator();
// set up security context
- sslContext.setKeyStoreBytes(ByteStreams.toByteArray(keyStore)); // contains server key pair
+ sslContext.setKeyStoreBytes(IOUtils.toByteArray(keyStore)); // contains server key pair
sslContext.setKeyStorePass("asdfgh");
- sslContext.setTrustStoreBytes(ByteStreams.toByteArray(trustStore)); // contains client certificate
+ sslContext.setTrustStoreBytes(IOUtils.toByteArray(trustStore)); // contains client certificate
sslContext.setTrustStorePass("asdfgh");
ResourceConfig rc = new ResourceConfig();
diff --git a/tests/e2e-server/pom.xml b/tests/e2e-server/pom.xml
index aca4fa5..51408e2 100644
--- a/tests/e2e-server/pom.xml
+++ b/tests/e2e-server/pom.xml
@@ -95,6 +95,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-gson</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-bean-validation</artifactId>
<scope>test</scope>
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/GsonCustomTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/GsonCustomTest.java
new file mode 100644
index 0000000..a967dc7
--- /dev/null
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/GsonCustomTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.e2e.server;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Date;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.ws.rs.ext.Provider;
+
+import org.glassfish.jersey.gson.JsonGsonFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class GsonCustomTest extends JerseyTest {
+
+ private static final Date date = new Date(0);
+
+ @Path("/test")
+ public static class Resource {
+
+ @GET
+ @Consumes("application/json")
+ public Date get() {
+ return date;
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig(Resource.class).register(JsonGsonFeature.class).register(GsonContextResolver.class);
+ }
+
+ @Test
+ public void get() {
+ Response response = target("/test").request().get();
+ assertEquals(200, response.getStatus());
+ String obj = response.readEntity(String.class);
+ assertEquals("\"1970\"", obj);
+ }
+
+ @Provider
+ public static class GsonContextResolver implements ContextResolver<Gson> {
+ @Override
+ public Gson getContext(Class<?> type) {
+ GsonBuilder builder = new GsonBuilder();
+ builder.setDateFormat("yyyy");
+ return builder.create();
+ }
+ }
+}
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/GsonDefaultTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/GsonDefaultTest.java
new file mode 100644
index 0000000..0d0dad5
--- /dev/null
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/GsonDefaultTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.e2e.server;
+
+import static org.junit.Assert.assertEquals;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+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.gson.JsonGsonFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+public class GsonDefaultTest extends JerseyTest {
+
+ @Path("/test")
+ public static class Resource {
+
+ @POST
+ @Consumes("application/json")
+ @Produces("application/json")
+ public Obj post(Obj entity) {
+ entity.setValue("bar");
+ return entity;
+ }
+
+ @GET
+ @Consumes("application/json")
+ public Obj get() {
+ Obj entity = new Obj();
+ entity.setValue("get");
+ return entity;
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ return new ResourceConfig(Resource.class)
+ .register(JsonGsonFeature.class);
+ }
+
+ @Override
+ protected void configureClient(ClientConfig config) {
+ config.register(JsonGsonFeature.class);
+ }
+
+ @Test
+ public void get() {
+ Response response = target("/test").request().get();
+ assertEquals(200, response.getStatus());
+ Obj obj = response.readEntity(Obj.class);
+ assertEquals("get", obj.getValue());
+ }
+
+ @Test
+ public void post() {
+ Obj obj = new Obj();
+ obj.setValue("foo");
+ Response response = target("/test").request().post(Entity.json(obj));
+ assertEquals(200, response.getStatus());
+ obj = response.readEntity(Obj.class);
+ assertEquals("bar", obj.getValue());
+ }
+
+ public static class Obj {
+ private String value;
+
+ public String getValue() {
+ return value;
+ }
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+}
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlBeanParamTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlBeanParamTest.java
index 481c20c..98965c9 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlBeanParamTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlBeanParamTest.java
@@ -22,7 +22,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import java.util.Properties;
+import java.util.Collections;
import jakarta.ws.rs.BeanParam;
import jakarta.ws.rs.CookieParam;
@@ -66,8 +66,6 @@
import org.w3c.dom.Element;
import org.w3c.dom.Node;
-import com.google.common.collect.ImmutableMap;
-
/**
* Tests whether WADL for a {@link BeanParam} annotated resource method parameter is generated properly.
* <p/>
@@ -174,7 +172,7 @@
XPathConstants.NODE))
);
XMLUnit.setXpathNamespaceContext(
- new SimpleNamespaceContext(ImmutableMap.of("wadl", "http://wadl.dev.java.net/2009/02")));
+ new SimpleNamespaceContext(Collections.singletonMap("wadl", "http://wadl.dev.java.net/2009/02")));
diff.overrideElementQualifier(elementQualifier);
XMLAssert.assertXMLEqual(diff, true);
}
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlResourceTest.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlResourceTest.java
index da2d787..1729036 100644
--- a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlResourceTest.java
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/wadl/WadlResourceTest.java
@@ -27,6 +27,7 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.URI;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -112,8 +113,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import com.google.common.collect.ImmutableMap;
-
import com.sun.research.ws.wadl.Method;
import com.sun.research.ws.wadl.Param;
import com.sun.research.ws.wadl.Request;
@@ -1284,7 +1283,7 @@
XPathConstants.NODE))
);
XMLUnit.setXpathNamespaceContext(
- new SimpleNamespaceContext(ImmutableMap.of("wadl", "http://wadl.dev.java.net/2009/02")));
+ new SimpleNamespaceContext(Collections.singletonMap("wadl", "http://wadl.dev.java.net/2009/02")));
final ElementQualifier elementQualifier = new RecursiveElementNameAndTextQualifier();
diff.overrideElementQualifier(elementQualifier);
XMLAssert.assertXMLEqual(diff, true);
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 10a5703..7e79571 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
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
diff --git a/tests/integration/j-376/pom.xml b/tests/integration/j-376/pom.xml
index a6c1535..935cd8f 100644
--- a/tests/integration/j-376/pom.xml
+++ b/tests/integration/j-376/pom.xml
@@ -86,8 +86,6 @@
<dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>grizzly-http-server</artifactId>
- <version>2.3.16</version>
- <scope>compile</scope>
</dependency>
<dependency>
diff --git a/tests/integration/jersey-4003/src/test/java/org/glassfish/jersey/tests/integration/jersey4003/LostResponseTest.java b/tests/integration/jersey-4003/src/test/java/org/glassfish/jersey/tests/integration/jersey4003/LostResponseTest.java
index 710ff81..059e450 100644
--- a/tests/integration/jersey-4003/src/test/java/org/glassfish/jersey/tests/integration/jersey4003/LostResponseTest.java
+++ b/tests/integration/jersey-4003/src/test/java/org/glassfish/jersey/tests/integration/jersey4003/LostResponseTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -59,7 +59,7 @@
HttpUrlConnectorProvider.ConnectionFactory connectionFactory =
Mockito.mock(HttpUrlConnectorProvider.ConnectionFactory.class);
HttpURLConnection connection = Mockito.mock(HttpURLConnection.class);
- Mockito.when(connectionFactory.getConnection(Mockito.any(URL.class))).thenReturn(connection);
+ Mockito.when(connectionFactory.getConnection(Mockito.any(URL.class), Mockito.any())).thenReturn(connection);
OutputStream outputStream = Mockito.mock(OutputStream.class);
Mockito.when(connection.getOutputStream()).thenReturn(outputStream);
diff --git a/tests/integration/jersey-5087/pom.xml b/tests/integration/jersey-5087/pom.xml
new file mode 100644
index 0000000..efbfe3c
--- /dev/null
+++ b/tests/integration/jersey-5087/pom.xml
@@ -0,0 +1,333 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v. 2.0, which is available at
+ http://www.eclipse.org/legal/epl-2.0.
+
+ This Source Code may also be made available under the following Secondary
+ Licenses when the conditions for such availability set forth in the
+ Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ version 2 with the GNU Classpath Exception, which is available at
+ https://www.gnu.org/software/classpath/license.html.
+
+ SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>project</artifactId>
+ <groupId>org.glassfish.jersey.tests.integration</groupId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>jersey-5087</artifactId>
+ <packaging>war</packaging>
+ <name>jersey-tests-integration-jersey-5087</name>
+
+ <description>dependencyConvergence rule check</description>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey</groupId>
+ <artifactId>jersey-bom</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.core</groupId>
+ <artifactId>jersey-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.bundles</groupId>
+ <artifactId>jaxrs-ri</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>jersey-apache-connector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>jersey-apache5-connector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>jersey-helidon-connector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>jersey-grizzly-connector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>jersey-jetty-connector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>jersey-jdk-connector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.connectors</groupId>
+ <artifactId>jersey-netty-connector</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-jetty-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-grizzly2-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-grizzly2-servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-jetty-servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-jdk-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-netty-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-servlet-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-simple-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers.glassfish</groupId>
+ <artifactId>jersey-gf-ejb</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-bean-validation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-entity-filtering</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-metainf-services</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.microprofile</groupId>
+ <artifactId>jersey-mp-config</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-mvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-mvc-bean-validation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-mvc-freemarker</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-mvc-jsp</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-mvc-mustache</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-proxy-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-spring6</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-declarative-linking</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext</groupId>
+ <artifactId>jersey-wadl-doclet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-weld2-se</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-cdi1x</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-cdi1x-transaction</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-cdi1x-validation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-cdi1x-servlet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-cdi1x-ban-custom-hk2-binding</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.cdi</groupId>
+ <artifactId>jersey-cdi-rs-inject</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.rx</groupId>
+ <artifactId>jersey-rx-client-guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.rx</groupId>
+ <artifactId>jersey-rx-client-rxjava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.rx</groupId>
+ <artifactId>jersey-rx-client-rxjava2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.ext.microprofile</groupId>
+ <artifactId>jersey-mp-rest-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-jaxb</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-jackson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-jettison</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-processing</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-json-binding</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-kryo</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-moxy</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-multipart</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.media</groupId>
+ <artifactId>jersey-media-sse</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.security</groupId>
+ <artifactId>oauth1-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.security</groupId>
+ <artifactId>oauth1-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.security</groupId>
+ <artifactId>oauth1-signature</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.security</groupId>
+ <artifactId>oauth2-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.inject</groupId>
+ <artifactId>jersey-hk2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.inject</groupId>
+ <artifactId>jersey-cdi2-se</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework</groupId>
+ <artifactId>jersey-test-framework-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-bundle</artifactId>
+ <type>pom</type>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-external</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-inmemory</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-jdk-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-simple</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-jetty</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework</groupId>
+ <artifactId>jersey-test-framework-util</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip> <!-- do not run any tests here, it's useless,
+ dependencies clash is being tested even before compilation. -->
+ </properties>
+</project>
\ No newline at end of file
diff --git a/tests/integration/jersey-5087/src/main/java/org/glassfish/jersey/tests/integration/jersey5087/Jersey5087.java b/tests/integration/jersey-5087/src/main/java/org/glassfish/jersey/tests/integration/jersey5087/Jersey5087.java
new file mode 100644
index 0000000..05f4d67
--- /dev/null
+++ b/tests/integration/jersey-5087/src/main/java/org/glassfish/jersey/tests/integration/jersey5087/Jersey5087.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.jersey5087;
+
+import org.glassfish.jersey.server.ResourceConfig;
+
+public class Jersey5087 extends ResourceConfig {
+
+ public Jersey5087() {
+ register(Resource5087.class);
+ }
+}
diff --git a/tests/integration/jersey-5087/src/main/java/org/glassfish/jersey/tests/integration/jersey5087/Resource5087.java b/tests/integration/jersey-5087/src/main/java/org/glassfish/jersey/tests/integration/jersey5087/Resource5087.java
new file mode 100644
index 0000000..ce32dc3
--- /dev/null
+++ b/tests/integration/jersey-5087/src/main/java/org/glassfish/jersey/tests/integration/jersey5087/Resource5087.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.jersey5087;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+
+@Path("/")
+public class Resource5087 {
+
+ @GET
+ public String getResource() {
+ return "OK";
+ }
+
+}
diff --git a/tests/integration/jersey-5087/src/test/java/org/glassfish/jersey/tests/integration/jersey5087/Jersey5087Test.java b/tests/integration/jersey-5087/src/test/java/org/glassfish/jersey/tests/integration/jersey5087/Jersey5087Test.java
new file mode 100644
index 0000000..8c1b3be
--- /dev/null
+++ b/tests/integration/jersey-5087/src/test/java/org/glassfish/jersey/tests/integration/jersey5087/Jersey5087Test.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.integration.jersey5087;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.ServerProperties;
+import org.glassfish.jersey.test.DeploymentContext;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.ServletDeploymentContext;
+import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
+import org.glassfish.jersey.test.spi.TestContainerFactory;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.EnumSet;
+
+public class Jersey5087Test extends JerseyTest {
+
+ @Override
+ protected ResourceConfig configure() {
+ return new Jersey5087();
+ }
+
+ @Override
+ protected TestContainerFactory getTestContainerFactory() {
+ return new GrizzlyWebTestContainerFactory();
+ }
+
+ @Override
+ protected DeploymentContext configureDeployment() {
+ return ServletDeploymentContext.newInstance(Jersey5087.class);
+ }
+
+ @Test
+ public void testDependenciesClash() {
+ final String response = target().request().get(String.class);
+ Assert.assertEquals("OK", response);
+ }
+}
diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml
index dc72108..c0289fb 100644
--- a/tests/integration/pom.xml
+++ b/tests/integration/pom.xml
@@ -92,6 +92,7 @@
<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>
@@ -189,6 +190,15 @@
</pluginManagement>
</build>
</profile>
+ <profile>
+ <id>spring6-jdk17</id>
+ <activation>
+ <jdk>[17,)</jdk>
+ </activation>
+ <modules>
+ <module>spring6</module>
+ </modules>
+ </profile>
</profiles>
<build>
diff --git a/tests/osgi/functional/pom.xml b/tests/osgi/functional/pom.xml
index eb31c6b..10fc862 100644
--- a/tests/osgi/functional/pom.xml
+++ b/tests/osgi/functional/pom.xml
@@ -34,6 +34,10 @@
Functional Jersey OSGi tests
</description>
+ <properties>
+ <enforcer.skip>true</enforcer.skip>
+ </properties>
+
<build>
<plugins>
<plugin>