users@jersey.java.net

Re: [Jersey] Problems with Jersey client and multipart/mixed POST

From: Mark Petrovic <mark_at_petrovic.org>
Date: Fri, 29 May 2009 22:37:41 -0700

I'm turning this work in progress into an open source project: a
simple contact manager, whose central feature is the binding of
documents (like resumes) to a contact:

http://code.google.com/p/conmgr/

It uses S3 as backing store for the documents, and HSQLDB+Hibernate as
a metadata store. Typical output thus far, which was injected via
multipart/mixed with the bundled client:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ContactInfo xmlns="http://carpediem.org/schema/ConMan">
    <contact>
       <contactId>1</contactId>
       <emailAddress>mark_at_petrovic.org</emailAddress>
       <documentInfo>
          <documentId>2</documentId>
          <documentUri>https://org.carpediem.contactmanager.s3.amazonaws.com/4ba3bb25396cf5c3172ac2342f90cc32
</documentUri>
          <mimetype>application/pdf</mimetype>
          <originalName>alice.pdf</originalName>
       </documentInfo>
       <documentInfo>
          <documentId>1</documentId>
          <documentUri>https://org.carpediem.contactmanager.s3.amazonaws.com/7e44327000aad8abff1d1ac57c1a99ed
</documentUri>
          <mimetype>application/pdf</mimetype>
          <originalName>bob.pdf</originalName>
       </documentInfo>
       <contactUri>http://localhost:8080/conman/services/contacts/1</
contactUri>
    </contact>
</ContactInfo>



On May 29, 2009, at 10:10 AM, Paul Sandoz wrote:

