Merge pull request #5079 from senivam/3x_merged
update the 3.x branch with actual master
diff --git a/NOTICE.md b/NOTICE.md
index 0846b57..5533ac7 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -70,10 +70,10 @@
* Project: http://www.javassist.org/
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
-Jackson JAX-RS Providers Version 2.11.3
+Jackson JAX-RS Providers Version 2.13.3
* License: Apache License, 2.0
* Project: https://github.com/FasterXML/jackson-jaxrs-providers
-* Copyright: (c) 2009-2011 FasterXML, LLC. All rights reserved unless otherwise indicated.
+* Copyright: (c) 2009-2022 FasterXML, LLC. All rights reserved unless otherwise indicated.
jQuery v1.12.4
* License: jquery.org/license
@@ -95,7 +95,7 @@
* Project: http://www.kineticjs.com, https://github.com/ericdrowell/KineticJS
* Copyright: Eric Rowell
-org.objectweb.asm Version 9.0
+org.objectweb.asm Version 9.3
* License: Modified BSD (https://asm.ow2.io/license.html)
* Copyright (c) 2000-2011 INRIA, France Telecom. All rights reserved.
diff --git a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/ProxyTest.java b/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/ProxyTest.java
deleted file mode 100644
index baebc78..0000000
--- a/connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/ProxyTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2019 Banco do Brasil S/A. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.jetty.connector;
-
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.glassfish.jersey.client.ClientConfig;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.Test;
-
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.Application;
-import jakarta.ws.rs.core.Response;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.Base64;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author Marcelo Rubim
-\ */
-public class ProxyTest extends JerseyTest {
- private static final Charset CHARACTER_SET = Charset.forName("iso-8859-1");
- private static final String PROXY_URI = "http://127.0.0.1:9997";
- private static final String PROXY_USERNAME = "proxy-user";
- private static final String PROXY_PASSWORD = "proxy-password";
-
-
- @Path("")
- public static class ProxyResource {
-
- @GET
- public Response getProxy() {
- return Response.status(407).header("Proxy-Authenticate", "Basic").build();
- }
-
- }
-
- @Path("proxyTest")
- public static class ProxyTestResource {
-
- @GET
- public Response getOK() {
- return Response.ok().build();
- }
-
- }
-
- @Override
- protected Application configure() {
- ResourceConfig config = new ResourceConfig(ProxyResource.class, ProxyTestResource.class);
- return config;
- }
-
- @Override
- protected void configureClient(ClientConfig config) {
- config.connectorProvider(new JettyConnectorProvider());
- }
-
- @Test
- public void testGet407() {
- startFakeProxy();
- client().property(ClientProperties.PROXY_URI, ProxyTest.PROXY_URI);
- Response response = target("proxyTest").request().get();
- assertEquals(407, response.getStatus());
- }
-
- @Test
- public void testGetSuccess() {
- startFakeProxy();
- client().property(ClientProperties.PROXY_URI, ProxyTest.PROXY_URI);
- 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());
- }
-
- private void startFakeProxy(){
- Server server = new Server(9997);
- server.setHandler(new ProxyHandler());
- try {
- server.start();
- } catch (Exception e) {
-
- }
- }
-
- class ProxyHandler extends AbstractHandler {
- @Override
- public void handle(String target,
- Request baseRequest,
- HttpServletRequest request,
- HttpServletResponse response) throws IOException,
- ServletException {
-
- if (request.getHeader("Proxy-Authorization") != null) {
- String proxyAuthorization = request.getHeader("Proxy-Authorization");
- String decoded = new String(Base64.getDecoder().decode(proxyAuthorization.substring(6).getBytes()),
- CHARACTER_SET);
- final String[] split = decoded.split(":");
- final String username = split[0];
- final String password = split[1];
-
- if (!username.equals(PROXY_USERNAME)) {
- response.setStatus(400);
- System.out.println("Found unexpected username: " + username);
- }
-
- if (!password.equals(PROXY_PASSWORD)) {
- response.setStatus(400);
- System.out.println("Found unexpected password: " + username);
- }
- response.setStatus(200);
- //TODO Add redirect to requestURI
- } else {
- response.setStatus(407);
- response.addHeader("Proxy-Authenticate", "Basic");
- }
-
-
- baseRequest.setHandled(true);
- }
- }
-}
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java
index 176fcb3..71f38ea 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,15 +19,20 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeoutException;
+import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.ClientRequest;
import org.glassfish.jersey.client.ClientResponse;
import org.glassfish.jersey.netty.connector.internal.NettyInputStream;
+import org.glassfish.jersey.netty.connector.internal.RedirectException;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -36,6 +41,7 @@
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpResponse;
+import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.timeout.IdleStateEvent;
@@ -47,21 +53,32 @@
*/
class JerseyClientHandler extends SimpleChannelInboundHandler<HttpObject> {
+ private static final int DEFAULT_MAX_REDIRECTS = 5;
+
+ // Modified only by the same thread. No need to synchronize it.
+ private final Set<URI> redirectUriHistory;
private final ClientRequest jerseyRequest;
private final CompletableFuture<ClientResponse> responseAvailable;
private final CompletableFuture<?> responseDone;
+ private final boolean followRedirects;
+ private final int maxRedirects;
+ private final NettyConnector connector;
private NettyInputStream nis;
private ClientResponse jerseyResponse;
private boolean readTimedOut;
- JerseyClientHandler(ClientRequest request,
- CompletableFuture<ClientResponse> responseAvailable,
- CompletableFuture<?> responseDone) {
+ JerseyClientHandler(ClientRequest request, CompletableFuture<ClientResponse> responseAvailable,
+ CompletableFuture<?> responseDone, Set<URI> redirectUriHistory, NettyConnector connector) {
+ this.redirectUriHistory = redirectUriHistory;
this.jerseyRequest = request;
this.responseAvailable = responseAvailable;
this.responseDone = responseDone;
+ // Follow redirects by default
+ this.followRedirects = jerseyRequest.resolveProperty(ClientProperties.FOLLOW_REDIRECTS, true);
+ this.maxRedirects = jerseyRequest.resolveProperty(NettyClientProperties.MAX_REDIRECTS, DEFAULT_MAX_REDIRECTS);
+ this.connector = connector;
}
@Override
@@ -84,7 +101,41 @@
if (jerseyResponse != null) {
ClientResponse cr = jerseyResponse;
jerseyResponse = null;
- responseAvailable.complete(cr);
+ int responseStatus = cr.getStatus();
+ if (followRedirects
+ && (responseStatus == HttpResponseStatus.MOVED_PERMANENTLY.code()
+ || responseStatus == HttpResponseStatus.FOUND.code()
+ || responseStatus == HttpResponseStatus.SEE_OTHER.code()
+ || responseStatus == HttpResponseStatus.TEMPORARY_REDIRECT.code()
+ || responseStatus == HttpResponseStatus.PERMANENT_REDIRECT.code())) {
+ String location = cr.getHeaderString(HttpHeaders.LOCATION);
+ if (location == null || location.isEmpty()) {
+ responseAvailable.completeExceptionally(new RedirectException(LocalizationMessages.REDIRECT_NO_LOCATION()));
+ } else {
+ try {
+ URI newUri = URI.create(location);
+ boolean alreadyRequested = !redirectUriHistory.add(newUri);
+ if (alreadyRequested) {
+ // infinite loop detection
+ responseAvailable.completeExceptionally(
+ new RedirectException(LocalizationMessages.REDIRECT_INFINITE_LOOP()));
+ } else if (redirectUriHistory.size() > maxRedirects) {
+ // maximal number of redirection
+ responseAvailable.completeExceptionally(
+ new RedirectException(LocalizationMessages.REDIRECT_LIMIT_REACHED(maxRedirects)));
+ } else {
+ ClientRequest newReq = new ClientRequest(jerseyRequest);
+ newReq.setUri(newUri);
+ connector.execute(newReq, redirectUriHistory, responseAvailable);
+ }
+ } catch (IllegalArgumentException e) {
+ responseAvailable.completeExceptionally(
+ new RedirectException(LocalizationMessages.REDIRECT_ERROR_DETERMINING_LOCATION(location)));
+ }
+ }
+ } else {
+ responseAvailable.complete(cr);
+ }
}
}
@@ -92,7 +143,6 @@
public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
if (msg instanceof HttpResponse) {
final HttpResponse response = (HttpResponse) msg;
-
jerseyResponse = new ClientResponse(new Response.StatusType() {
@Override
public int getStatusCode() {
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
index bf34699..671b08f 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
@@ -68,4 +68,18 @@
* @see javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String)
*/
public static final String ENABLE_SSL_HOSTNAME_VERIFICATION = "jersey.config.client.tls.enableHostnameVerification";
+
+ /**
+ * The maximal number of redirects during single request.
+ * <p/>
+ * Value is expected to be positive {@link Integer}. Default value is {@value #DEFAULT_MAX_REDIRECTS}.
+ * <p/>
+ * HTTP redirection must be enabled by property {@link org.glassfish.jersey.client.ClientProperties#FOLLOW_REDIRECTS},
+ * otherwise {@code MAX_REDIRECTS} is not applied.
+ *
+ * @since 2.36
+ * @see org.glassfish.jersey.client.ClientProperties#FOLLOW_REDIRECTS
+ * @see org.glassfish.jersey.netty.connector.internal.RedirectException
+ */
+ public static final String MAX_REDIRECTS = "jersey.config.client.NettyConnectorProvider.maxRedirects";
}
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 3e931f0..77d0d27 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,12 +19,17 @@
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;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService;
@@ -43,6 +48,7 @@
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;
@@ -51,16 +57,20 @@
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
+import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.DefaultHttpRequest;
import io.netty.handler.codec.http.HttpChunkedInput;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpContentDecompressor;
import io.netty.handler.codec.http.HttpHeaderNames;
+import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
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;
import io.netty.handler.ssl.IdentityCipherSuiteFilter;
@@ -151,7 +161,9 @@
@Override
public ClientResponse apply(ClientRequest jerseyRequest) {
try {
- return execute(jerseyRequest).join();
+ CompletableFuture<ClientResponse> response = new CompletableFuture<>();
+ execute(jerseyRequest, new HashSet<>(), response);
+ return response.join();
} catch (CompletionException cex) {
final Throwable t = cex.getCause() == null ? cex : cex.getCause();
throw new ProcessingException(t.getMessage(), t);
@@ -162,19 +174,25 @@
@Override
public Future<?> apply(final ClientRequest jerseyRequest, final AsyncConnectorCallback jerseyCallback) {
- return execute(jerseyRequest).whenCompleteAsync((r, th) -> {
- if (th == null) jerseyCallback.response(r);
- else jerseyCallback.failure(th);
- }, executorService);
+ CompletableFuture<ClientResponse> response = new CompletableFuture<>();
+ response.whenCompleteAsync((r, th) -> {
+ if (th == null) {
+ jerseyCallback.response(r);
+ } else {
+ jerseyCallback.failure(th);
+ }
+ }, executorService);
+ execute(jerseyRequest, new HashSet<>(), response);
+ return response;
}
- protected CompletableFuture<ClientResponse> execute(final ClientRequest jerseyRequest) {
+ protected void execute(final ClientRequest jerseyRequest, final Set<URI> redirectUriHistory,
+ final CompletableFuture<ClientResponse> responseAvailable) {
Integer timeout = jerseyRequest.resolveProperty(ClientProperties.READ_TIMEOUT, 0);
if (timeout == null || timeout < 0) {
throw new ProcessingException(LocalizationMessages.WRONG_READ_TIMEOUT(timeout));
}
- final CompletableFuture<ClientResponse> responseAvailable = new CompletableFuture<>();
final CompletableFuture<?> responseDone = new CompletableFuture<>();
final URI requestUri = jerseyRequest.getUri();
@@ -213,6 +231,8 @@
}
}
+ Integer connectTimeout = jerseyRequest.resolveProperty(ClientProperties.CONNECT_TIMEOUT, 0);
+
if (chan == null) {
Bootstrap b = new Bootstrap();
b.group(group)
@@ -236,8 +256,29 @@
InetSocketAddress proxyAddr = new InetSocketAddress(u.getHost(),
u.getPort() == -1 ? 8080 : u.getPort());
- p.addLast(userName == null ? new HttpProxyHandler(proxyAddr)
- : new HttpProxyHandler(proxyAddr, userName, password));
+ 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;
+ }
+ }
}
// Enable HTTPS if necessary.
@@ -274,7 +315,6 @@
});
// connect timeout
- Integer connectTimeout = jerseyRequest.resolveProperty(ClientProperties.CONNECT_TIMEOUT, 0);
if (connectTimeout > 0) {
b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout);
}
@@ -290,7 +330,8 @@
// assert: it is ok to abort the entire response, if responseDone is completed exceptionally - in particular, nothing
// will leak
final Channel ch = chan;
- JerseyClientHandler clientHandler = new JerseyClientHandler(jerseyRequest, responseAvailable, responseDone);
+ JerseyClientHandler clientHandler =
+ new JerseyClientHandler(jerseyRequest, responseAvailable, responseDone, redirectUriHistory, this);
// read timeout makes sense really as an inactivity timeout
ch.pipeline().addLast(READ_TIMEOUT_HANDLER,
new IdleStateHandler(0, 0, timeout, TimeUnit.MILLISECONDS));
@@ -346,9 +387,7 @@
}
// headers
- for (final Map.Entry<String, List<String>> e : jerseyRequest.getStringHeaders().entrySet()) {
- nettyRequest.headers().add(e.getKey(), e.getValue());
- }
+ setHeaders(jerseyRequest, nettyRequest.headers());
// host header - http 1.1
nettyRequest.headers().add(HttpHeaderNames.HOST, jerseyRequest.getUri().getHost());
@@ -411,8 +450,6 @@
} catch (InterruptedException e) {
responseDone.completeExceptionally(e);
}
-
- return responseAvailable;
}
private String buildPathWithQueryParameters(URI requestUri) {
@@ -475,4 +512,24 @@
}
}
}
+
+ private static ProxyHandler createProxyHandler(ClientRequest jerseyRequest, SocketAddress proxyAddr,
+ String userName, String password, long connectTimeout) {
+ HttpHeaders httpHeaders = setHeaders(jerseyRequest, new DefaultHttpHeaders());
+
+ ProxyHandler proxy = userName == null ? new HttpProxyHandler(proxyAddr, httpHeaders)
+ : new HttpProxyHandler(proxyAddr, userName, password, httpHeaders);
+ if (connectTimeout > 0) {
+ proxy.setConnectTimeoutMillis(connectTimeout);
+ }
+
+ return proxy;
+ }
+
+ private static HttpHeaders setHeaders(ClientRequest jerseyRequest, HttpHeaders headers) {
+ for (final Map.Entry<String, List<String>> e : jerseyRequest.getStringHeaders().entrySet()) {
+ headers.add(e.getKey(), e.getValue());
+ }
+ return headers;
+ }
}
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/internal/RedirectException.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/internal/RedirectException.java
new file mode 100644
index 0000000..bef04e1
--- /dev/null
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/internal/RedirectException.java
@@ -0,0 +1,62 @@
+/*
+ * 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.netty.connector.internal;
+
+import org.glassfish.jersey.client.ClientProperties;
+
+/**
+ * This Exception is used only if {@link ClientProperties#FOLLOW_REDIRECTS} is set to {@code true}.
+ * <p/>
+ * This exception is thrown when any of the Redirect HTTP response status codes (301, 302, 303, 307, 308) is received and:
+ * <ul>
+ * <li>
+ * the chained redirection count exceeds the value of
+ * {@link org.glassfish.jersey.netty.connector.NettyClientProperties#MAX_REDIRECTS}
+ * </li>
+ * <li>
+ * or an infinite redirection loop is detected
+ * </li>
+ * <li>
+ * or Location response header is missing, empty or does not contain a valid {@link java.net.URI}.
+ * </li>
+ * </ul>
+ *
+ */
+public class RedirectException extends Exception {
+
+ private static final long serialVersionUID = 4357724300486801294L;
+
+ /**
+ * Constructor.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public RedirectException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public RedirectException(String message, Throwable t) {
+ super(message, t);
+ }
+}
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 bf12db6..9055d62 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
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
@@ -19,4 +19,7 @@
wrong.max.pool.size=Unexpected ("{0}") maximum number of connections per destination.
wrong.max.pool.total=Unexpected ("{0}") maximum number of connections total.
wrong.max.pool.idle=Unexpected ("{0}") maximum number of idle seconds.
-
+redirect.no.location="Received redirect that does not contain a location or the location is empty."
+redirect.error.determining.location="Error determining redirect location: ({0})."
+redirect.infinite.loop="Infinite loop in chained redirects detected."
+redirect.limit.reached="Max chained redirect limit ({0}) exceeded."
diff --git a/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/FollowRedirectsTest.java b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/FollowRedirectsTest.java
new file mode 100644
index 0000000..6eb2d93
--- /dev/null
+++ b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/FollowRedirectsTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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.netty.connector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.net.URI;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.netty.connector.internal.RedirectException;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+public class FollowRedirectsTest extends JerseyTest {
+
+ private static final Logger LOGGER = Logger.getLogger(FollowRedirectsTest.class.getName());
+ private static final String TEST_URL = "http://localhost:9998/test";
+
+ @Path("/test")
+ public static class RedirectResource {
+ @GET
+ public String get() {
+ return "GET";
+ }
+
+ @GET
+ @Path("redirect")
+ public Response redirect() {
+ return Response.seeOther(URI.create(TEST_URL)).build();
+ }
+
+ @GET
+ @Path("loop")
+ public Response loop() {
+ return Response.seeOther(URI.create(TEST_URL + "/loop")).build();
+ }
+
+ @GET
+ @Path("redirect2")
+ public Response redirect2() {
+ return Response.seeOther(URI.create(TEST_URL + "/redirect")).build();
+ }
+ }
+
+ @Override
+ protected Application configure() {
+ ResourceConfig config = new ResourceConfig(RedirectResource.class);
+ config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+ return config;
+ }
+
+ @Override
+ protected void configureClient(ClientConfig config) {
+ config.property(ClientProperties.FOLLOW_REDIRECTS, false);
+ config.connectorProvider(new NettyConnectorProvider());
+ }
+
+ @Test
+ public void testDoFollow() {
+ final URI u = target().getUri();
+ ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
+ config.connectorProvider(new NettyConnectorProvider());
+ Client c = ClientBuilder.newClient(config);
+ WebTarget t = c.target(u);
+ Response r = t.path("test/redirect")
+ .request().get();
+ assertEquals(200, r.getStatus());
+ assertEquals("GET", r.readEntity(String.class));
+ c.close();
+ }
+
+ @Test
+ public void testDoFollowPerRequestOverride() {
+ WebTarget t = target("test/redirect");
+ t.property(ClientProperties.FOLLOW_REDIRECTS, true);
+ Response r = t.request().get();
+ assertEquals(200, r.getStatus());
+ assertEquals("GET", r.readEntity(String.class));
+ }
+
+ @Test
+ public void testDontFollow() {
+ WebTarget t = target("test/redirect");
+ assertEquals(303, t.request().get().getStatus());
+ }
+
+ @Test
+ public void testDontFollowPerRequestOverride() {
+ final URI u = target().getUri();
+ ClientConfig config = new ClientConfig().property(ClientProperties.FOLLOW_REDIRECTS, true);
+ config.connectorProvider(new NettyConnectorProvider());
+ Client client = ClientBuilder.newClient(config);
+ WebTarget t = client.target(u);
+ t.property(ClientProperties.FOLLOW_REDIRECTS, false);
+ Response r = t.path("test/redirect").request().get();
+ assertEquals(303, r.getStatus());
+ client.close();
+ }
+
+ @Test
+ public void testInfiniteLoop() {
+ WebTarget t = target("test/loop");
+ t.property(ClientProperties.FOLLOW_REDIRECTS, true);
+ try {
+ t.request().get();
+ fail("Expected exception");
+ } catch (ProcessingException e) {
+ assertEquals(RedirectException.class, e.getCause().getClass());
+ assertEquals(LocalizationMessages.REDIRECT_INFINITE_LOOP(), e.getCause().getMessage());
+ }
+ }
+
+ @Test
+ public void testRedirectLimitReached() {
+ WebTarget t = target("test/redirect2");
+ t.property(ClientProperties.FOLLOW_REDIRECTS, true);
+ t.property(NettyClientProperties.MAX_REDIRECTS, 1);
+ try {
+ t.request().get();
+ fail("Expected exception");
+ } catch (ProcessingException e) {
+ assertEquals(RedirectException.class, e.getCause().getClass());
+ assertEquals(LocalizationMessages.REDIRECT_LIMIT_REACHED(1), e.getCause().getMessage());
+ }
+ }
+
+ @Test
+ public void testRedirectNoLimitReached() {
+ WebTarget t = target("test/redirect2");
+ t.property(ClientProperties.FOLLOW_REDIRECTS, true);
+ Response r = t.request().get();
+ assertEquals(200, r.getStatus());
+ assertEquals("GET", r.readEntity(String.class));
+ }
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java b/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java
index 6b2021d..d5a1658 100644
--- a/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java
+++ b/core-common/src/main/java/org/glassfish/jersey/CommonProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -256,6 +256,55 @@
public static final String JAXRS_SERVICE_LOADING_ENABLE = "jakarta.ws.rs.loadServices";
/**
+ * Comma separated list of jackson modules which are only enabled (only those modules will be used)
+ * for json-jackson processing
+ *
+ * @since 2.36
+ */
+ public static final String JSON_JACKSON_ENABLED_MODULES = "jersey.config.json.jackson.enabled.modules";
+
+ /**
+ * Client-specific version of {@link CommonProperties#JSON_JACKSON_ENABLED_MODULES}.
+ *
+ * If present, it overrides the generic one for the client environment.
+ * @since 2.36
+ */
+ public static final String JSON_JACKSON_ENABLED_MODULES_CLIENT = "jersey.config.client.json.jackson.enabled.modules";
+
+ /**
+ * Server-specific version of {@link CommonProperties#JSON_JACKSON_ENABLED_MODULES}.
+ *
+ * If present, it overrides the generic one for the server environment.
+ * @since 2.36
+ */
+ public static final String JSON_JACKSON_ENABLED_MODULES_SERVER = "jersey.config.server.json.jackson.enabled.modules";
+
+ /**
+ * Comma separated list of jackson modules which shall be excluded from json-jackson processing.
+ * the JaxbAnnotationModule is always excluded (cannot be configured).
+ *
+ * @since 2.36
+ */
+
+ public static final String JSON_JACKSON_DISABLED_MODULES = "jersey.config.json.jackson.disabled.modules";
+
+ /**
+ * Client-specific version of {@link CommonProperties#JSON_JACKSON_DISABLED_MODULES}.
+ *
+ * If present, it overrides the generic one for the client environment.
+ * @since 2.36
+ */
+ public static final String JSON_JACKSON_DISABLED_MODULES_CLIENT = "jersey.config.client.json.jackson.disabled.modules";
+
+ /**
+ * Server-specific version of {@link CommonProperties#JSON_JACKSON_DISABLED_MODULES}.
+ *
+ * If present, it overrides the generic one for the client environment.
+ * @since 2.36
+ */
+ public static final String JSON_JACKSON_DISABLED_MODULES_SERVER = "jersey.config.server.json.jackson.disabled.modules";
+
+ /**
* Prevent instantiation.
*/
private CommonProperties() {
@@ -274,7 +323,7 @@
*
* @since 2.8
*/
- public static Object getValue(final Map<String, ?> properties, final String propertyName, final Class<?> type) {
+ public static <T> T getValue(final Map<String, ?> properties, final String propertyName, final Class<T> type) {
return PropertiesHelper.getValue(properties, propertyName, type, CommonProperties.LEGACY_FALLBACK_MAP);
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/logging/ClientLoggingFilter.java b/core-common/src/main/java/org/glassfish/jersey/logging/ClientLoggingFilter.java
index 7a797a0..2b99da6 100644
--- a/core-common/src/main/java/org/glassfish/jersey/logging/ClientLoggingFilter.java
+++ b/core-common/src/main/java/org/glassfish/jersey/logging/ClientLoggingFilter.java
@@ -83,7 +83,7 @@
printRequestLine(b, "Sending client request", id, context.getMethod(), context.getUri());
printPrefixedHeaders(b, id, REQUEST_PREFIX, context.getStringHeaders());
- if (context.hasEntity() && printEntity(verbosity, context.getMediaType())) {
+ if (printEntity(verbosity, context.getMediaType()) && context.hasEntity()) {
final OutputStream stream = new LoggingStream(b, context.getEntityStream());
context.setEntityStream(stream);
context.setProperty(ENTITY_LOGGER_PROPERTY, stream);
@@ -107,7 +107,7 @@
printResponseLine(b, "Client response received", id, responseContext.getStatus());
printPrefixedHeaders(b, id, RESPONSE_PREFIX, responseContext.getHeaders());
- if (responseContext.hasEntity() && printEntity(verbosity, responseContext.getMediaType())) {
+ if (printEntity(verbosity, responseContext.getMediaType()) && responseContext.hasEntity()) {
responseContext.setEntityStream(logInboundEntity(b, responseContext.getEntityStream(),
MessageUtils.getCharset(responseContext.getMediaType())));
}
diff --git a/core-common/src/main/java/org/glassfish/jersey/logging/ServerLoggingFilter.java b/core-common/src/main/java/org/glassfish/jersey/logging/ServerLoggingFilter.java
index 7430859..6ed5dfe 100644
--- a/core-common/src/main/java/org/glassfish/jersey/logging/ServerLoggingFilter.java
+++ b/core-common/src/main/java/org/glassfish/jersey/logging/ServerLoggingFilter.java
@@ -83,7 +83,7 @@
printRequestLine(b, "Server has received a request", id, context.getMethod(), context.getUriInfo().getRequestUri());
printPrefixedHeaders(b, id, REQUEST_PREFIX, context.getHeaders());
- if (context.hasEntity() && printEntity(verbosity, context.getMediaType())) {
+ if (printEntity(verbosity, context.getMediaType()) && context.hasEntity()) {
context.setEntityStream(
logInboundEntity(b, context.getEntityStream(), MessageUtils.getCharset(context.getMediaType())));
}
@@ -105,7 +105,7 @@
printResponseLine(b, "Server responded with a response", id, responseContext.getStatus());
printPrefixedHeaders(b, id, RESPONSE_PREFIX, responseContext.getStringHeaders());
- if (responseContext.hasEntity() && printEntity(verbosity, responseContext.getMediaType())) {
+ if (printEntity(verbosity, responseContext.getMediaType()) && responseContext.hasEntity()) {
final OutputStream stream = new LoggingStream(b, responseContext.getEntityStream());
responseContext.setEntityStream(stream);
requestContext.setProperty(ENTITY_LOGGER_PROPERTY, stream);
diff --git a/core-common/src/test/java/org/glassfish/jersey/logging/HasEntityTimeoutTest.java b/core-common/src/test/java/org/glassfish/jersey/logging/HasEntityTimeoutTest.java
new file mode 100644
index 0000000..3cd15cb
--- /dev/null
+++ b/core-common/src/test/java/org/glassfish/jersey/logging/HasEntityTimeoutTest.java
@@ -0,0 +1,277 @@
+/*
+ * 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.logging;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientResponseContext;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedHashMap;
+import jakarta.ws.rs.core.UriInfo;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+public class HasEntityTimeoutTest {
+
+ private enum DirectionType {
+ INBOUND,
+ OUTBOUND
+ }
+
+ private static class UriInfoHandler implements InvocationHandler {
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ switch (method.getName()) {
+ case "getRequestUri":
+ return URI.create("http://localhost:8080/get");
+ }
+ return null;
+ }
+ }
+
+ private static class RequestResponseHandler implements InvocationHandler {
+ private final DirectionType type;
+
+ private RequestResponseHandler(DirectionType type) {
+ this.type = type;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ switch (method.getName()) {
+ case "hasEntity":
+ throw new ProcessingException(new SocketTimeoutException("Read timed out"));
+ case "getUri":
+ return URI.create("http://localhost:8080");
+ case "getStringHeaders":
+ case "getHeaders":
+ return new MultivaluedHashMap<String, String>();
+ case "getMethod":
+ return "GET";
+ case "getMediaType":
+ return MediaType.SERVER_SENT_EVENTS_TYPE;
+ case "getEntityStream":
+ return type == DirectionType.OUTBOUND
+ ? new ByteArrayOutputStream()
+ : new ByteArrayInputStream("entity".getBytes());
+ case "getStatus":
+ return 200;
+ case "getUriInfo":
+ return Proxy.newProxyInstance(
+ UriInfo.class.getClassLoader(),
+ new Class[]{UriInfo.class},
+ new UriInfoHandler());
+ }
+ return null;
+ }
+ }
+
+ @Test
+ public void testClientFilterTimedOut() throws IOException {
+ ClientLoggingFilter loggingFilter = new ClientLoggingFilter(
+ LoggingFeature.builder()
+ .withLogger(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME))
+ .level(Level.INFO)
+ .verbosity(LoggingFeature.Verbosity.HEADERS_ONLY)
+ .maxEntitySize(10)
+ );
+
+ ClientRequestContext clientRequestContext = (ClientRequestContext) Proxy.newProxyInstance(
+ ClientRequestContext.class.getClassLoader(),
+ new Class[]{ClientRequestContext.class},
+ new RequestResponseHandler(DirectionType.OUTBOUND));
+ loggingFilter.filter(clientRequestContext);
+ }
+
+ @Test
+ public void testClientFilterTimedOutException() throws IOException {
+ ClientLoggingFilter loggingFilter = new ClientLoggingFilter(
+ LoggingFeature.builder()
+ .withLogger(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME))
+ .level(Level.INFO)
+ .verbosity(LoggingFeature.Verbosity.PAYLOAD_ANY)
+ .maxEntitySize(10)
+ );
+
+ ClientRequestContext clientRequestContext = (ClientRequestContext) Proxy.newProxyInstance(
+ ClientRequestContext.class.getClassLoader(),
+ new Class[]{ClientRequestContext.class},
+ new RequestResponseHandler(DirectionType.OUTBOUND));
+ try {
+ loggingFilter.filter(clientRequestContext);
+ throw new RuntimeException("The expected exception has not been thrown");
+ } catch (ProcessingException pe) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testClientFilterResponseTimedOut() throws IOException {
+ ClientLoggingFilter loggingFilter = new ClientLoggingFilter(
+ LoggingFeature.builder()
+ .withLogger(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME))
+ .level(Level.INFO)
+ .verbosity(LoggingFeature.Verbosity.HEADERS_ONLY)
+ .maxEntitySize(10)
+ );
+
+ ClientRequestContext clientRequestContext = (ClientRequestContext) Proxy.newProxyInstance(
+ ClientRequestContext.class.getClassLoader(),
+ new Class[]{ClientRequestContext.class},
+ new RequestResponseHandler(DirectionType.OUTBOUND));
+
+ ClientResponseContext clientResponseContext = (ClientResponseContext) Proxy.newProxyInstance(
+ ClientResponseContext.class.getClassLoader(),
+ new Class[]{ClientResponseContext.class},
+ new RequestResponseHandler(DirectionType.INBOUND));
+ loggingFilter.filter(clientRequestContext, clientResponseContext);
+ }
+
+ @Test
+ public void testClientFilterResponseTimedOutException() throws IOException {
+ ClientLoggingFilter loggingFilter = new ClientLoggingFilter(
+ LoggingFeature.builder()
+ .withLogger(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME))
+ .level(Level.INFO)
+ .verbosity(LoggingFeature.Verbosity.PAYLOAD_ANY)
+ .maxEntitySize(10)
+ );
+
+ ClientRequestContext clientRequestContext = (ClientRequestContext) Proxy.newProxyInstance(
+ ClientRequestContext.class.getClassLoader(),
+ new Class[]{ClientRequestContext.class},
+ new RequestResponseHandler(DirectionType.OUTBOUND));
+
+ ClientResponseContext clientResponseContext = (ClientResponseContext) Proxy.newProxyInstance(
+ ClientResponseContext.class.getClassLoader(),
+ new Class[]{ClientResponseContext.class},
+ new RequestResponseHandler(DirectionType.INBOUND));
+
+ try {
+ loggingFilter.filter(clientRequestContext, clientResponseContext);
+ throw new RuntimeException("The expected exception has not been thrown");
+ } catch (ProcessingException pe) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testServerFilterTimedOut() throws IOException {
+ ServerLoggingFilter loggingFilter = new ServerLoggingFilter(
+ LoggingFeature.builder()
+ .withLogger(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME))
+ .level(Level.INFO)
+ .verbosity(LoggingFeature.Verbosity.HEADERS_ONLY)
+ .maxEntitySize(10)
+ );
+
+ ContainerRequestContext containerRequestContext = (ContainerRequestContext) Proxy.newProxyInstance(
+ ContainerRequestContext.class.getClassLoader(),
+ new Class[]{ContainerRequestContext.class},
+ new RequestResponseHandler(DirectionType.INBOUND));
+ loggingFilter.filter(containerRequestContext);
+ }
+
+ @Test
+ public void testServerFilterTimedOutException() throws IOException {
+ ServerLoggingFilter loggingFilter = new ServerLoggingFilter(
+ LoggingFeature.builder()
+ .withLogger(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME))
+ .level(Level.INFO)
+ .verbosity(LoggingFeature.Verbosity.PAYLOAD_ANY)
+ .maxEntitySize(10)
+ );
+
+ ContainerRequestContext containerRequestContext = (ContainerRequestContext) Proxy.newProxyInstance(
+ ContainerRequestContext.class.getClassLoader(),
+ new Class[]{ContainerRequestContext.class},
+ new RequestResponseHandler(DirectionType.INBOUND));
+
+ try {
+ loggingFilter.filter(containerRequestContext);
+ throw new RuntimeException("The expected exception has not been thrown");
+ } catch (ProcessingException pe) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testServerFilterResponseTimedOut() throws IOException {
+ ServerLoggingFilter loggingFilter = new ServerLoggingFilter(
+ LoggingFeature.builder()
+ .withLogger(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME))
+ .level(Level.INFO)
+ .verbosity(LoggingFeature.Verbosity.HEADERS_ONLY)
+ .maxEntitySize(10)
+ );
+
+ ContainerRequestContext containerRequestContext = (ContainerRequestContext) Proxy.newProxyInstance(
+ ContainerRequestContext.class.getClassLoader(),
+ new Class[]{ContainerRequestContext.class},
+ new RequestResponseHandler(DirectionType.INBOUND));
+
+ ContainerResponseContext containerResponseContext = (ContainerResponseContext) Proxy.newProxyInstance(
+ ContainerResponseContext.class.getClassLoader(),
+ new Class[]{ContainerResponseContext.class},
+ new RequestResponseHandler(DirectionType.OUTBOUND));
+
+ loggingFilter.filter(containerRequestContext, containerResponseContext);
+ }
+
+ @Test
+ public void testServerFilterResponseTimedOutException() throws IOException {
+ ServerLoggingFilter loggingFilter = new ServerLoggingFilter(
+ LoggingFeature.builder()
+ .withLogger(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME))
+ .level(Level.INFO)
+ .verbosity(LoggingFeature.Verbosity.PAYLOAD_ANY)
+ .maxEntitySize(10)
+ );
+
+ ContainerRequestContext containerRequestContext = (ContainerRequestContext) Proxy.newProxyInstance(
+ ContainerRequestContext.class.getClassLoader(),
+ new Class[]{ContainerRequestContext.class},
+ new RequestResponseHandler(DirectionType.INBOUND));
+
+ ContainerResponseContext containerResponseContext = (ContainerResponseContext) Proxy.newProxyInstance(
+ ContainerResponseContext.class.getClassLoader(),
+ new Class[]{ContainerResponseContext.class},
+ new RequestResponseHandler(DirectionType.OUTBOUND));
+
+ try {
+ loggingFilter.filter(containerRequestContext, containerResponseContext);
+ throw new RuntimeException("The expected exception has not been thrown");
+ } catch (ProcessingException pe) {
+ // expected
+ }
+ }
+
+}
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationVisitor.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationVisitor.java
index 8ca2039..0654582 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationVisitor.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/AnnotationVisitor.java
@@ -38,8 +38,8 @@
public abstract class AnnotationVisitor {
/**
- * The ASM API version implemented by this visitor. The value of this field must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ * The ASM API version implemented by this visitor. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
*/
protected final int api;
@@ -52,22 +52,22 @@
/**
* Constructs a new {@link AnnotationVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
*/
- public AnnotationVisitor(final int api) {
+ protected AnnotationVisitor(final int api) {
this(api, null);
}
/**
* Constructs a new {@link AnnotationVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
* @param annotationVisitor the annotation visitor to which this visitor must delegate method
* calls. May be {@literal null}.
*/
- public AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
+ protected AnnotationVisitor(final int api, final AnnotationVisitor annotationVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ByteVector.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ByteVector.java
index 7b386a0..472318f 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ByteVector.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ByteVector.java
@@ -66,6 +66,15 @@
}
/**
+ * Returns the actual number of bytes in this vector.
+ *
+ * @return the actual number of bytes in this vector.
+ */
+ public int size() {
+ return length;
+ }
+
+ /**
* Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary.
*
* @param byteValue a byte.
@@ -352,6 +361,9 @@
* @param size number of additional bytes that this byte vector should be able to receive.
*/
private void enlarge(final int size) {
+ if (length > data.length) {
+ throw new AssertionError("Internal error");
+ }
int doubleCapacity = 2 * data.length;
int minimalCapacity = length + size;
byte[] newData = new byte[doubleCapacity > minimalCapacity ? doubleCapacity : minimalCapacity];
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java
index b0173c8..cd4a6bb 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java
@@ -194,7 +194,7 @@
this.b = classFileBuffer;
// Check the class' major_version. This field is after the magic and minor_version fields, which
// use 4 and 2 bytes respectively.
- if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V18) {
+ if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V19) {
throw new IllegalArgumentException(
"Unsupported class file major version " + readShort(classFileOffset + 6));
}
@@ -308,12 +308,13 @@
* @return the content of the given input stream.
* @throws IOException if a problem occurs during reading.
*/
+ @SuppressWarnings("PMD.UseTryWithResources")
private static byte[] readStream(final InputStream inputStream, final boolean close)
throws IOException {
if (inputStream == null) {
throw new IOException("Class not found");
}
- int bufferSize = calculateBufferSize(inputStream);
+ int bufferSize = computeBufferSize(inputStream);
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] data = new byte[bufferSize];
int bytesRead;
@@ -334,19 +335,19 @@
}
}
- private static int calculateBufferSize(final InputStream inputStream) throws IOException {
+ private static int computeBufferSize(final InputStream inputStream) throws IOException {
int expectedLength = inputStream.available();
/*
- * Some implementations can return 0 while holding available data
- * (e.g. new FileInputStream("/proc/a_file"))
- * Also in some pathological cases a very small number might be returned,
- * and in this case we use default size
+ * Some implementations can return 0 while holding available data (e.g. new
+ * FileInputStream("/proc/a_file")). Also in some pathological cases a very small number might
+ * be returned, and in this case we use a default size.
*/
if (expectedLength < 256) {
return INPUT_STREAM_DATA_CHUNK_SIZE;
}
return Math.min(expectedLength, MAX_BUFFER_SIZE);
}
+
// -----------------------------------------------------------------------------------------------
// Accessors
// -----------------------------------------------------------------------------------------------
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java
index e3a5b60..8ebf594f 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java
@@ -40,8 +40,8 @@
public abstract class ClassVisitor {
/**
- * The ASM API version implemented by this visitor. The value of this field must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ * The ASM API version implemented by this visitor. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
*/
protected final int api;
@@ -51,23 +51,22 @@
/**
* Constructs a new {@link ClassVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
*/
- public ClassVisitor(final int api) {
+ protected ClassVisitor(final int api) {
this(api, null);
}
/**
* Constructs a new {@link ClassVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link
- * Opcodes#ASM8} or {@link Opcodes#ASM9}.
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
* @param classVisitor the class visitor to which this visitor must delegate method calls. May be
* null.
*/
- public ClassVisitor(final int api, final ClassVisitor classVisitor) {
+ protected ClassVisitor(final int api, final ClassVisitor classVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java
index 81176b8..de2c441 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java
@@ -65,6 +65,12 @@
*/
public static final int COMPUTE_FRAMES = 2;
+ /**
+ * The flags passed to the constructor. Must be zero or more of {@link #COMPUTE_MAXS} and {@link
+ * #COMPUTE_FRAMES}.
+ */
+ private final int flags;
+
// Note: fields are ordered as in the ClassFile structure, and those related to attributes are
// ordered as in Section 4.7 of the JVMS.
@@ -248,24 +254,40 @@
* @param classReader the {@link ClassReader} used to read the original class. It will be used to
* copy the entire constant pool and bootstrap methods from the original class and also to
* copy other fragments of original bytecode where applicable.
- * @param flags option flags that can be used to modify the default behavior of this class.Must be
- * zero or more of {@link #COMPUTE_MAXS} and {@link #COMPUTE_FRAMES}. <i>These option flags do
- * not affect methods that are copied as is in the new class. This means that neither the
+ * @param flags option flags that can be used to modify the default behavior of this class. Must
+ * be zero or more of {@link #COMPUTE_MAXS} and {@link #COMPUTE_FRAMES}. <i>These option flags
+ * do not affect methods that are copied as is in the new class. This means that neither the
* maximum stack size nor the stack frames will be computed for these methods</i>.
*/
public ClassWriter(final ClassReader classReader, final int flags) {
super(/* latest api = */ Opcodes.ASM9);
+ this.flags = flags;
symbolTable = classReader == null ? new SymbolTable(this) : new SymbolTable(this, classReader);
if ((flags & COMPUTE_FRAMES) != 0) {
- this.compute = MethodWriter.COMPUTE_ALL_FRAMES;
+ compute = MethodWriter.COMPUTE_ALL_FRAMES;
} else if ((flags & COMPUTE_MAXS) != 0) {
- this.compute = MethodWriter.COMPUTE_MAX_STACK_AND_LOCAL;
+ compute = MethodWriter.COMPUTE_MAX_STACK_AND_LOCAL;
} else {
- this.compute = MethodWriter.COMPUTE_NOTHING;
+ compute = MethodWriter.COMPUTE_NOTHING;
}
}
// -----------------------------------------------------------------------------------------------
+ // Accessors
+ // -----------------------------------------------------------------------------------------------
+
+ /**
+ * Returns true if all the given flags were passed to the constructor.
+ *
+ * @param flags some option flags. Must be zero or more of {@link #COMPUTE_MAXS} and {@link
+ * #COMPUTE_FRAMES}.
+ * @return true if all the given flags, or more, were passed to the constructor.
+ */
+ public boolean hasFlags(final int flags) {
+ return (this.flags & flags) == flags;
+ }
+
+ // -----------------------------------------------------------------------------------------------
// Implementation of the ClassVisitor abstract class
// -----------------------------------------------------------------------------------------------
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldVisitor.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldVisitor.java
index 716d6b0..64865d6 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldVisitor.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/FieldVisitor.java
@@ -37,9 +37,8 @@
public abstract class FieldVisitor {
/**
- * The ASM API version implemented by this visitor. The value of this field must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link
- * Opcodes#ASM8} or {@link Opcodes#ASM9}.
+ * The ASM API version implemented by this visitor. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
*/
protected final int api;
@@ -49,24 +48,22 @@
/**
* Constructs a new {@link FieldVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7}, {@link
- * Opcodes#ASM8} or {@link Opcodes#ASM9}.
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
*/
- public FieldVisitor(final int api) {
+ protected FieldVisitor(final int api) {
this(api, null);
}
/**
* Constructs a new {@link FieldVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link
- * Opcodes#ASM8}.
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
* @param fieldVisitor the field visitor to which this visitor must delegate method calls. May be
* null.
*/
- public FieldVisitor(final int api, final FieldVisitor fieldVisitor) {
+ protected FieldVisitor(final int api, final FieldVisitor fieldVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodVisitor.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodVisitor.java
index 77392c7..805aed5 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodVisitor.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodVisitor.java
@@ -51,8 +51,8 @@
private static final String REQUIRES_ASM5 = "This feature requires ASM5";
/**
- * The ASM API version implemented by this visitor. The value of this field must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ * The ASM API version implemented by this visitor. The value of this field must be one of the
+ * {@code ASM}<i>x</i> values in {@link Opcodes}.
*/
protected final int api;
@@ -64,22 +64,22 @@
/**
* Constructs a new {@link MethodVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
*/
- public MethodVisitor(final int api) {
+ protected MethodVisitor(final int api) {
this(api, null);
}
/**
* Constructs a new {@link MethodVisitor}.
*
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+ * @param api the ASM API version implemented by this visitor. Must be one of the {@code
+ * ASM}<i>x</i> values in {@link Opcodes}.
* @param methodVisitor the method visitor to which this visitor must delegate method calls. May
* be null.
*/
- public MethodVisitor(final int api, final MethodVisitor methodVisitor) {
+ protected MethodVisitor(final int api, final MethodVisitor methodVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
@@ -351,12 +351,12 @@
*
* @param opcode the opcode of the local variable instruction to be visited. This opcode is either
* ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
- * @param var the operand of the instruction to be visited. This operand is the index of a local
- * variable.
+ * @param varIndex the operand of the instruction to be visited. This operand is the index of a
+ * local variable.
*/
- public void visitVarInsn(final int opcode, final int var) {
+ public void visitVarInsn(final int opcode, final int varIndex) {
if (mv != null) {
- mv.visitVarInsn(opcode, var);
+ mv.visitVarInsn(opcode, varIndex);
}
}
@@ -554,12 +554,12 @@
/**
* Visits an IINC instruction.
*
- * @param var index of the local variable to be incremented.
+ * @param varIndex index of the local variable to be incremented.
* @param increment amount to increment the local variable by.
*/
- public void visitIincInsn(final int var, final int increment) {
+ public void visitIincInsn(final int varIndex, final int increment) {
if (mv != null) {
- mv.visitIincInsn(var, increment);
+ mv.visitIincInsn(varIndex, increment);
}
}
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java
index 24f7f61..ea2e4e4 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/MethodWriter.java
@@ -466,7 +466,8 @@
/**
* Indicates what must be computed. Must be one of {@link #COMPUTE_ALL_FRAMES}, {@link
- * #COMPUTE_INSERTED_FRAMES}, {@link #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_NOTHING}.
+ * #COMPUTE_INSERTED_FRAMES}, {@link COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES}, {@link
+ * #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_NOTHING}.
*/
private final int compute;
@@ -904,26 +905,26 @@
}
@Override
- public void visitVarInsn(final int opcode, final int var) {
+ public void visitVarInsn(final int opcode, final int varIndex) {
lastBytecodeOffset = code.length;
// Add the instruction to the bytecode of the method.
- if (var < 4 && opcode != Opcodes.RET) {
+ if (varIndex < 4 && opcode != Opcodes.RET) {
int optimizedOpcode;
if (opcode < Opcodes.ISTORE) {
- optimizedOpcode = Constants.ILOAD_0 + ((opcode - Opcodes.ILOAD) << 2) + var;
+ optimizedOpcode = Constants.ILOAD_0 + ((opcode - Opcodes.ILOAD) << 2) + varIndex;
} else {
- optimizedOpcode = Constants.ISTORE_0 + ((opcode - Opcodes.ISTORE) << 2) + var;
+ optimizedOpcode = Constants.ISTORE_0 + ((opcode - Opcodes.ISTORE) << 2) + varIndex;
}
code.putByte(optimizedOpcode);
- } else if (var >= 256) {
- code.putByte(Constants.WIDE).put12(opcode, var);
+ } else if (varIndex >= 256) {
+ code.putByte(Constants.WIDE).put12(opcode, varIndex);
} else {
- code.put11(opcode, var);
+ code.put11(opcode, varIndex);
}
// If needed, update the maximum stack size and number of locals, and stack map frames.
if (currentBasicBlock != null) {
if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
- currentBasicBlock.frame.execute(opcode, var, null, null);
+ currentBasicBlock.frame.execute(opcode, varIndex, null, null);
} else {
if (opcode == Opcodes.RET) {
// No stack size delta.
@@ -945,9 +946,9 @@
|| opcode == Opcodes.DLOAD
|| opcode == Opcodes.LSTORE
|| opcode == Opcodes.DSTORE) {
- currentMaxLocals = var + 2;
+ currentMaxLocals = varIndex + 2;
} else {
- currentMaxLocals = var + 1;
+ currentMaxLocals = varIndex + 1;
}
if (currentMaxLocals > maxLocals) {
maxLocals = currentMaxLocals;
@@ -1307,21 +1308,21 @@
}
@Override
- public void visitIincInsn(final int var, final int increment) {
+ public void visitIincInsn(final int varIndex, final int increment) {
lastBytecodeOffset = code.length;
// Add the instruction to the bytecode of the method.
- if ((var > 255) || (increment > 127) || (increment < -128)) {
- code.putByte(Constants.WIDE).put12(Opcodes.IINC, var).putShort(increment);
+ if ((varIndex > 255) || (increment > 127) || (increment < -128)) {
+ code.putByte(Constants.WIDE).put12(Opcodes.IINC, varIndex).putShort(increment);
} else {
- code.putByte(Opcodes.IINC).put11(var, increment);
+ code.putByte(Opcodes.IINC).put11(varIndex, increment);
}
// If needed, update the maximum stack size and number of locals, and stack map frames.
if (currentBasicBlock != null
&& (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES)) {
- currentBasicBlock.frame.execute(Opcodes.IINC, var, null, null);
+ currentBasicBlock.frame.execute(Opcodes.IINC, varIndex, null, null);
}
if (compute != COMPUTE_NOTHING) {
- int currentMaxLocals = var + 1;
+ int currentMaxLocals = varIndex + 1;
if (currentMaxLocals > maxLocals) {
maxLocals = currentMaxLocals;
}
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ModuleVisitor.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ModuleVisitor.java
index 0089d06..9667590 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ModuleVisitor.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ModuleVisitor.java
@@ -53,7 +53,7 @@
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
* or {@link Opcodes#ASM7}.
*/
- public ModuleVisitor(final int api) {
+ protected ModuleVisitor(final int api) {
this(api, null);
}
@@ -65,7 +65,7 @@
* @param moduleVisitor the module visitor to which this visitor must delegate method calls. May
* be null.
*/
- public ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) {
+ protected ModuleVisitor(final int api, final ModuleVisitor moduleVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
&& api != Opcodes.ASM7
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java
index 7850f21..0a591ec 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java
@@ -284,6 +284,7 @@
int V16 = 0 << 16 | 60;
int V17 = 0 << 16 | 61;
int V18 = 0 << 16 | 62;
+ int V19 = 0 << 16 | 63;
/**
* Version flag indicating that the class is using 'preview' features.
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/RecordComponentVisitor.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/RecordComponentVisitor.java
index bab13ad..65cf92c 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/RecordComponentVisitor.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/RecordComponentVisitor.java
@@ -53,7 +53,7 @@
* @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM8}
* or {@link Opcodes#ASM9}.
*/
- public RecordComponentVisitor(final int api) {
+ protected RecordComponentVisitor(final int api) {
this(api, null);
}
@@ -64,7 +64,7 @@
* @param recordComponentVisitor the record component visitor to which this visitor must delegate
* method calls. May be null.
*/
- public RecordComponentVisitor(
+ protected RecordComponentVisitor(
final int api, final RecordComponentVisitor recordComponentVisitor) {
if (api != Opcodes.ASM9
&& api != Opcodes.ASM8
diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java
index dbe11cc..ab8687e 100644
--- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java
+++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Type.java
@@ -440,7 +440,7 @@
case '(':
return new Type(METHOD, descriptorBuffer, descriptorBegin, descriptorEnd);
default:
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Invalid descriptor: " + descriptorBuffer);
}
}
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java
index cdb34b1..60fdf20 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.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
@@ -303,7 +303,7 @@
private static class ClassReaderWrapper {
private static final Logger LOGGER = Logger.getLogger(ClassReader.class.getName());
- private static final int WARN_VERSION = Opcodes.V18;
+ private static final int WARN_VERSION = Opcodes.V19;
private static final int INPUT_STREAM_DATA_CHUNK_SIZE = 4096;
private final byte[] b;
diff --git a/core-server/src/main/resources/META-INF/NOTICE.markdown b/core-server/src/main/resources/META-INF/NOTICE.markdown
index c95dd3a..9399ca7 100644
--- a/core-server/src/main/resources/META-INF/NOTICE.markdown
+++ b/core-server/src/main/resources/META-INF/NOTICE.markdown
@@ -36,7 +36,7 @@
* Copyright (c) 2015-2018 Oracle and/or its affiliates. All rights reserved.
* Copyright 2010-2013 Coda Hale and Yammer, Inc.
-org.objectweb.asm Version 9.0
+org.objectweb.asm Version 9.3
* License: Modified BSD (https://asm.ow2.io/license.html)
* Copyright: (c) 2000-2011 INRIA, France Telecom. All rights reserved.
diff --git a/docs/src/main/docbook/appendix-properties.xml b/docs/src/main/docbook/appendix-properties.xml
index a3232c6..9a0c4d6 100644
--- a/docs/src/main/docbook/appendix-properties.xml
+++ b/docs/src/main/docbook/appendix-properties.xml
@@ -148,6 +148,42 @@
</entry>
</row>
<row>
+ <entry>&jersey.common.CommonProperties.JSON_JACKSON_ENABLED_MODULES; /
+ <entry>&jersey.common.CommonProperties.JSON_JACKSON_ENABLED_MODULES_CLIENT; /
+ <entry>&jersey.common.CommonProperties.JSON_JACKSON_ENABLED_MODULES_SERVER;
+ </entry>
+ <entry>
+ <literal>jersey.config.json.jackson.enabled.modules</literal>
+ <literal>jersey.config.client.json.jackson.enabled.modules</literal>
+ <literal>jersey.config.server.json.jackson.enabled.modules</literal>
+ </entry>
+ <entry>
+ Comma separated list of jackson modules which shall be used for json-jackson provider.
+ If set, only those modules will be used for JSON processing.
+
+ Default value is <literal>NULL</literal>
+ @since 2.36
+ </entry>
+ </row>
+ <row>
+ <entry>&jersey.common.CommonProperties.JSON_JACKSON_DISABLED_MODULES; /
+ <entry>&jersey.common.CommonProperties.JSON_JACKSON_DISABLED_MODULES_CLIENT; /
+ <entry>&jersey.common.CommonProperties.JSON_JACKSON_DISABLED_MODULES_SERVER;
+ </entry>
+ <entry>
+ <literal>jersey.config.json.jackson.disabled.modules</literal>
+ <literal>jersey.config.client.json.jackson.disabled.modules</literal>
+ <literal>jersey.config.server.json.jackson.disabled.modules</literal>
+ </entry>
+ <entry>
+ Comma separated list of jackson modules which shall be excluded from json-jackson provider.
+ If set, those modules will be excluded from JSON processing.
+
+ Default value is <literal>NULL</literal>
+ @since 2.36
+ </entry>
+ </row>
+ <row>
<entry>&jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_NAME;
</entry>
<entry>
@@ -1845,6 +1881,18 @@
</para>
</entry>
</row>
+ <row>
+ <entry>&jersey.netty.NettyClientProperties.MAX_REDIRECTS;</entry>
+ <entry><literal>jersey.config.client.NettyConnectorProvider.maxRedirect</literal></entry>
+ <entry>
+ <para>
+ This property determines the maximal number of redirects during single request. Value is expected to be
+ positive number. Default value is 5.
+ HTTP redirection must be enabled by property org.glassfish.jersey.client.ClientProperties.FOLLOW_REDIRECTS
+ otherwise &jersey.netty.NettyClientProperties.MAX_REDIRECTS; is not applied.
+ </para>
+ </entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/docs/src/main/docbook/jersey.ent b/docs/src/main/docbook/jersey.ent
index 800c3f9..2f91101 100644
--- a/docs/src/main/docbook/jersey.ent
+++ b/docs/src/main/docbook/jersey.ent
@@ -396,6 +396,12 @@
<!ENTITY jersey.common.CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_CLIENT "<link xlink:href='&jersey.javadoc.uri.prefix;/CommonProperties.html#OUTBOUND_CONTENT_LENGTH_BUFFER_CLIENT'>CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_CLIENT</link>" >
<!ENTITY jersey.common.CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER "<link xlink:href='&jersey.javadoc.uri.prefix;/CommonProperties.html#OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER'>CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER</link>" >
<!ENTITY jersey.common.CommonProperties.PROVIDER_DEFAULT_DISABLE "<link xlink:href='&jersey.javadoc.uri.prefix;/CommonProperties.html#PROVIDER_DEFAULT_DISABLE'>CommonProperties.PROVIDER_DEFAULT_DISABLE</link>" >
+<!ENTITY jersey.common.CommonProperties.JSON_JACKSON_ENABLED_MODULES "<link xlink:href='&jersey.javadoc.uri.prefix;/CommonProperties.html#JSON_JACKSON_ENABLED_MODULES'>CommonProperties.JSON_JACKSON_ENABLED_MODULES</link>" >
+<!ENTITY jersey.common.CommonProperties.JSON_JACKSON_ENABLED_MODULES_CLIENT "<link xlink:href='&jersey.javadoc.uri.prefix;/CommonProperties.html#JSON_JACKSON_ENABLED_MODULES'>CommonProperties.JSON_JACKSON_ENABLED_MODULES_CLIENT</link>" >
+<!ENTITY jersey.common.CommonProperties.JSON_JACKSON_ENABLED_MODULES_SERVER "<link xlink:href='&jersey.javadoc.uri.prefix;/CommonProperties.html#JSON_JACKSON_ENABLED_MODULES'>CommonProperties.JSON_JACKSON_ENABLED_MODULES_SERVER</link>" >
+<!ENTITY jersey.common.CommonProperties.JSON_JACKSON_DISABLED_MODULES "<link xlink:href='&jersey.javadoc.uri.prefix;/CommonProperties.html#JSON_JACKSON_DISABLED_MODULES'>CommonProperties.JSON_JACKSON_DISABLED_MODULES</link>" >
+<!ENTITY jersey.common.CommonProperties.JSON_JACKSON_DISABLED_MODULES_CLIENT "<link xlink:href='&jersey.javadoc.uri.prefix;/CommonProperties.html#JSON_JACKSON_DISABLED_MODULES'>CommonProperties.JSON_JACKSON_DISABLED_MODULES_CLIENT</link>" >
+<!ENTITY jersey.common.CommonProperties.JSON_JACKSON_DISABLED_MODULES_SERVER "<link xlink:href='&jersey.javadoc.uri.prefix;/CommonProperties.html#JSON_JACKSON_DISABLED_MODULES'>CommonProperties.JSON_JACKSON_DISABLED_MODULES_SERVER</link>" >
<!ENTITY jersey.common.internal.inject.DisposableSupplier "<link xlink:href='&jersey.javadoc.uri.prefix;/internal/inject/DisposableSupplier.html'>DisposableSupplier</link>">
<!ENTITY jersey.common.internal.inject.InjectionManager "<link xlink:href='&jersey.javadoc.uri.prefix;/internal/inject/InjectionManager.html'>InjectionManager</link>">
<!ENTITY jersey.common.internal.inject.AbstractBinder "<link xlink:href='&jersey.javadoc.uri.prefix;/internal/inject/AbstractBinder.html'>AbstractBinder</link>">
@@ -537,6 +543,7 @@
<!ENTITY jersey.netty.NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyClientProperties.html#IDLE_CONNECTION_PRUNE_TIMEOUT'>NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT</link>" >
<!ENTITY jersey.netty.NettyClientProperties.MAX_CONNECTIONS "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyClientProperties.html#MAX_CONNECTIONS'>NettyClientProperties.MAX_CONNECTIONS</link>" >
<!ENTITY jersey.netty.NettyClientProperties.MAX_CONNECTIONS_TOTAL "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyClientProperties.html#MAX_CONNECTIONS_TOTAL'>NettyClientProperties.MAX_CONNECTIONS_TOTAL</link>" >
+<!ENTITY jersey.netty.NettyClientProperties.MAX_REDIRECTS "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyClientProperties.html#MAX_REDIRECTS'>NettyClientProperties.MAX_REDIRECTS</link>" >
<!ENTITY jersey.netty.NettyConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyConnectorProvider.html'>NettyConnectorProvider</link>">
<!ENTITY jersey.server.ApplicationHandler "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ApplicationHandler.html'>ApplicationHandler</link>">
<!ENTITY jersey.server.BackgroundScheduler "<link xlink:href='&jersey.javadoc.uri.prefix;/server/BackgroundScheduler.html'>@BackgroundScheduler</link>">
diff --git a/docs/src/main/docbook/media.xml b/docs/src/main/docbook/media.xml
index 95581df..f830e90 100644
--- a/docs/src/main/docbook/media.xml
+++ b/docs/src/main/docbook/media.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" standalone="no"?>
<!--
- 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
@@ -570,6 +570,15 @@
</para>
<para>
+ Since the 2.36 version of Jersey it is possible to filter (include/exclude) Jackson modules by properties
+ &jersey.common.CommonProperties.JSON_JACKSON_DISABLED_MODULES; and &jersey.common.CommonProperties.JSON_JACKSON_ENABLED_MODULES;
+ (with their client/server derivatives). If the &jersey.common.CommonProperties.JSON_JACKSON_ENABLED_MODULES; property is used,
+ only those named modules will be used for JSON processing. On the other hand if the &jersey.common.CommonProperties.JSON_JACKSON_DISABLED_MODULES;
+ property is used, those listed modules will be explicitly excluded from processing while other (not listed) will remain. Please note that
+ the <literal>JaxbAnnotationModule</literal> module is always excluded from processing and this is not configurable.
+ </para>
+
+ <para>
In order to use Jackson as your JSON (JAXB/POJO) provider you need to register &jersey.media.JacksonFeature;
and a &lit.jaxrs.ext.ContextResolver; for &lit.jersey.media.ObjectMapper;,
if needed, in your &jaxrs.core.Configurable; (client/server).
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProvider.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProvider.java
index f4f0f3f..527f1db 100644
--- a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProvider.java
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/DefaultJacksonJaxbJsonProvider.java
@@ -18,11 +18,16 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.Module;
+import org.glassfish.jersey.CommonProperties;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.cfg.Annotations;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
+import java.util.Arrays;
import java.util.List;
+import jakarta.annotation.PostConstruct;
import jakarta.inject.Singleton;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Context;
/**
* Entity Data provider based on Jackson JSON provider.
@@ -30,32 +35,57 @@
@Singleton
public class DefaultJacksonJaxbJsonProvider extends JacksonJaxbJsonProvider {
+ @Context
+ private Configuration commonConfig;
+
//do not register JaxbAnnotationModule because it brakes default annotations processing
private static final String[] EXCLUDE_MODULE_NAMES = {"JaxbAnnotationModule", "JakartaXmlBindAnnotationModule"};
public DefaultJacksonJaxbJsonProvider() {
super(new JacksonMapperConfigurator(null, DEFAULT_ANNOTATIONS));
- findAndRegisterModules();
}
public DefaultJacksonJaxbJsonProvider(final Annotations... annotationsToUse) {
super(new JacksonMapperConfigurator(null, annotationsToUse));
- findAndRegisterModules();
}
+ @PostConstruct
private void findAndRegisterModules() {
final ObjectMapper defaultMapper = _mapperConfig.getDefaultMapper();
final ObjectMapper mapper = _mapperConfig.getConfiguredMapper();
+ final List<Module> modules = filterModules();
+
+ defaultMapper.registerModules(modules);
+ if (mapper != null) {
+ mapper.registerModules(modules);
+ }
+ }
+
+ private List<Module> filterModules() {
+ final String disabledModules =
+ CommonProperties.getValue(commonConfig.getProperties(),
+ commonConfig.getRuntimeType(),
+ CommonProperties.JSON_JACKSON_DISABLED_MODULES, String.class);
+ final String enabledModules =
+ CommonProperties.getValue(commonConfig.getProperties(),
+ commonConfig.getRuntimeType(),
+ CommonProperties.JSON_JACKSON_ENABLED_MODULES, String.class);
+
final List<Module> modules = ObjectMapper.findModules();
for (String exludeModuleName : EXCLUDE_MODULE_NAMES) {
modules.removeIf(mod -> mod.getModuleName().contains(exludeModuleName));
}
- defaultMapper.registerModules(modules);
- if (mapper != null) {
- mapper.registerModules(modules);
+ if (enabledModules != null && !enabledModules.isEmpty()) {
+ final List<String> enabledModulesList = Arrays.asList(enabledModules.split(","));
+ modules.removeIf(mod -> !enabledModulesList.contains(mod.getModuleName()));
+ } else if (disabledModules != null && !disabledModules.isEmpty()) {
+ final List<String> disabledModulesList = Arrays.asList(disabledModules.split(","));
+ modules.removeIf(mod -> disabledModulesList.contains(mod.getModuleName()));
}
+
+ return modules;
}
}
\ No newline at end of file
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/base/ProviderBase.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/base/ProviderBase.java
index 1127535..b793cb1 100644
--- a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/base/ProviderBase.java
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/base/ProviderBase.java
@@ -12,7 +12,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
@@ -63,7 +62,7 @@
*/
public final static String HEADER_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
- protected final static String CLASS_NAME_NO_CONTENT_EXCEPTION = "javax.ws.rs.core.NoContentException";
+ protected final static String CLASS_NAME_NO_CONTENT_EXCEPTION = "jakarta.ws.rs.core.NoContentException";
private final static String NO_CONTENT_MESSAGE = "No content (empty input stream)";
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/PackageVersion.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/PackageVersion.java
index 9974df6..0389a9c 100644
--- a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/PackageVersion.java
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/PackageVersion.java
@@ -11,7 +11,7 @@
*/
public final class PackageVersion implements Versioned {
public final static Version VERSION = VersionUtil.parseVersion(
- "2.13.0", "com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider");
+ "2.13.3", "com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider");
@Override
public Version version() {
diff --git a/media/json-jackson/src/main/resources/META-INF/NOTICE.markdown b/media/json-jackson/src/main/resources/META-INF/NOTICE.markdown
index c383a09..f35a86b 100644
--- a/media/json-jackson/src/main/resources/META-INF/NOTICE.markdown
+++ b/media/json-jackson/src/main/resources/META-INF/NOTICE.markdown
@@ -31,7 +31,7 @@
## Third-party Content
-Jackson JAX-RS Providers version 2.11.3
+Jackson JAX-RS Providers version 2.13.3
* License: Apache License, 2.0
* Project: https://github.com/FasterXML/jackson-jaxrs-providers
-* Copyright: (c) 2009-2011 FasterXML, LLC. All rights reserved unless otherwise indicated.
\ No newline at end of file
+* Copyright: (c) 2009-2022 FasterXML, LLC. All rights reserved unless otherwise indicated.
diff --git a/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJsonJacksonProviderForBothModulesTest.java b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJsonJacksonProviderForBothModulesTest.java
new file mode 100644
index 0000000..947d599
--- /dev/null
+++ b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJsonJacksonProviderForBothModulesTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.jackson.internal;
+
+import org.glassfish.jersey.jackson.internal.model.ServiceTest;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+import jakarta.ws.rs.core.Application;
+
+import static org.junit.Assert.assertEquals;
+
+public class DefaultJsonJacksonProviderForBothModulesTest extends JerseyTest {
+ @Override
+ protected final Application configure() {
+ return new ResourceConfig(ServiceTest.class)
+ .property("jersey.config.json.jackson.enabled.modules", "Jdk8Module");
+ }
+
+ @Test
+ public final void testDisabledModule() {
+ final String response = target("entity/simple")
+ .request().get(String.class);
+
+ assertEquals("{\"name\":\"Hello\",\"value\":\"World\"}", response);
+ }
+
+}
diff --git a/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJsonJacksonProviderForDisabledModulesTest.java b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJsonJacksonProviderForDisabledModulesTest.java
new file mode 100644
index 0000000..a9a86e6
--- /dev/null
+++ b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJsonJacksonProviderForDisabledModulesTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.jackson.internal;
+
+import org.glassfish.jersey.CommonProperties;
+import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
+import org.glassfish.jersey.jackson.internal.model.JAXBServiceTest;
+import org.glassfish.jersey.jackson.internal.model.ServiceTest;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+import jakarta.annotation.PostConstruct;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Configuration;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+public class DefaultJsonJacksonProviderForDisabledModulesTest extends JerseyTest {
+ @Override
+ protected final Application configure() {
+ return new ResourceConfig(ServiceTest.class, JAXBServiceTest.class)
+ .property("jersey.config.json.jackson.disabled.modules", "Jdk8Module");
+ }
+
+ @Test
+ public final void testDisabledModule() {
+ getClient()
+ .register(JacksonFeature.class)
+ .register(TestJacksonJaxbJsonProvider.class)
+ .property("jersey.config.json.jackson.disabled.modules", "Jdk8Module");
+ final String response = target("JAXBEntity")
+ .request().get(String.class);
+ assertNotEquals("{\"key\":\"key\",\"value\":\"value\"}", response);
+ }
+
+ private static class TestJacksonJaxbJsonProvider extends JacksonJaxbJsonProvider {
+
+ @Inject
+ private Configuration configuration;
+
+ @PostConstruct
+ public void checkModulesCount() {
+ final String disabledModules =
+ CommonProperties.getValue(configuration.getProperties(),
+ configuration.getRuntimeType(),
+ CommonProperties.JSON_JACKSON_DISABLED_MODULES, String.class);
+ assertEquals("Jdk8Module", disabledModules);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJsonJacksonProviderForEnabledModulesTest.java b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJsonJacksonProviderForEnabledModulesTest.java
new file mode 100644
index 0000000..b1d5e9d
--- /dev/null
+++ b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/DefaultJsonJacksonProviderForEnabledModulesTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.jackson.internal;
+
+import org.glassfish.jersey.jackson.internal.model.ServiceTest;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+import jakarta.ws.rs.core.Application;
+
+import static org.junit.Assert.assertNotEquals;
+
+public class DefaultJsonJacksonProviderForEnabledModulesTest extends JerseyTest {
+ @Override
+ protected final Application configure() {
+ return new ResourceConfig(ServiceTest.class)
+ .property("jersey.config.json.jackson.enabled.modules", "jackson-module-kotlin");
+ }
+
+ @Test
+ public final void testDisabledModule() {
+ final String response = target("entity/simple")
+ .request().get(String.class);
+ assertNotEquals("{\"name\":\"Hello\",\"value\":\"World\"}", response);
+ }
+
+}
diff --git a/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/model/JAXBServiceTest.java b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/model/JAXBServiceTest.java
new file mode 100644
index 0000000..ed312a3
--- /dev/null
+++ b/media/json-jackson/src/test/java/org/glassfish/jersey/jackson/internal/model/JAXBServiceTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.jackson.internal.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Optional;
+
+@Path("JAXBEntity")
+public class JAXBServiceTest {
+ @GET
+ @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+ public SimpleEntity get() {
+ return new SimpleEntity("key", "value");
+ }
+
+ @XmlRootElement
+ public static class SimpleEntity {
+ @JsonProperty
+ private String key;
+
+ @JsonProperty
+ private String value;
+
+ public SimpleEntity() {
+ key = "key";
+ value = "value";
+ }
+ public SimpleEntity(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Optional<String> getKey() {
+ return Optional.ofNullable(key);
+ }
+
+ public Optional<String> getValue() {
+ return Optional.ofNullable(value);
+ }
+
+ }
+}
diff --git a/pom.xml b/pom.xml
index 5305302..1d8f553 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2091,7 +2091,7 @@
<jersey.version>${project.version}</jersey.version>
<!-- asm is now source integrated - keeping this property to see the version -->
<!-- see core-server/src/main/java/jersey/repackaged/asm/.. -->
- <asm.version>9.2</asm.version>
+ <asm.version>9.3</asm.version>
<bnd.plugin.version>2.3.6</bnd.plugin.version>
<bouncycastle.version>1.68</bouncycastle.version>
@@ -2125,7 +2125,7 @@
<hk2.config.version>6.0.0</hk2.config.version>
<httpclient.version>4.5.13</httpclient.version>
<httpclient5.version>5.1.2</httpclient5.version>
- <jackson.version>2.13.0</jackson.version>
+ <jackson.version>2.13.3</jackson.version>
<javassist.version>3.25.0-GA</javassist.version>
<jboss.logging.version>3.3.0.Final</jboss.logging.version>
<jersey1.version>1.19.3</jersey1.version>
diff --git a/tests/e2e-client/pom.xml b/tests/e2e-client/pom.xml
index 3890a59..1dce53c 100644
--- a/tests/e2e-client/pom.xml
+++ b/tests/e2e-client/pom.xml
@@ -186,6 +186,34 @@
<profiles>
<profile>
+ <id>JettyTestExclude</id>
+ <activation>
+ <jdk>1.8</jdk>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-testCompile</id>
+ <phase>test-compile</phase>
+ <configuration>
+ <testExcludes>
+ <testExclude>org/glassfish/jersey/tests/e2e/client/connector/proxy/Proxy*Test.java</testExclude>
+ </testExcludes>
+ </configuration>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
<id>jdk11+</id>
<activation>
<jdk>[11,)</jdk>
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
new file mode 100644
index 0000000..1741a66
--- /dev/null
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxySelectorTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 Banco do Brasil S/A. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * 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.client.connector.proxy;
+
+import org.eclipse.jetty.server.HttpChannel;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
+import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.spi.ConnectorProvider;
+import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
+import org.glassfish.jersey.netty.connector.NettyConnectorProvider;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Moved from jetty-connector
+ * @author Marcelo Rubim
+ */
+@RunWith(Parameterized.class)
+public class ProxySelectorTest {
+ private static final String NO_PASS = "no-pass";
+
+ @Parameterized.Parameters(name = "{index}: {0}")
+ public static List<Object[]> testData() {
+ return Arrays.asList(new Object[][]{
+// {ApacheConnectorProvider.class},
+// {Apache5ConnectorProvider.class},
+// {JettyConnectorProvider.class},
+ {NettyConnectorProvider.class},
+ });
+ }
+
+ private final ConnectorProvider connectorProvider;
+
+ public ProxySelectorTest(Class<? extends ConnectorProvider> connectorProviderClass)
+ throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
+ this.connectorProvider = connectorProviderClass.getConstructor().newInstance();
+ }
+
+ protected void configureClient(ClientConfig config) {
+ config.connectorProvider(connectorProvider);
+ }
+
+ @Test
+ public void testGetNoPass() {
+ try (Response response = target("proxyTest").request().header(NO_PASS, 200).get()) {
+ assertEquals(200, response.getStatus());
+ }
+ }
+
+ @Test
+ public void testGet407() {
+ try (Response response = target("proxyTest").request().get()) {
+ assertEquals(407, response.getStatus());
+ } catch (ProcessingException pe) {
+ Assert.assertTrue(pe.getMessage().contains("407")); // netty
+ }
+ }
+
+ private static Server server;
+ @BeforeClass
+ public static void startFakeProxy() {
+ server = new Server(9997);
+ server.setHandler(new ProxyHandler());
+ try {
+ server.start();
+ } catch (Exception e) {
+
+ }
+
+ System.setProperty("http.proxyHost", "http://localhost");
+ System.setProperty("http.proxyPort", "9997");
+ }
+
+ @AfterClass
+ public static void tearDownProxy() {
+ try {
+ server.stop();
+ } catch (Exception e) {
+
+ } finally {
+ System.clearProperty("http.proxyHost");
+ System.clearProperty("http.proxyPort");
+ }
+ }
+
+ private static Client client;
+ @Before
+ public void beforeEach() {
+ ClientConfig config = new ClientConfig();
+ this.configureClient(config);
+ client = ClientBuilder.newClient(config);
+ }
+
+ private Client client() {
+ return client;
+ }
+
+ private WebTarget target(String path) {
+ // ProxySelector goes DIRECT to localhost, no matter the proxy
+ return client().target("http://eclipse.org:9998").path(path);
+ }
+
+ static class ProxyHandler extends AbstractHandler {
+ Set<HttpChannel> httpConnect = new HashSet<>();
+ @Override
+ public void handle(String target,
+ Request baseRequest,
+ HttpServletRequest request,
+ HttpServletResponse response) {
+ if (request.getHeader(NO_PASS) != null) {
+ response.setStatus(Integer.parseInt(request.getHeader(NO_PASS)));
+ } else {
+ response.setStatus(407);
+ response.addHeader("Proxy-Authenticate", "Basic");
+ }
+
+ baseRequest.setHandled(true);
+ }
+ }
+}
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java
new file mode 100644
index 0000000..1ae437b
--- /dev/null
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/proxy/ProxyTest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 Banco do Brasil S/A. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * 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.client.connector.proxy;
+
+import org.eclipse.jetty.server.HttpChannel;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
+import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.spi.ConnectorProvider;
+import org.glassfish.jersey.jetty.connector.JettyConnectorProvider;
+import org.glassfish.jersey.netty.connector.NettyConnectorProvider;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Moved from jetty-connector
+ * @author Marcelo Rubim
+ */
+@RunWith(Parameterized.class)
+public class ProxyTest {
+ private static final Charset CHARACTER_SET = Charset.forName("iso-8859-1");
+ private static final String PROXY_URI = "http://127.0.0.1:9997";
+ private static final String PROXY_USERNAME = "proxy-user";
+ private static final String PROXY_PASSWORD = "proxy-password";
+ private static final String NO_PASS = "no-pass";
+
+ @Parameterized.Parameters(name = "{index}: {0}")
+ public static List<Object[]> testData() {
+ return Arrays.asList(new Object[][]{
+ {ApacheConnectorProvider.class},
+ {Apache5ConnectorProvider.class},
+ {JettyConnectorProvider.class},
+ {NettyConnectorProvider.class},
+ });
+ }
+
+ private final ConnectorProvider connectorProvider;
+
+ public ProxyTest(Class<? extends ConnectorProvider> connectorProviderClass)
+ throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
+ this.connectorProvider = connectorProviderClass.getConstructor().newInstance();
+ }
+
+ protected void configureClient(ClientConfig config) {
+ config.connectorProvider(connectorProvider);
+ }
+
+ @Test
+ public void testGetNoPass() {
+ client().property(ClientProperties.PROXY_URI, ProxyTest.PROXY_URI);
+ try (Response response = target("proxyTest").request().header(NO_PASS, 200).get()) {
+ assertEquals(200, response.getStatus());
+ }
+ }
+
+ @Test
+ public void testGet407() {
+ client().property(ClientProperties.PROXY_URI, ProxyTest.PROXY_URI);
+ try (Response response = target("proxyTest").request().get()) {
+ assertEquals(407, response.getStatus());
+ } catch (ProcessingException pe) {
+ Assert.assertTrue(pe.getMessage().contains("407")); // netty
+ }
+ }
+
+ @Test
+ public void testGetSuccess() {
+ client().property(ClientProperties.PROXY_URI, ProxyTest.PROXY_URI);
+ 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());
+ }
+
+ private static Server server;
+ @BeforeClass
+ public static void startFakeProxy() {
+ server = new Server(9997);
+ server.setHandler(new ProxyHandler());
+ try {
+ server.start();
+ } catch (Exception e) {
+
+ }
+ }
+
+ @AfterClass
+ public static void tearDownProxy() {
+ try {
+ server.stop();
+ } catch (Exception e) {
+
+ }
+ }
+
+ private static Client client;
+ @Before
+ public void beforeEach() {
+ ClientConfig config = new ClientConfig();
+ this.configureClient(config);
+ client = ClientBuilder.newClient(config);
+ }
+
+ private Client client() {
+ return client;
+ }
+
+ private WebTarget target(String path) {
+ return client().target("http://localhost:9998").path(path);
+ }
+
+ static class ProxyHandler extends AbstractHandler {
+ Set<HttpChannel> httpConnect = new HashSet<>();
+ @Override
+ public void handle(String target,
+ Request baseRequest,
+ HttpServletRequest request,
+ HttpServletResponse response) {
+ if (request.getHeader(NO_PASS) != null) {
+ response.setStatus(Integer.parseInt(request.getHeader(NO_PASS)));
+ } else if (request.getHeader("Proxy-Authorization") != null) {
+ String proxyAuthorization = request.getHeader("Proxy-Authorization");
+ String decoded = new String(Base64.getDecoder().decode(proxyAuthorization.substring(6).getBytes()),
+ CHARACTER_SET);
+ final String[] split = decoded.split(":");
+ final String username = split[0];
+ final String password = split[1];
+
+ if (!username.equals(PROXY_USERNAME)) {
+ response.setStatus(400);
+ System.out.println("Found unexpected username: " + username);
+ }
+
+ if (!password.equals(PROXY_PASSWORD)) {
+ response.setStatus(400);
+ System.out.println("Found unexpected password: " + username);
+ }
+
+ if (response.getStatus() != 400) {
+ response.setStatus(200);
+ if ("CONNECT".equalsIgnoreCase(baseRequest.getMethod())) { // NETTY way of doing proxy
+ httpConnect.add(baseRequest.getHttpChannel());
+ }
+ }
+ //TODO Add redirect to requestURI
+ } else {
+ if (httpConnect.contains(baseRequest.getHttpChannel())) {
+ response.setStatus(200);
+ } else {
+ response.setStatus(407);
+ response.addHeader("Proxy-Authenticate", "Basic");
+ }
+ }
+
+ baseRequest.setHandled(true);
+ }
+ }
+}
diff --git a/tests/integration/servlet-2.5-reload/pom.xml b/tests/integration/servlet-2.5-reload/pom.xml
index 32d8cf6..dbafe7f 100644
--- a/tests/integration/servlet-2.5-reload/pom.xml
+++ b/tests/integration/servlet-2.5-reload/pom.xml
@@ -55,10 +55,10 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
- <plugin>
+ <!-- TODO: fix after 2.36 <plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
- </plugin>
+ </plugin>-->
</plugins>
</build>
diff --git a/tests/integration/servlet-2.5-reload/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_config_reload/ReloadTestIT.java b/tests/integration/servlet-2.5-reload/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_config_reload/ReloadTestIT.java
index 313a319..bc57a0e 100644
--- a/tests/integration/servlet-2.5-reload/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_config_reload/ReloadTestIT.java
+++ b/tests/integration/servlet-2.5-reload/src/test/java/org/glassfish/jersey/tests/integration/servlet_25_config_reload/ReloadTestIT.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -24,6 +24,7 @@
import org.glassfish.jersey.test.spi.TestContainerException;
import org.glassfish.jersey.test.spi.TestContainerFactory;
+import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@@ -44,6 +45,7 @@
}
@Test
+ @Ignore //TODO - fix after 2.36
public void testReload() throws Exception {
Response response = target().path("helloworld").request().get();
assertEquals(200, response.getStatus());