Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-7368

JAXB provider is handling non-jaxb classes

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.1.11
    • 3.1.12, 3.0.14, 3.2.0
    • JAX-RS
    • None
    • Unknown

    Description

      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:

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

      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:

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

      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:

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

      Attachments

        Activity

          People

            sergey_beryozkin Sergey Beryozkin
            lrohner Lukas Rohner
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: