Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge of the current master into jakartified branch #4674

Merged
merged 13 commits into from
Jan 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions bundles/jaxrs-ri/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,21 @@
jakarta.persistence.*;resolution:=optional,
jakarta.validation.*;resolution:=optional;version="[3,4)",
sun.misc.*;resolution:=optional,
jakarta.activation.*;version="!";resolution:=optional,
javax.imageio;resolution:=optional,
javax.imageio.spi;resolution:=optional,
javax.imageio.stream;resolution:=optional,
jakarta.xml.bind;version="!";resolution:=optional,
jakarta.xml.bind.annotation;version="!";resolution:=optional,
jakarta.xml.bind.annotation.adapters;version="!";resolution:=optional,
javax.xml.namespace;resolution:=optional,
javax.xml.parsers;resolution:=optional,
javax.xml.transform;resolution:=optional,
javax.xml.transform.dom;resolution:=optional,
javax.xml.transform.sax;resolution:=optional,
javax.xml.transform.stream;resolution:=optional,
org.w3c.dom;resolution:=optional,
org.xml.sax;resolution:=optional,
${hk2.osgi.version},
*
]]></Import-Package>
Expand Down
7 changes: 7 additions & 0 deletions connectors/jetty-connector/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-jaxb</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,27 @@ public final class ClientProperties {
*/
public static final String USE_ENCODING = "jersey.config.client.useEncoding";

/**
* Ignore a response in an exception thrown by the client API by not forwarding
* it to this service's client. A value of {@code true} indicates that responses
* will be ignored, and only the response status will return to the client. This
* property will normally be specified as a system property; note that system
* properties are only visible if {@link CommonProperties#ALLOW_SYSTEM_PROPERTIES_PROVIDER}
* is set to {@code true}.
* <p>
* The value MUST be an instance convertible to {@link java.lang.Boolean}.
* </p>
* <p>
* The default value is {@code false}.
* </p>
* <p>
* The name of the configuration property is <tt>{@value}</tt>.
* </p>
*
* @see org.glassfish.jersey.CommonProperties#ALLOW_SYSTEM_PROPERTIES_PROVIDER
*/
public static final String IGNORE_EXCEPTION_RESPONSE = "jersey.config.client.ignoreExceptionResponse";

/**
* If {@code true} then disable auto-discovery on the client.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.InjectionManagerSupplier;
import org.glassfish.jersey.internal.util.ExceptionUtils;
import org.glassfish.jersey.internal.util.PropertiesHelper;
import org.glassfish.jersey.internal.PropertiesResolver;
import org.glassfish.jersey.internal.util.collection.LazyValue;
import org.glassfish.jersey.internal.util.collection.Value;
import org.glassfish.jersey.internal.util.collection.Values;
import org.glassfish.jersey.message.MessageBodyWorkers;
import org.glassfish.jersey.message.internal.HeaderUtils;
import org.glassfish.jersey.message.internal.OutboundMessageContext;
Expand All @@ -58,7 +61,8 @@
*
* @author Marek Potociar
*/
public class ClientRequest extends OutboundMessageContext implements ClientRequestContext, HttpHeaders, InjectionManagerSupplier {
public class ClientRequest extends OutboundMessageContext
implements ClientRequestContext, HttpHeaders, InjectionManagerSupplier, PropertiesResolver {

// Request-scoped configuration instance
private final ClientConfig clientConfig;
Expand All @@ -82,6 +86,10 @@ public class ClientRequest extends OutboundMessageContext implements ClientReque
private Iterable<ReaderInterceptor> readerInterceptors;
// do not add user-agent header (if not directly set) to the request.
private boolean ignoreUserAgent;
// lazy PropertiesResolver
private LazyValue<PropertiesResolver> propertiesResolver = Values.lazy(
(Value<PropertiesResolver>) () -> PropertiesResolver.create(getConfiguration(), getPropertiesDelegate())
);

private static final Logger LOGGER = Logger.getLogger(ClientRequest.class.getName());

Expand Down Expand Up @@ -120,65 +128,14 @@ public ClientRequest(final ClientRequest original) {
this.ignoreUserAgent = original.ignoreUserAgent;
}

/**
* Resolve a property value for the specified property {@code name}.
*
* <p>
* The method returns the value of the property registered in the request-specific
* property bag, if available. If no property for the given property name is found
* in the request-specific property bag, the method looks at the properties stored
* in the {@link #getConfiguration() global client-runtime configuration} this request
* belongs to. If there is a value defined in the client-runtime configuration,
* it is returned, otherwise the method returns {@code null} if no such property is
* registered neither in the client runtime nor in the request-specific property bag.
* </p>
*
* @param name property name.
* @param type expected property class type.
* @param <T> property Java type.
* @return resolved property value or {@code null} if no such property is registered.
*/
@Override
public <T> T resolveProperty(final String name, final Class<T> type) {
return resolveProperty(name, null, type);
return propertiesResolver.get().resolveProperty(name, type);
}

/**
* Resolve a property value for the specified property {@code name}.
*
* <p>
* The method returns the value of the property registered in the request-specific
* property bag, if available. If no property for the given property name is found
* in the request-specific property bag, the method looks at the properties stored
* in the {@link #getConfiguration() global client-runtime configuration} this request
* belongs to. If there is a value defined in the client-runtime configuration,
* it is returned, otherwise the method returns {@code defaultValue} if no such property is
* registered neither in the client runtime nor in the request-specific property bag.
* </p>
*
* @param name property name.
* @param defaultValue default value to return if the property is not registered.
* @param <T> property Java type.
* @return resolved property value or {@code defaultValue} if no such property is registered.
*/
@SuppressWarnings("unchecked")
@Override
public <T> T resolveProperty(final String name, final T defaultValue) {
return resolveProperty(name, defaultValue, (Class<T>) defaultValue.getClass());
}

private <T> T resolveProperty(final String name, Object defaultValue, final Class<T> type) {
// Check runtime configuration first
Object result = getConfiguration().getProperty(name);
if (result != null) {
defaultValue = result;
}

// Check request properties next
result = propertiesDelegate.getProperty(name);
if (result == null) {
result = defaultValue;
}

return (result == null) ? null : PropertiesHelper.convertValue(result, type);
return propertiesResolver.get().resolveProperty(name, defaultValue);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ public class JerseyInvocation implements jakarta.ws.rs.client.Invocation {
// Copy request context when invoke or submit methods are invoked.
private final boolean copyRequestContext;

private boolean ignoreResponseException;

private JerseyInvocation(final Builder builder) {
this(builder, false);
}
Expand All @@ -91,6 +93,15 @@ private JerseyInvocation(final Builder builder, final boolean copyRequestContext

this.requestContext = new ClientRequest(builder.requestContext);
this.copyRequestContext = copyRequestContext;

Object value = builder.requestContext.getConfiguration()
.getProperty(ClientProperties.IGNORE_EXCEPTION_RESPONSE);
if (value != null) {
Boolean booleanValue = PropertiesHelper.convertValue(value, Boolean.class);
if (booleanValue != null) {
this.ignoreResponseException = booleanValue;
}
}
}

private enum EntityPresence {
Expand Down Expand Up @@ -875,56 +886,60 @@ public JerseyInvocation property(final String name, final Object value) {
}

private ProcessingException convertToException(final Response response) {
// Use an empty response if ignoring response in exception
final int statusCode = response.getStatus();
final Response finalResponse = ignoreResponseException ? Response.status(statusCode).build() : response;

try {
// Buffer and close entity input stream (if any) to prevent
// leaking connections (see JERSEY-2157).
response.bufferEntity();

final WebApplicationException webAppException;
final int statusCode = response.getStatus();
final Response.Status status = Response.Status.fromStatusCode(statusCode);

if (status == null) {
final Response.Status.Family statusFamily = response.getStatusInfo().getFamily();
webAppException = createExceptionForFamily(response, statusFamily);
final Response.Status.Family statusFamily = finalResponse.getStatusInfo().getFamily();
webAppException = createExceptionForFamily(finalResponse, statusFamily);
} else {
switch (status) {
case BAD_REQUEST:
webAppException = new BadRequestException(response);
webAppException = new BadRequestException(finalResponse);
break;
case UNAUTHORIZED:
webAppException = new NotAuthorizedException(response);
webAppException = new NotAuthorizedException(finalResponse);
break;
case FORBIDDEN:
webAppException = new ForbiddenException(response);
webAppException = new ForbiddenException(finalResponse);
break;
case NOT_FOUND:
webAppException = new NotFoundException(response);
webAppException = new NotFoundException(finalResponse);
break;
case METHOD_NOT_ALLOWED:
webAppException = new NotAllowedException(response);
webAppException = new NotAllowedException(finalResponse);
break;
case NOT_ACCEPTABLE:
webAppException = new NotAcceptableException(response);
webAppException = new NotAcceptableException(finalResponse);
break;
case UNSUPPORTED_MEDIA_TYPE:
webAppException = new NotSupportedException(response);
webAppException = new NotSupportedException(finalResponse);
break;
case INTERNAL_SERVER_ERROR:
webAppException = new InternalServerErrorException(response);
webAppException = new InternalServerErrorException(finalResponse);
break;
case SERVICE_UNAVAILABLE:
webAppException = new ServiceUnavailableException(response);
webAppException = new ServiceUnavailableException(finalResponse);
break;
default:
final Response.Status.Family statusFamily = response.getStatusInfo().getFamily();
webAppException = createExceptionForFamily(response, statusFamily);
final Response.Status.Family statusFamily = finalResponse.getStatusInfo().getFamily();
webAppException = createExceptionForFamily(finalResponse, statusFamily);
}
}

return new ResponseProcessingException(response, webAppException);
return new ResponseProcessingException(finalResponse, webAppException);
} catch (final Throwable t) {
return new ResponseProcessingException(response, LocalizationMessages.RESPONSE_TO_EXCEPTION_CONVERSION_FAILED(), t);
return new ResponseProcessingException(finalResponse,
LocalizationMessages.RESPONSE_TO_EXCEPTION_CONVERSION_FAILED(), t);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ public class HttpUrlConnector implements Connector {

private static final Logger LOGGER = Logger.getLogger(HttpUrlConnector.class.getName());
private static final String ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY = "sun.net.http.allowRestrictedHeaders";
// Avoid multi-thread uses of HttpsURLConnection.getDefaultSSLSocketFactory() because it does not implement a
// proper lazy-initialization. See https://github.com/jersey/jersey/issues/3293
private static final SSLSocketFactory DEFAULT_SSL_SOCKET_FACTORY = HttpsURLConnection.getDefaultSSLSocketFactory();
// The list of restricted headers is extracted from sun.net.www.protocol.http.HttpURLConnection
private static final String[] restrictedHeaders = {
"Access-Control-Request-Headers",
Expand Down Expand Up @@ -302,7 +305,7 @@ protected void secureConnection(final JerseyClient client, final HttpURLConnecti
suc.setHostnameVerifier(verifier);
}

if (HttpsURLConnection.getDefaultSSLSocketFactory() == suc.getSSLSocketFactory()) {
if (DEFAULT_SSL_SOCKET_FACTORY == suc.getSSLSocketFactory()) {
// indicates that the custom socket factory was not set
suc.setSSLSocketFactory(sslSocketFactory.get());
}
Expand Down
18 changes: 17 additions & 1 deletion core-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,21 @@
<!-- Note: When you're changing these properties change them also in bundles/jaxrs-ri/pom.xml. -->
<Import-Package>
sun.misc.*;resolution:=optional,
jakarta.activation.*;version="!",
jakarta.activation.*;version="!";resolution:=optional,
javax.imageio;resolution:=optional,
javax.imageio.spi;resolution:=optional,
javax.imageio.stream;resolution:=optional,
jakarta.xml.bind;version="!";resolution:=optional,
jakarta.xml.bind.annotation;version="!";resolution:=optional,
jakarta.xml.bind.annotation.adapters;version="!";resolution:=optional,
javax.xml.namespace;resolution:=optional,
javax.xml.parsers;resolution:=optional,
javax.xml.transform;resolution:=optional,
javax.xml.transform.dom;resolution:=optional,
javax.xml.transform.sax;resolution:=optional,
javax.xml.transform.stream;resolution:=optional,
org.w3c.dom;resolution:=optional,
org.xml.sax;resolution:=optional,
${jakarta.annotation.osgi.version},
*
</Import-Package>
Expand Down Expand Up @@ -180,6 +194,8 @@
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>jakarta.activation</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,15 @@ public final class CommonProperties {
* Disable some of the default providers from being loaded. The following providers extend application footprint
* by XML dependencies, which is too heavy for native image, or by AWT which may possibly be not available by JDK 11 desktop:
* <ul>
* <li>jakarta.activation.DataSource</li>
* <li>java.awt.image.RenderedImage</li>
* <li>javax.xml.transform.Source</li>
* <li>javax.xml.transform.dom.DOMSource</li>
* <li>javax.xml.transform.sax.SAXSource</li>
* <li>javax.xml.transform.stream.StreamSource</li>
* </ul>
* The following are the options to disable the provides: {@code DOMSOURCE, RENDEREDIMAGE, SAXSOURCE, SOURCE, STREAMSOURCE},
* The following are the options to disable the provides:
* {@code DATASOURCE, DOMSOURCE, RENDEREDIMAGE, SAXSOURCE, SOURCE, STREAMSOURCE},
* or to disable all: {@code ALL}. Multiple options can be disabled by adding multiple comma separated values.
*
* @since 2.30
Expand Down
Loading