Guillaume,
as you are the author of this class maybe you can clarify things here.
I am using the binary file marshaler for a test case with the new
servicemix-mail component. My test case simply polls all files from a given
folder and sends it to a mail-sender endpoint.
When using my own file marshaler (using FileDataSource) this test case works
well. But when I am switching to the BinaryFileMarshaler the problems start.
Here the error stack trace:
-------------------------------------------------------------------------------------------
javax.mail.MessagingException: IOException while sending message;
nested exception is:
java.io.IOException: Stream closed
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:625)
at javax.mail.Transport.send0(Transport.java:169)
at javax.mail.Transport.send(Transport.java:98)
at
org.apache.servicemix.mail.MailSenderEndpoint.processInOnly(MailSenderEndpoint.java:113)
at
org.apache.servicemix.common.endpoints.ProviderEndpoint.process(ProviderEndpoint.java:100)
at
org.apache.servicemix.common.AsyncBaseLifeCycle.doProcess(AsyncBaseLifeCycle.java:538)
at
org.apache.servicemix.common.AsyncBaseLifeCycle.processExchange(AsyncBaseLifeCycle.java:490)
at
org.apache.servicemix.common.BaseLifeCycle.onMessageExchange(BaseLifeCycle.java:46)
at
org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.processInBound(DeliveryChannelImpl.java:610)
at
org.apache.servicemix.jbi.nmr.flow.AbstractFlow.doRouting(AbstractFlow.java:170)
at
org.apache.servicemix.jbi.nmr.flow.seda.SedaFlow.doRouting(SedaFlow.java:167)
at
org.apache.servicemix.jbi.nmr.flow.seda.SedaQueue$1.run(SedaQueue.java:134)
at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.io.IOException: Stream closed
at
java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:145)
at java.io.BufferedInputStream.read(BufferedInputStream.java:304)
at java.io.FilterInputStream.read(FilterInputStream.java:90)
at javax.activation.DataHandler.writeTo(DataHandler.java:307)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:845)
at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:361)
at
com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:85)
at
javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:883)
at javax.activation.DataHandler.writeTo(DataHandler.java:316)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350)
at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1683)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:585)
... 14 more
-------------------------------------------------------------------------------------------
I was wondering why this happens. So I decided to make another FileMarshaler
just cloning the BinaryFileMarshaler class and just replace the
StreamDataSource with the FileDataSource. The result was that it worked
afterwards.
I had a look at the JAF and googled a bit and found that the getInputStream()
method should always return a new instance of a input stream to the
underlying data. This is not the case with the StreamDataSource.
So the question is what to do now? Is the StreamDataSource not JAF compliant
and has to be changed or should the BinaryFileMarshaler use the
FileDataSource instead? (I would suggest the later)
What do you think?
Regards,
Lars
Am Mittwoch, 5. März 2008 17:28:52 schrieb lhein:
> Hi,
>
> I stumbled about the BinaryFileMarshaler while looking for a problem I had.
> This one has 2 parameters to set:
>
> - contentType
> - attachment
>
> Now the question. Why should somebody specify a content type? Isn't it
> better to use the FileDataSource to put the file as attachment into the
> message?
> Second is why is there a configuration possibility for naming the
> attachment? Is this really needed? I mean 99% would use the file name as
> this or not?
>
> maybe we could also change it to something like this as a middle solution:
>
> /**
> * A FileMarshaler that converts the given input stream into a binary
> * attachment.
> *
> * @org.apache.xbean.XBean
> *
> * @author Guillaume Nodet
> * @since 3.0
> */
> public class BinaryFileMarshaler extends DefaultFileMarshaler {
>
> private String attachment = FILE_CONTENT;
> private String contentType;
>
> public String getAttachment() {
> return attachment;
> }
>
> public void setAttachment(String attachment) {
> this.attachment = attachment;
> }
>
> public String getContentType() {
> return contentType;
> }
>
> public void setContentType(String contentType) {
> this.contentType = contentType;
> }
>
> public void readMessage(MessageExchange exchange, NormalizedMessage
> message,
> InputStream in, String path) throws
> IOException, JBIException {
> File file = new File(path);
> FileDataSource fds = new FileDataSource(file);
> DataSource ds = new StreamDataSource(in, contentType != null ?
> contentType : fds.getContentType(), file.getName());
> DataHandler handler = new DataHandler(ds);
> message.addAttachment(attachment, handler);
> message.setProperty(FILE_NAME_PROPERTY, file.getName());
> message.setProperty(FILE_PATH_PROPERTY, path);
> }
>
> public void writeMessage(MessageExchange exchange, NormalizedMessage
> message,
> OutputStream out, String path) throws
> IOException, JBIException {
> DataHandler handler = message.getAttachment(attachment);
> if (handler == null) {
> throw new MessagingException("Could not find attachment: "
> + attachment);
> }
> InputStream is = handler.getInputStream();
> FileUtil.copyInputStream(is, out);
> }
>
> }
>
> Shouldn't it be possible to use only FileDataSource or where is the sense
> in doing it with StreamDataSource?
>
> Regards,
> Lars