Skip to content

Commit

Permalink
Prevent NoSuchMethodError when used MP Rest Client 1.4 API & CDI (#4835)
Browse files Browse the repository at this point in the history
Signed-off-by: jansupol <[email protected]>
  • Loading branch information
jansupol committed Aug 12, 2021
1 parent 1ec382f commit 4920736
Show file tree
Hide file tree
Showing 13 changed files with 420 additions and 43 deletions.
5 changes: 5 additions & 0 deletions ext/microprofile/mp-rest-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@

<build>
<plugins>
<plugin>
<groupId>com.sun.istack</groupId>
<artifactId>istack-commons-maven-plugin</artifactId>
<inherited>true</inherited>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,13 @@
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ParamConverterProvider;

import org.eclipse.microprofile.rest.client.RestClientDefinitionException;
import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam;
import org.eclipse.microprofile.rest.client.annotation.RegisterClientHeaders;
import org.eclipse.microprofile.rest.client.ext.AsyncInvocationInterceptor;
import org.eclipse.microprofile.rest.client.ext.AsyncInvocationInterceptorFactory;
import org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory;
import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;
import org.glassfish.jersey.client.inject.ParameterUpdater;
import org.glassfish.jersey.client.inject.ParameterUpdaterProvider;
import org.glassfish.jersey.internal.inject.InjectionManager;
import org.glassfish.jersey.internal.inject.Providers;
import org.glassfish.jersey.model.Parameter;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -16,8 +16,6 @@

package org.glassfish.jersey.microprofile.restclient;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.HashSet;
import java.util.Set;

Expand All @@ -26,20 +24,12 @@
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.DeploymentException;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.ProcessInjectionPoint;
import javax.enterprise.inject.spi.WithAnnotations;
import javax.enterprise.util.AnnotationLiteral;
import javax.inject.Qualifier;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* Filters out all interfaces annotated with {@link RegisterRestClient}
* and creates new Producer from each of these selected interfaces.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,9 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.enterprise.inject.spi.BeanManager;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.ext.ParamConverterProvider;

import org.eclipse.microprofile.rest.client.ext.AsyncInvocationInterceptorFactory;
import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;
import org.glassfish.jersey.internal.inject.InjectionManager;

/**
* Model of the rest client interface.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.eclipse.microprofile.rest.client.ext.QueryParamStyle;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.glassfish.jersey.internal.util.ReflectionHelper;
Expand Down Expand Up @@ -139,26 +138,11 @@ public Object create(CreationalContext<Object> creationalContext) {
getConfigOption(Long.class, CONFIG_READ_TIMEOUT)
.ifPresent(aLong -> restClientBuilder.readTimeout(aLong, TimeUnit.MILLISECONDS));
getConfigOption(Boolean.class, CONFIG_FOLLOW_REDIRECTS)
.ifPresent(restClientBuilder::followRedirects);
.ifPresent(follow -> VersionSupport.followRedirects(restClientBuilder, follow));
getConfigOption(String.class, CONFIG_QUERY_PARAM_STYLE)
.ifPresent(value -> restClientBuilder.queryParamStyle(QueryParamStyle.valueOf(value)));
.ifPresent(value -> VersionSupport.queryParamStyle(restClientBuilder, value));
getConfigOption(String.class, CONFIG_PROXY_ADDRESS)
.ifPresent(proxy -> {
int index = proxy.lastIndexOf(':');
//If : was not found at all or it is the last character of the proxy string
if (index < 0 || proxy.length() - 1 == index) {
throw new IllegalArgumentException("Invalid proxy URI: " + proxy);
}
String proxyHost = proxy.substring(0, index);
int proxyPort;
String proxyPortStr = proxy.substring(index + 1);
try {
proxyPort = Integer.parseInt(proxyPortStr);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("Invalid proxy port: " + proxyPortStr, nfe);
}
restClientBuilder.proxyAddress(proxyHost, proxyPort);
});
.ifPresent(proxy -> VersionSupport.proxyAddress(restClientBuilder, proxy));

// Providers from configuration
addConfiguredProviders(restClientBuilder);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.microprofile.restclient;

import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.glassfish.jersey.microprofile.restclient.internal.LocalizationMessages;
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 java.util.logging.Logger;

/**
* Backward compatibility support not to throw an exception when an old API is used.
*/
abstract class VersionSupport {

protected abstract RestClientBuilder _followRedirects(RestClientBuilder restClientBuilder, boolean follow);
protected abstract RestClientBuilder _proxyAddress(RestClientBuilder restClientBuilder, String proxy);
protected abstract RestClientBuilder _queryParamStyle(RestClientBuilder restClientBuilder, String style);

private static final Logger logger = Logger.getLogger(VersionSupport.class.getName());

// determine the version only once per jvm
private static LazyValue<VersionSupport> currentVersion = Values.lazy((Value<VersionSupport>) () -> {
final Class<?> restClientBuilderClass = RestClientBuilder.class;
try {
if (null != restClientBuilderClass.getMethod("followRedirects", boolean.class)) {
return new Version20Support();
}
} catch (NoSuchMethodException e) {
// VERSION 1.4
}
return new Version14Support();
});

static RestClientBuilder followRedirects(RestClientBuilder restClientBuilder, boolean follow) {
return currentVersion.get()._followRedirects(restClientBuilder, follow);
}

static RestClientBuilder proxyAddress(RestClientBuilder restClientBuilder, String proxy) {
return currentVersion.get()._proxyAddress(restClientBuilder, proxy);
}

static RestClientBuilder queryParamStyle(RestClientBuilder restClientBuilder, String style) {
return currentVersion.get()._queryParamStyle(restClientBuilder, style);
}

private static class Version14Support extends VersionSupport {
protected RestClientBuilder _followRedirects(RestClientBuilder restClientBuilder, boolean follow) {
logger.warning(LocalizationMessages.WARN_VERSION_14_FOLLOWREDIRECT());
return restClientBuilder;
}

protected RestClientBuilder _proxyAddress(RestClientBuilder restClientBuilder, String proxy) {
logger.warning(LocalizationMessages.WARN_VERSION_14_PROXY());
return restClientBuilder;
}

protected RestClientBuilder _queryParamStyle(RestClientBuilder restClientBuilder, String style) {
logger.warning(LocalizationMessages.WARN_VERSION_14_QUERYPARAMSTYLE());
return restClientBuilder;
}
}

private static class Version20Support extends VersionSupport {
protected RestClientBuilder _followRedirects(RestClientBuilder restClientBuilder, boolean follow) {
return restClientBuilder.followRedirects(follow);
}

protected RestClientBuilder _proxyAddress(RestClientBuilder restClientBuilder, String proxy) {
int index = proxy.lastIndexOf(':');
//If : was not found at all or it is the last character of the proxy string
if (index < 0 || proxy.length() - 1 == index) {
throw new IllegalArgumentException(LocalizationMessages.ERR_INVALID_PROXY_URI(proxy));
}
String proxyHost = proxy.substring(0, index);
int proxyPort;
String proxyPortStr = proxy.substring(index + 1);
try {
proxyPort = Integer.parseInt(proxyPortStr);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException(LocalizationMessages.ERR_INVALID_PROXY_PORT(proxyPortStr), nfe);
}
return restClientBuilder.proxyAddress(proxyHost, proxyPort);
}

protected RestClientBuilder _queryParamStyle(RestClientBuilder restClientBuilder, String style) {
// do not import for compatibility with 1.4
org.eclipse.microprofile.rest.client.ext.QueryParamStyle queryParamStyle =
org.eclipse.microprofile.rest.client.ext.QueryParamStyle.valueOf(style);
return restClientBuilder.queryParamStyle(queryParamStyle);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#
# Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# This Source Code may also be made available under the following Secondary
# Licenses when the conditions for such availability set forth in the
# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
# version 2 with the GNU Classpath Exception, which is available at
# https://www.gnu.org/software/classpath/license.html.
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
#

err.invalid.proxy.uri=Invalid proxy URI: {0}.
err.invalid.proxy.port=Invalid proxy port: {0}.
warn.version14.followredirect=MP Rest Client Version 1.4 does not support RestClientBuilder#followRedirect and it is ignored.
warn.version14.proxy=MP Rest Client Version 1.4 does not support RestClientBuilder#proxy and it is ignored.
warn.version14.queryparamstyle=MP Rest Client Version 1.4 does not support RestClientBuilder#queryParamStyle and it is ignored.

1 change: 1 addition & 0 deletions tests/integration/cdi-integration/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
<module>cdi-multimodule</module>
<module>cdi-multipart-webapp</module>
<module>cdi-resource-with-at-context</module>
<module>cdi-singleton</module>
<module>cdi-test-webapp</module>
<module>cdi-with-jersey-injection-custom-cfg-webapp</module>
<module>cdi-with-jersey-injection-custom-hk2-banned-webapp</module>
Expand Down
1 change: 1 addition & 0 deletions tests/integration/microprofile/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<modules>
<module>config</module>
<module>rest-client</module>
<module>rest-client14-compatibility</module>
</modules>

<build>
Expand Down
115 changes: 115 additions & 0 deletions tests/integration/microprofile/rest-client14-compatibility/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
http://www.eclipse.org/legal/epl-2.0.
This Source Code may also be made available under the following Secondary
Licenses when the conditions for such availability set forth in the
Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
version 2 with the GNU Classpath Exception, which is available at
https://www.gnu.org/software/classpath/license.html.
SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>microprofile-integration-project</artifactId>
<groupId>org.glassfish.jersey.tests.integration.microprofile</groupId>
<version>2.35-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>jersey-rest-client14-compatibility</artifactId>

<dependencies>
<dependency>
<groupId>org.glassfish.jersey.ext.microprofile</groupId>
<artifactId>jersey-mp-rest-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
</exclusion>
<exclusion>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.microprofile.rest.client</groupId>
<artifactId>microprofile-rest-client-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Overrides CDI from parent pom -->
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.rest.client</groupId>
<artifactId>microprofile-rest-client-api</artifactId>
<!-- specifically this version we check with the backward compatibility -->
<version>1.4.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
<artifactId>jersey-weld2-se</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
<artifactId>jersey-cdi1x</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config</artifactId>
<version>1.8.4</version> <!-- Workswith CQ 22471 -->
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-bundle</artifactId>
<type>pom</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext.cdi</groupId>
<artifactId>jersey-weld2-se</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Loading

0 comments on commit 4920736

Please sign in to comment.