You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Sergey Beryozkin (JIRA)" <ji...@apache.org> on 2017/05/11 16:21:04 UTC

[jira] [Commented] (CXF-7368) JAXB provider is handling non-jaxb classes

    [ https://issues.apache.org/jira/browse/CXF-7368?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16006706#comment-16006706 ] 

Sergey Beryozkin commented on CXF-7368:
---------------------------------------

Reading and parsing the index file will be expensive for the isSupported checks that are done on every read/write request.
If you do not use JSONProvider then you can simply exclude it from the classpath, the other option is to extend it and handle isSupported as needed. You can also have MessageBodyWriter typed on StreamingOutput. One of these 3 options should do. 
Otherwise, If jaxb.index is available then the best thing we can do is to check it is not some well known type like InputStream or StreamingOutput that is beung checked
 

> JAXB provider is handling non-jaxb classes
> ------------------------------------------
>
>                 Key: CXF-7368
>                 URL: https://issues.apache.org/jira/browse/CXF-7368
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS
>    Affects Versions: 3.1.11
>            Reporter: Lukas Rohner
>
> The default JSONProvider is trying to marshal a non-jaxb class which results in a 500 response of my endpoint.
> One of my endpoints is returning a StreamingOutput object to the response object:
> {noformat}
>   public static Response okJson(JValue json) {
>     return Response.ok(new StreamingOutput() {
>       @Override
>       public void write(OutputStream s) throws IOException, WebApplicationException {
>         try (final BufferedOutputStream bs = new BufferedOutputStream(s)) {
>           serializer.fn.toJson(json).apply(bs);
>         }
>       }
>     }, MediaType.APPLICATION_JSON_TYPE).build();
>   }
> {noformat}
> Unfortunately, the default JSONProvider is trying to marshal this class because it thinks it is a jaxb supported class. This support check happens in the AbstractJAXBProvider class:
> {noformat}
>     protected boolean isSupported(Class<?> type, Type genericType, Annotation[] anns) {
>         if (jaxbElementClassMap != null && jaxbElementClassMap.containsKey(type.getName())
>             || isSkipJaxbChecks()) {
>             return true;
>         }
>         return isXmlRoot(type)
>             || JAXBElement.class.isAssignableFrom(type)
>             || objectFactoryOrIndexAvailable(type)
>             || (type != genericType && objectFactoryForType(genericType))
>             || org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(type, anns) != null;
>     
>     }
>     protected boolean objectFactoryOrIndexAvailable(Class<?> type) {
>         return type.getResource("ObjectFactory.class") != null
>                || type.getResource("jaxb.index") != null; 
>     }
> {noformat}
> The issue is that the objectFactoryOrIndexAvailable is returning true which doesn't indicate that the type itself is a jaxb class. To fix the support method it should actually check if there is a jaxb.index file and if in the index file the current type is available. Then we can clearly say it's a jaxb supported class.
> Something like this:
> {noformat}
>         return isXmlRoot(type)
>             || JAXBElement.class.isAssignableFrom(type)
>             || (objectFactoryOrIndexAvailable(type) && indexContainsType(type))
>             || (type != genericType && objectFactoryForType(genericType))
>             || org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(type, anns) != null;
>     protected boolean indexContainsType(Class<?> type) {
>       try (BufferedReader reader = new BufferedReader(new InputStreamReader(type.getResourceAsStream("jaxb.index")))) {
>         String line = null;
>         while((line = reader.readLine()) != null) {
>           if(line.contains(type.getName()))
>             return true;
>         }
>       }
>       return false;
>     }
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)