FileDownloader causes out of sync after upgrading to Vaadin 7.1.13

I have an application that uses the FileDownloader component to download pdfs from our site. This functionality works fine in Vaadin 7.0.7 but has a bug when we upgrade to 7.1.13. I have not tried other versions to see when it was actually introduced.

The symtom of the bug is intermitant. Sometimes when you click on the button it doesn’t download the file. When I load this in the debugger (eclipse) I see that we are in an out of sync condition. In the logs I see:

Apr 14, 2014 9:50:57 AM com.vaadin.server.communication.ServerRpcHandler parseInvocation
WARNING: RPC call to com.vaadin.shared.ui.button.ButtonServerRpc.click received for connector 114 but no such connector could be found. Resynchronizing client.

That message is generated from ServerRpcHandler line 156.

Here is the relavent code:
String fileName = (String) source.getContainerProperty(itemId, “fileName”).getValue();
FileDownloader downloader = new FileDownloader(createResource(document, fileName));
downloader.extend(button);

private StreamResource createResource(final Document document, final String fileName) {
return new StreamResource(new StreamResource.StreamSource() {
private static final long serialVersionUID = 1876589032596988869L;

        @Override
        public InputStream getStream() {
            InputStream fileStream = streamProvider.getFileStream(document);
            downloadStarted = false;
            return fileStream;
        }
    }, fileName);
}

Any help is appreciated. This is preventing us from upgrading Vaadin.

We are seeing something similar with 7.1.13, with messages like this in catalina.out:


Apr 14, 2014 4:21:17 PM com.vaadin.server.communication.ServerRpcHandler parseInvocation
WARNING: RPC call to com.vaadin.shared.ui.button.ButtonServerRpc.click received for connector 166 but no such connector could be found. Resynchronizing client.
Apr 14, 2014 4:21:17 PM com.vaadin.server.ConnectorResourceHandler error
WARNING: Ignoring connector request for no-existent connector 167 in root 0

It’s not all the time, but it does happen periodically, and when it does, we sometimes only get a partial download with no application-level errors (in our app’s logs).

Hi David, thanks for your input. Do you know if this message was being logged in previous versions?

These sorts of errors are really tricky. In fact, I couldn’t even reproduce it today, yet nothing has changed. I wonder if there could be any issues on version upgrades where browsers are not always getting the very latest styles and javascript/widgetsets.

I did see that sort of error logged before 7.1.13, so it’s not truly new, though the earlier ones I cannot confirm what was happening. The FileDownloader issue was something I was doing while monitoring the logs, so I knew they went together.

I suspect there are timing issues since I have a popup button that contains other buttons (shown as links) and those do the FileDownloader. Most of the time, that all works fine, but at other times the popup button’s layout doesn’t get hidden, too, and then if I click any other link, I get an error about the URL not even found:


/APP/connector/0/321/url/Application.html can not be found
Requested link/URL: https://example.com/demo/ui/APP/connector/0/321/url/Application.html

Argh, I had typed a message but forgot to send it, and Tori ate it. Anyway, this sounds like a classic race condition between the button click request and the one starting the download. Do you by any chance use a click listener to remove the download button from the UI? If so, the FileDownloader gets removed as well and if the click event happens before the download request, the latter can’t find the FileDownloader anymore…

Yes we are removing the button in a click listener. We do want the button removed after they download the file. The problem we have is that we haven’t found any way to get an event for when the file is done downloading. Is there some listener I haven’t found yet so I can remove the button AFTER the file is downloaded?

Vaadin does unfortunately not support download events although it would be possible in principle to implement those for Resource downloads (even without core changes - although this would require duplicating most of the code in DownloadStream.writeResponse). The main drawback would be that the clientside couldn’t be updated on such an event without using server push or polling. Anyway, you might want to hide the button instead of removing it - the download request should then still work, although it is debatable whether this is desirable from a security viewpoint.

In our case, we don’t remove the button.

We have an extended PopupButton (an add-on) in which we generate a set of Button (shown as a link) in a VerticalLayout. The popup button builds the layout when it’s first opened (the popup is visible and the vertical layout is empty). For each Button added, we do have setDisabledOnClick(true). And in our ‘getStream()’ callback when the Button is clicked to generate the content (must be retrieved from a database) we return the BufferedInputStream with a ‘finally’ clause that ensures the popup button is no longer visible (setPopupVisible(false)). It is these added buttons we ‘extend’ with the BrowserWindowOpener (and/or FileDownloader in other scenarios).

We don’t ever remove the buttons. Would making the popup button not visible cause a timing issue?

We want the button to be disabled on click because it may take time to retrieve and send back the data and we don’t want them clicking it again. And after they click to download, we want the popup button to close itself , too.

OK, so we seemed to get this to work correctly by hiding the row after they click it. It’s not a security risk in our case just a usability issue. Thanks for your help

I created a bug report of this issue: http://dev.vaadin.com/ticket/13628

OK, so I tested this in both FireFox and Chrome. In FF I get the an error in the logs and it doesn’t download correctly. This is intermittanly. In chrome I am always able to download the file but I still get errors in the logs.

From Chrome:
Apr 22, 2014 7:49:01 AM com.vaadin.server.ConnectorResourceHandler error
WARNING: Ignoring connector request for no-existent connector 456 in root 0
Apr 22, 2014 7:49:01 AM com.vaadin.server.communication.ServerRpcHandler parseInvocation
WARNING: RPC call to com.vaadin.shared.ui.button.ButtonServerRpc.click received for connector 455 but no such connector could be found. Resynchronizing client.

It certainly seems to be a race condition. When I put the code on a remove server (slower than my laptop) then I’m able to reproduce this with Chrome too.

I avoid the problem with Thread.sleep(500) before setvisible false.
Somthing like that :
if (UI.getCurrent().getPage().getWebBrowser().isFirefox()) {//Avoid the bug #13628 with firefox when the button disapear.
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(DownloadFileWindow.class.getName()).log(Level.SEVERE, null, ex);
}
}
close();
}