iris ding created CXF-5835:
------------------------------

             Summary: Two issues in 
org.apache.cxf.jaxrs.provider.DataSourceProvider
                 Key: CXF-5835
                 URL: https://issues.apache.org/jira/browse/CXF-5835
             Project: CXF
          Issue Type: Bug
          Components: JAX-RS
    Affects Versions: 3.0.0
            Reporter: iris ding


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.





--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to