[
https://issues.apache.org/jira/browse/CXF-8556?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Andriy Redko resolved CXF-8556.
-------------------------------
Resolution: Fixed
> Null AbstractEndpointFactory Properties Interferes with Class-Level PathParam
> When Creating Proxies with Defined ClientState
> ----------------------------------------------------------------------------------------------------------------------------
>
> Key: CXF-8556
> URL: https://issues.apache.org/jira/browse/CXF-8556
> Project: CXF
> Issue Type: Bug
> Components: JAX-RS
> Affects Versions: 3.4.4, 3.3.11
> Reporter: Noah Rickles
> Assignee: Andriy Redko
> Priority: Major
> Labels: Bug
> Fix For: 3.3.12, 3.4.5, 3.5.0
>
>
> A service in question needs to be reachable via multiple paths. The {{@Path}}
> param allows for regex matching on a class-level like the following:
> {{@Path("/\{a:cat|dog}")}}. The class in which this annotation is used will
> correctly take requests at either {{/cat}} or {{/dog}}. A class-level
> {{@PathParam}} is created by the name of {{a}}.
>
> The issue comes when creating a proxy for this service through the
> {{JAXRSClientFactoryBean.java}} create method shown below:
> {code:java}
> // @param varValues optional list of values which will be used to substitute
> // template variables specified in the class-level JAX-RS
> Path annotations
> public <T> T create(Class<T> cls, Object... varValues)
> { return cls.cast(createWithValues(varValues)); }{code}
> To define the value of the {{@PathParam a}} that this proxy should use, it
> appears as if the {{Object... varValues}} needs to be populated. The
> {{ClientProxyImpl}} is created with the following, after the {{ClientState}}
> is retrieved:
> {code:java}
> protected ClientProxyImpl createClientProxy(ClassResourceInfo cri, boolean
> isRoot,
> ClientState actualState, Object[]
> varValues) {
> if (actualState == null) {
> return new ClientProxyImpl(URI.create(getAddress()), proxyLoader,
> cri, isRoot,
> inheritHeaders, getProperties(), varValues);
> } else {
> return new ClientProxyImpl(actualState, proxyLoader, cri, isRoot,
> inheritHeaders, getProperties(), varValues);
> }
> }
> {code}
> In this scenario, {{actualState}} is defined, and {{getProperties()}} returns
> {{null}}. {{varValues}} is populated with one entry, "dog". The constructor
> for the {{ClientProxyImpl}} in this situation is:
> {code:java}
> public ClientProxyImpl(ClientState initialState,
> ClassLoader loader,
> ClassResourceInfo cri,
> boolean isRoot,
> boolean inheritHeaders,
> Object... varValues) { ... }
> {code}
> The key here is that the result of {{getProperties()}} will be the first
> entry in the {{Object[]}} created by the var args.
> After the {{initValuesMap(Object... varValues)}} is called, I would expect
> the {{valuesMap}} to have one entry, a mapping of "a" to "dog" so that when
> the proxy is used, it will populate the {{@PathParam a}} with "dog"
> automatically. What ends up happening is because the {{null }}{{properties}}
> is being passed as part of the {{Object... varValues}} to the
> {{ClientProxyImpl}} constructor, the {{varValues}} turns into an array of
> [null, "dog"] instead of the expected ["dog"]. The proxy creates successfully
> but does not work because the {{valuesMap}} ends up mapping "a" to {{null}}.
> This breaks the URI builder implementation with an
> {{IllegalArgumentException}}:
> {code:java}
> private URI doBuild(boolean fromEncoded, boolean encodePathSlash, Object...
> values) {
> if (values == null) {
> throw new IllegalArgumentException("Template parameter values are set
> to null");
> }
> for (int i = 0; i < values.length; i++) {
> if (values[i] == null) {
> throw new IllegalArgumentException("Template parameter value at
> position " + i + " is set to null");
> }
> }
> ...
> }
> {code}
>
> This change to the {{createClientProxy}} method was made here:
> [https://github.com/apache/cxf/pull/572|https://github.com/apache/cxf/pull/572.]
> and maybe needs to be addressed.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)