Noah Rickles created CXF-8556:
---------------------------------

             Summary: 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
            Reporter: Noah Rickles


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:

```

* @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));
}

```

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 
`ClientProxy` will be created with the following, after the `ClientState` is 
retrieved:

```

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);
    }
}

```

In this scenario, `actualState` is defined, and `getProperties()` returns 
`null`. `varValues` is populated with `\{"dog"}`. The constructor for the 
`ClientProxyImpl` in this situation is:

```

public ClientProxyImpl(ClientState initialState,
 ClassLoader loader,
 ClassResourceInfo cri,
 boolean isRoot,
 boolean inheritHeaders,
 Object... varValues) \{ ... }

```

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`:

```

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");
 }
 }

...
}

 

A change to the `createClientProxy` method was made here: 
[https://github.com/apache/cxf/pull/572|https://github.com/apache/cxf/pull/572.]
 and needs to be addressed.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to