DownloadStream not downloading with vaadin 6.6.2

Hello,

my application runs on vaadin 6.5.1. I wanted to upgraded to the current stable vaadin release (6.6.2), but after upgrading the file download function is no longer working.
On Chrome I got an empty page, with fire fox I got an error (can’r find viewer for unknown application). Reverting back to vaadin 6.5.1 everything works fine.

Does anyone has encountered this problem ?

best regards
Massimo

I haven’t encountered this problem myself, so could you elaborate a bit on what you are trying to do when the problem occurs? A small example from the relevant part of your code and a few rows from the stack trace might help to narrow things down. Also, is it just download that doesn’t work, or are there any other problems? Quite a bit has changed between 6.5.1 and 6.6.2, so if there’s anything in your application that is using (or trying to use) old gwt-dependencies, themes or widgetsets (either default or custom-made, if they haven’t been recompiled after the update) things might go more than a little wonky.

Hello Anna,

thanks for the reply.
This is the first test I done with 6.6.2, so I don’t know whether there’re more issues with the latest vaadin version.
My code is quite simple: when a button is pressed I open a new window with my own FileResource


                public void buttonClick(ClickEvent event) {

                    try {
                        Attachment attachment = documentDao.getAttachment(filename);
                        if (logger.isDebugEnabled())
                            logger.debug("Downloading: " + attachment.getFilename());
                        event.getButton()
                                .getWindow()
                                .open(new FileDownloadResource(new File(attachment.getFilename()), ApplicationHelper
                                        .getCurrentApplication(), documentDao, attachment.getAttachmentId(), true),
                                        "_blank");
                    } catch (Exception e) {
                        PersistenceExceptionHandling.handleDefaultException(e);
                        return;
                    }
                }

The FileDownloadResource class extends the vaadin FileResource class in order to return a DownloadStream initialized with the inputStream from a Blob retrieved from the database.


public class FileDownloadResource extends FileResource {
    private static final Logger logger = LoggerFactory.getLogger(FileDownloadResource.class);
    private static final long serialVersionUID = 1L;

    private InputStream inputStream;
    private long length;
    private DocumentDAO documentDao;
    private long objectId;
    private boolean isAttachment;

    /**
     * This constructor is intended to be used when the source is a file.
     * 
     * @param sourceFile
     * @param application
     * @param inputStream
     * @param length
     */
    public FileDownloadResource(File sourceFile, Application application, InputStream inputStream, long length) {
        super(sourceFile, application);
        this.inputStream = inputStream;
        this.length = length;
    }

    /**
     * This constructor is intended to be generally used when we're providing
     * the resource from a Blob retrieved from the NESS-DR database. The actual
     * inputStream is created when {@link #getStream()} is invoked. This could
     * be required (and is required when using Hibernate and the download is
     * delegated to a different window, served by a new Thread) since the
     * database session and the related transaction could have been closed since
     * the {@link FileDownloadResource} object serving the data is instantiated.
     * 
     * @param sourceFile
     *            name of the file
     * @param application
     *            Vaadin application providing the required UI/servlet context
     * @param documentDao
     *            the Data Access Object providing access to the database where
     *            the file to be served is stored as a blob
     * @param fileId
     *            identifier of the database entity that contains the blob
     * @param isAttachment
     *            <code>true</code> if the blob is stored in an
     *            {@link Attachment} entity rather than in a {@link Document}
     *            entity
     */
    public FileDownloadResource(File sourceFile, Application application, DocumentDAO documentDao, long fileId,
            boolean isAttachment) {
        super(sourceFile, application);
        this.documentDao = documentDao;
        this.objectId = fileId;
        this.isAttachment = isAttachment;
    }

    /**
     * Return the {@link DownloadStream} properly initialized with the
     * appropriated input stream. If the {@link #documentDao} is not
     * <code>null</code> we are retrieving the data from a Blob stored in the
     * persistent storage. In this case the Blob is retrieved from the database
     * via the injected {@link #documentDao} and using the {@link #objectId}
     * provided in the constructor and get access to the blob as a binary data
     * stream. In the other case the inputStream has been already open by the
     * class that instantiated this {@link FileDownloadResource} object and
     * we'll use it
     * 
     * @return
     * @see com.vaadin.terminal.FileResource#getStream()
     */
    public DownloadStream getStream() {
        if (documentDao != null) {
            try {
                Blob blob = isAttachment ? documentDao.getAttachmentFile(objectId) : documentDao
                        .getDocumentFile(objectId);
                inputStream = blob.getBinaryStream();
                length = blob.length();
            } catch (PersistenceException e) {
                PersistenceExceptionHandling.handleDefaultException(e);
                return null;
            } catch (SQLException e) {
                PersistenceExceptionHandling.handleDefaultException(e);
                return null;
            }
        }

        final DownloadStream ds = new DownloadStream(inputStream, getMIMEType(), getFilename());
        ds.setParameter("Content-Length", String.valueOf(length));
        ds.setParameter("Content-Disposition", "attachment; filename=" + getFilename());
        ds.setCacheTime(0);
        logger.debug("FileDownloadResource returning Download Stream, mimeType=" + getMIMEType());
        return ds;

    }
}

I played around with your code a bit and it seems to work just fine for me in 6.6.2, so either the problem only comes out with more complicated cases than what I tried, or the real problem is somewhere outside the code you already provided. If the central parts of your application are easily isolated you could try to create a new Vaadin project with 6.6.2 and copy the code over to make sure there’s no forgotten bits of configuration that demand for an older version of Vaadin. My test was done with only three classes: an application class with one button, your FileDownloadResource and a ridiculously simple DocumentDAO.