jmix-framework / jmix

Jmix framework
https://www.jmix.io
Apache License 2.0
487 stars 112 forks source link

NPE on downloading PDF file in Chrome #3401

Open gorbunkov opened 2 weeks ago

gorbunkov commented 2 weeks ago

Environment

Jmix version: 2.2.3

Bug Description

NullPointerException appears when users try to download the PDF file from the Chrome PDF viewer.

See forum topic.

Steps To Reproduce

Create a screen that downloads a PDF file using the Downloader bean, for example:

    @Subscribe(id = "downloadPdfBtn", subject = "clickListener")
    public void onDownloadPdfBtnClick(final ClickEvent<JmixButton> event) {
        downloader.download(
                reportService.createPdf(),
                "report.pdf",
                DownloadFormat.PDF
        );
    }

Run the application, and initiate the downloading.

The PDF file will be opened in Chrome browser.

Try to download the file using the button in Chrome PDF viewer:

Screenshot 2024-06-19 at 09 54 07

Current Behavior

An exception will be thrown and the file with 0 bytes size will be downloaded.

java.lang.NullPointerException: Cannot invoke "java.io.InputStream.read(byte[])" because "source" is null
    at com.vaadin.flow.server.StreamResource$Pipe.read(StreamResource.java:119) ~[flow-server-24.3.8.jar:24.3.8]
    at com.vaadin.flow.server.StreamResource$Pipe.copy(StreamResource.java:109) ~[flow-server-24.3.8.jar:24.3.8]
    at com.vaadin.flow.server.StreamResource$Pipe.accept(StreamResource.java:84) ~[flow-server-24.3.8.jar:24.3.8]
    at io.jmix.flowui.component.filedownloader.JmixFileDownloader.lambda$runCommand$18809115$1(JmixFileDownloader.java:121) ~[jmix-flowui-2.2.3.jar:na]
    at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65) ~[na:na]
    at io.jmix.flowui.component.filedownloader.JmixFileDownloader.lambda$beforeClientResponseDownloadHandler$69016e48$1(JmixFileDownloader.java:158) ~[jmix-flowui-2.2.3.jar:na]
    at com.vaadin.flow.server.communication.SessionRequestHandler.handleRequest(SessionRequestHandler.java:64) ~[flow-server-24.3.8.jar:24.3.8]
    at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1574) ~[flow-server-24.3.8.jar:24.3.8]
    at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:398) ~[flow-server-24.3.8.jar:24.3.8]
    at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:106) ~[vaadin-spring-24.3.8.jar:na]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]

It looks like Chrome tries to access downloader controller multiple times: when it opens the document for preview and when the download button in the viewer is clicked.

Expected Behavior

File dowloaded successfully.

Sample Project

pdf-download.zip