> Hi Mark,
>
> The example helped, i know what the problem is. When the maven
> project creates the jar from which you execute using java -jar the
> META-INF/services stuff copied from the dependencies is not correct.
>
> Basically the assembly plugin is not merging the META-INF/services/
> javax.ws.rs.ext.MessageBodyWriter files from the jersey-core and
> jersey-multipart modules.
>
> When i do mvn clean install i see the following output:
>
> [INFO] META-INF/services/javax.ws.rs.ext.MessageBodyReader already
> added, skipping
> [INFO] META-INF/services/javax.ws.rs.ext.MessageBodyWriter already
> added, skipping
>
> If i remove the version:
>
> <plugin>
> <artifactId>maven-assembly-plugin</artifactId>
> <!--
> <version>2.2-beta-3</version>
> -->
>
> the the META-INF/services file from jersey-multpart is used, so it
> is the reverse!
>
> I am not a maven expert so i do not know if this is a bug in maven
> or there is some esoteric option to merge META-INF/services stuff.
>
> Paul.
>
> On May 29, 2009, at 9:33 AM, Mark Petrovic wrote:
>
>> Paul, thank you.
>>
>> I will study your code.
>>
>> In the meantime, I am attaching a standalone, runnable version of
>> my client (should have done that at the start). There is not much
>> to it, nor is there there a server counterpart - I don't need one
>> until I clear up this multipart issue. Meaning, if the client gets
>> far enough to encounter 'connection refused' by a server that is
>> not there, I will declare victory, start my server, then move onto
>> examining what the client actually sends.
>>
>> Invoke as:
>>
>> $ mvn clean package; java -jar target/conman-client-jar-with-
>> dependencies.jar -c -e biff_at_foo.org -d RESTandS3.pdf -m application/
>> pdf
>>
>>
>> <conman.zip>
>>
>>
>>
>> Mark
>>
>>
>> On May 29, 2009, at 6:57 AM, Paul Sandoz wrote:
>>
>>> Hi Mark,
>>>
>>> Without a complete example for myself to test i cannot really say
>>> what is going on. The error indicates that when you are executing
>>> the client that assocaited jersey-multipart readers/writers have
>>> not been loaded. There might be an issue with the loading of the
>>> jersey-multipart module, if you set logging to CONFIG it might
>>> tell you why it could not be loaded.
>>>
>>> I have attached a simple example you can experiment with. It is a
>>> web app that deploys a simple servlet, and you run the Main class
>>> which utilizes the client API. This works fine.
>>>
>>> You should not need to write your own message body writer.
>>>
>>> Paul.
>>>
>>> <example-jersey-multipart.zip>
>>>
>>>
>>> On May 28, 2009, at 6:47 PM, Mark Petrovic wrote:
>>>
>>>>
>>>> Good day.
>>>>
>>>> This feels like a FAQ question, but I've banged my head on this
>>>> long enough and have concluded it's time to ask for help.
>>>>
>>>>
>>>>
>>>> Craig posted an example of exactly what I want to do: use
>>>> multipart/mixed to post a JAXB object and an attendant binary
>>>> stream in a single POST operation:
>>>>
>>>> https://jersey.dev.java.net/servlets/ReadMsg?listName=users&msgNo=3579
>>>>
>>>> However, when I try this same technique in a client I wrote, the
>>>> client throws an exception
>>>>
>>>> Exception in thread "main"
>>>> com.sun.jersey.api.client.ClientHandlerException:
>>>> com.sun.jersey.api.client.ClientHandlerException: A message body
>>>> writer for Java type, class com.sun.jersey.multipart.MultiPart,
>>>> and MIME media type, multipart/mixed, was not found
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .client
>>>> .urlconnection
>>>> .URLConnectionClientHandler
>>>> .handle(URLConnectionClientHandler.java:128)
>>>> at com.sun.jersey.api.client.Client.handle(Client.java:397)
>>>> at
>>>> com.sun.jersey.api.client.WebResource.voidHandle(WebResource.java:
>>>> 579)
>>>> at com.sun.jersey.api.client.WebResource.access
>>>> $500(WebResource.java:69)
>>>> at com.sun.jersey.api.client.WebResource
>>>> $Builder.post(WebResource.java:487)
>>>> at
>>>> org
>>>> .carpediem
>>>> .conman.client.ConmanClient.createContact(ConmanClient.java:36)
>>>> at
>>>> org.carpediem.conman.client.ConmanClient.run(ConmanClient.java:21)
>>>> at
>>>> org.carpediem.conman.client.ConmanClient.main(ConmanClient.java:15)
>>>> Caused by: com.sun.jersey.api.client.ClientHandlerException: A
>>>> message body writer for Java type, class
>>>> com.sun.jersey.multipart.MultiPart, and MIME media type,
>>>> multipart/mixed, was not found
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .api
>>>> .client
>>>> .TerminatingClientHandler
>>>> .writeRequestEntity(TerminatingClientHandler.java:308)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .client
>>>> .urlconnection
>>>> .URLConnectionClientHandler
>>>> ._invoke(URLConnectionClientHandler.java:179)
>>>> at
>>>> com
>>>> .sun
>>>> .jersey
>>>> .client
>>>> .urlconnection
>>>> .URLConnectionClientHandler
>>>> .handle(URLConnectionClientHandler.java:126)
>>>> ... 7 more
>>>>
>>>>
>>>> Here is the client code:
>>>>
>>>> package org.carpediem.conman.client;
>>>>
>>>> import com.sun.jersey.api.client.Client;
>>>> import com.sun.jersey.api.client.WebResource;
>>>> import com.sun.jersey.multipart.MultiPart;
>>>> import org.apache.commons.cli.CommandLine;
>>>> import org.carpediem.schema.conman.ContactInfo;
>>>>
>>>> import javax.ws.rs.core.MediaType;
>>>> import java.io.FileInputStream;
>>>>
>>>> public class ConmanClient extends Base {
>>>>
>>>> public static void main(String[] argv) {
>>>> ... // setup
>>>> }
>>>>
>>>> private void createContact(String emailAddress, String
>>>> documentFile, String mimeType) throws Exception {
>>>> // A JAXB object
>>>> ContactInfo cInfo = cInfo(emailAddress, mimeType);
>>>>
>>>> Client client = Client.create();
>>>> WebResource service = client.resource("http://localhost:8080/conman/services
>>>> ");
>>>>
>>>> MultiPart mp = new MultiPart();
>>>> mp.bodyPart(cInfo, MediaType.APPLICATION_XML_TYPE)
>>>> .bodyPart(new FileInputStream(documentFile),
>>>> MediaType.APPLICATION_OCTET_STREAM_TYPE);
>>>>
>>>> service.path("/contacts").type("multipart/mixed").post(mp);
>>>> }
>>>>
>>>> }
>>>>
>>>>
>>>> The base class "Base" contains only uninteresting non-JAX-WS-
>>>> related helper methods.
>>>>
>>>> I'm using maven to drive the build and exec; the pom.xml file
>>>> references these dependencies related to Jersey:
>>>>
>>>> <dependency>
>>>> <groupId>com.sun.jersey</groupId>
>>>> <artifactId>jersey-client</artifactId>
>>>> <version>1.1.0-ea</version>
>>>> </dependency>
>>>> <dependency>
>>>> <groupId>com.sun.jersey.contribs</groupId>
>>>> <artifactId>jersey-multipart</artifactId>
>>>> <version>1.1.0-ea</version>
>>>> </dependency>
>>>>
>>>>
>>>> I read the "example upload" code that Paul posted sometime back,
>>>> which is similar and I thought instructive:
>>>>
>>>> https://jersey.dev.java.net/servlets/ReadMsg?list=users&msgNo=5738
>>>>
>>>> ...and I'm still baffled as to how my code differs from either
>>>> Craig's or Paul's such that the exception obtains. And I haven't
>>>> even gotten to debugging the REST resource handler in the
>>>> server :-)
>>>>
>>>>
>>>> Can someone please help clear up why the exception obtains? I
>>>> tried writing my own MessageBodyWriter, but I didn't have much
>>>> luck with that. Besides, for a JAXB object and a binary stream,
>>>> I didn't think I needed one??
>>>>
>>>> Thanks.
>>>>
>>>> Mark
>>>>
>>>>
>>>>
>>>> --
>>>> Mark Petrovic
>>>> mark_at_petrovic.org
>>>> http://www.petrovic.org
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>> --
>> Mark Petrovic
>> mark_at_petrovic.org
>> http://www.petrovic.org
>>
>>
>>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>

--
Mark Petrovic
mark_at_petrovic.org
http://www.petrovic.org