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

Two issues in org.apache.cxf.jaxrs.provider.DataSourceProvider

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.0
    • Fix Version/s: 2.7.12, 3.0.1
    • Component/s: JAX-RS
    • Labels:
      None
    • Estimated Complexity:
      Moderate

      Description

      Issue 1: ClassCastException if you post a FileDataSource in your resource class:
      @Path("providers/standard/datasource")
      public class DataSourceResource {
      @POST
      public DataSource postDataSource(FileDataSource ds)

      { return ds; }

      }
      The error stack is like below:
      Caused by: java.lang.ClassCastException: Cannot cast class org.apache.cxf.jaxrs.ext.multipart.InputStreamDataSource to class javax.activation.FileDataSource
      at java.lang.Class.cast(Class.java:1730)
      at org.apache.cxf.jaxrs.provider.DataSourceProvider.readFrom(DataSourceProvider.java:55)
      at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1311)
      at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1262)
      at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:801)
      at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:764)
      at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:212)
      at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:76)
      at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)

      Since there are several implementation class for DataSource, we can not use the logic below:
      public T readFrom(Class<T> cls, Type genericType, Annotation[] annotations,
      MediaType type,
      MultivaluedMap<String, String> headers, InputStream is)
      throws IOException

      { DataSource ds = new InputStreamDataSource(is, type.toString()); return cls.cast(DataSource.class.isAssignableFrom(cls) ? ds : new DataHandler(ds)); }

      Issue 2: Return the original InputStream directly in InputStreamDataSource.getInputStream().

      I have checked Jersy and Wink's implementation for this part, both of them will replace the incomming InputStream with ByteArrayInputStream. Using this way, the inputStream.available() will be correctly be called.
      My resource can run successfully both in Jersey and Wink. But failed with CXF. The resource class snippet is like below:

      @POST
      public Response post(DataSource dataSource) {
      Response resp = null;
      try

      { InputStream inputStream = dataSource.getInputStream(); byte[] inputBytes = new byte[inputStream.available()]; .......... }

      From my understanding, we need to this conversion for InputStream to convert it to a standard java.io.ByteArrayInputStream. Because only in such way, we can return to users a standard InputStream. For example, the incomming InputStream might be a specific type to J2ee container.

        Attachments

          Activity

            People

            • Assignee:
              sergey_beryozkin Sergey Beryozkin
              Reporter:
              irisding Iris Ding
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: