cxf-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Roni Frantchi (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (CXF-7330) org.apache.cxf.jaxrs.provider.ProviderFactory.handleMapper fails when using multiply bounded types
Date Tue, 11 Apr 2017 17:03:41 GMT

     [ 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)

Mime
View raw message