[
https://issues.apache.org/jira/browse/CXF-7330?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Roni Frantchi updated CXF-7330:
-------------------------------
Description:
When having a mapper such as:
{code}
class FaultInfoMapper<T extends Throwable & SomeOtherInterface> implements
ExceptionMapper<T> {
@Override
public Response toResponse(T exception) {
exception.methodOfSomeOtherInterface();
...
}
}
{code}
Expected behavior: the above mapper will pick up only those exceptions which
have are Throwable AND implement SomeOtherInterface.
Actual behavior: The above will be selected to handle any and all exceptions.
Which causes the code above to fail on ClassCastException.
The reason seems to be that
org.apache.cxf.jaxrs.provider.ProviderFactory.handleMapper iterates and selects
the mapper which has at least one bound type that matches:
{code}
for (int j = 0; j < bounds.length; j++) {
Class<?> cls = InjectionUtils.getRawType(bounds[j]);
if (cls != null && (cls == Object.class ||
cls.isAssignableFrom(expectedType))) {
isResolved = true;
break;
}
}
{code}
when it should actually select the one which has ALL bound types match.
Workaround: If using Java 8, one could use an interface instead of a class and
return a bean with that class:
{code}
interface FaultInfoMapper<T extends Throwable & SomeOtherInterface> extends
ExceptionMapper<T> {
@Override
default Response toResponse(T exception) {
exception.methodOfSomeOtherInterface();
...
}
}
// when using Spring:
@Bean
public FaultInfoMapper<MyAppException> myAppExceptionMapper() {
return new FaultInfoMapper<BdmsAppException>() {};
}
{code}
was:
When having a mapper such as:
{code}
class FaultInfoMapper<T extends Throwable & SomeOtherInterface> implements
ExceptionMapper<T> {
@Override
public Response toResponse(T exception) {
exception.methodOfSomeOtherInterface();
...
}
}
{code}
Expected behavior: the above mapper will pick up only those exceptions which
have are Throwable AND implement SomeOtherInterface.
Actual behavior: The above will be selected to handle any and all exceptions.
Which causes the code above to fail on ClassCastException.
The reason seems to be that
org.apache.cxf.jaxrs.provider.ProviderFactory.handleMapper iterates and selects
the mapper which has at least one bound type that matches:
{code}
for (int j = 0; j < bounds.length; j++) {
Class<?> cls = InjectionUtils.getRawType(bounds[j]);
if (cls != null && (cls == Object.class ||
cls.isAssignableFrom(expectedType))) {
isResolved = true;
break;
}
}
{code}
when it should actually select the one which has ALL bound types match.
Workaround: If using Java 8, one could use an interface instead of a class and
return a bean with that class:
{code}
interface FaultInfoMapper<T extends Throwable & SomeOtherInterface> extends
ExceptionMapper<T> {
@Override
public Response toResponse(T exception) {
exception.methodOfSomeOtherInterface();
...
}
}
// when using Spring:
@Bean
public FaultInfoMapper<MyAppException> myAppExceptionMapper() {
return new FaultInfoMapper<BdmsAppException>() {};
}
{code}
> org.apache.cxf.jaxrs.provider.ProviderFactory.handleMapper fails when using
> multiply bounded types
> --------------------------------------------------------------------------------------------------
>
> Key: CXF-7330
> URL: https://issues.apache.org/jira/browse/CXF-7330
> Project: CXF
> Issue Type: Bug
> Affects Versions: 3.1.4
> Reporter: Roni Frantchi
>
> When having a mapper such as:
> {code}
> class FaultInfoMapper<T extends Throwable & SomeOtherInterface> implements
> ExceptionMapper<T> {
> @Override
> public Response toResponse(T exception) {
> exception.methodOfSomeOtherInterface();
> ...
> }
> }
> {code}
> Expected behavior: the above mapper will pick up only those exceptions which
> have are Throwable AND implement SomeOtherInterface.
> Actual behavior: The above will be selected to handle any and all exceptions.
> Which causes the code above to fail on ClassCastException.
> The reason seems to be that
> org.apache.cxf.jaxrs.provider.ProviderFactory.handleMapper iterates and
> selects the mapper which has at least one bound type that matches:
> {code}
> for (int j = 0; j < bounds.length; j++) {
> Class<?> cls = InjectionUtils.getRawType(bounds[j]);
> if (cls != null && (cls == Object.class ||
> cls.isAssignableFrom(expectedType))) {
> isResolved = true;
> break;
> }
> }
> {code}
> when it should actually select the one which has ALL bound types match.
> Workaround: If using Java 8, one could use an interface instead of a class
> and return a bean with that class:
> {code}
> interface FaultInfoMapper<T extends Throwable & SomeOtherInterface> extends
> ExceptionMapper<T> {
> @Override
> default Response toResponse(T exception) {
> exception.methodOfSomeOtherInterface();
> ...
> }
> }
> // when using Spring:
> @Bean
> public FaultInfoMapper<MyAppException> myAppExceptionMapper() {
> return new FaultInfoMapper<BdmsAppException>() {};
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)