PDF file resource not released

Hi Vaadin team,

I met a problem that I cannot delete the pdf file after printing pdf in vaadin8.2.0.
Here is my code:

private void printingPDF(List<PrintableBean> beans, String templateFileName) {
		Callback callback = new Callback() {
			@Override
			public void onSuccessful() {
				com.vaadin.server.StreamResource.StreamSource source = new com.vaadin.server.StreamResource.StreamSource() {
		 			/**
					 * 
					 */
					private static final long serialVersionUID = 1L;

					@Override
		 			public InputStream getStream() {
		 				FileInputStream inputStream = null;
						try {
							inputStream = new FileInputStream("reports/generates/"+loggedInUser.getUserUniqueId()+"/report.pdf");
						} catch (FileNotFoundException e) {
							e.printStackTrace();
						}
						return inputStream;
		 			}
		 		}; 
				
		        // Create the stream resource and give it a file name
		        String filename = "report.pdf";
		        StreamResource resource = new StreamResource(source, filename);

		        // These settings are not usually necessary. MIME type
		        // is detected automatically from the file name, but
		        // setting it explicitly may be necessary if the file
		        // suffix is not ".pdf".
		        resource.setMIMEType("application/pdf");
		        resource.getStream().setParameter(
		                "Content-Disposition",
		                "attachment; filename="+filename);
		        resource.setCacheTime(0);
		        
		        // Extend the print button with an opener
		        // for the PDF resource
		        opener = new BrowserWindowOpener(resource);
		        opener.extend(btnOk);
		        
				// Update status
				ui.transactionService.updateStatus(trans.getVin(), trans.getUuid(), ui.state().getName("B19"));
			}
		};
		try {
			// generate a pdf report file
			new TB4Reports().jasperToPDF(beans, loggedInUser.getUserUniqueId(), templateFileName, callback);
		} catch (ReportException e1) {
			e1.printStackTrace();
		}
	}
	
	
	/**
	 * Deleting file
	 * 
	 * @param path
	 */
	public void deleteReportFiles(String path) {
		File removableDir = new File(path);
		if (removableDir.exists()) {
			try {
				FileUtils.deleteDirectory(removableDir);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

Moreover, I tried to close the stream with the following code, but it doesn’t work and I still cannot delete the pdf file manually.

try {
	resource.getStreamSource().getStream().close();
	resource.getStream().getStream().close();

} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

I attached my screenshot here, please check.Thanks!

Best regards

Shunyi

17374217.png

“I still cannot delete the pdf file manually.” Do you maybe have a PDF file open somehow? Also can you delete the file after shutdown the application server?

Haijian Wang:
“I still cannot delete the pdf file manually.” Do you maybe have a PDF file open somehow? Also can you delete the file after shutdown the application server?

Hi Haijian,

I’m sure that PDF has never been opened by any other programs.But when I shutdown the server, I can delete PDF file successfully.

When I commented out below code, I can delete that PDF file.

// Create the stream resource and give it a file name
String filename = "report.pdf";
StreamResource resource = new StreamResource(source, filename);

// These settings are not usually necessary. MIME type
// is detected automatically from the file name, but
// setting it explicitly may be necessary if the file
// suffix is not ".pdf".
resource.setMIMEType("application/pdf");
resource.getStream().setParameter(
		"Content-Disposition",
		"attachment; filename="+filename);
resource.setCacheTime(0);

// Extend the print button with an opener
// for the PDF resource
opener = new BrowserWindowOpener(resource);
opener.extend(btnOk);

So,I wonder if the PDF file is open and in use by the instance of StreamResource or BrowserWindowOpener.

I tried that close the stream with below code, but it still does not work.

try {
	resource.getStreamSource().getStream().close();
	resource.getStream().getStream().close(); 
} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

Are there any methods to close the stream or a way that I can release the resource?

Best regards,

Shunyi Chen

首先可以只comment掉

opener = new BrowserWindowOpener(resource);
opener.extend(btnOk);

看看是不是由opener引起的。

另外就是你是在什么时候 close stream的

try {
	resource.getStreamSource().getStream().close();
	resource.getStream().getStream().close(); 
} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

这些代码是不是真的执行了?运行的时候有没有错误信息?

Haijian Wang:
首先可以只comment掉

opener = new BrowserWindowOpener(resource);
opener.extend(btnOk);

看看是不是由opener引起的。

另外就是你是在什么时候 close stream的

try {
	resource.getStreamSource().getStream().close();
	resource.getStream().getStream().close(); 
} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

这些代码是不是真的执行了?运行的时候有没有错误信息?

我正在调试,会尽快告诉你结果。谢谢。

Shunyi Chen:

Haijian Wang:
首先可以只comment掉

opener = new BrowserWindowOpener(resource);
opener.extend(btnOk);

看看是不是由opener引起的。

另外就是你是在什么时候 close stream的

try {
	resource.getStreamSource().getStream().close();
	resource.getStream().getStream().close(); 
} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

这些代码是不是真的执行了?运行的时候有没有错误信息?

我正在调试,会尽快告诉你结果。谢谢。

问题解决了,下面是我更改后代码

	private void printingPDF(List<PrintableBean> beans, String templateFileName) {
		Callback callback = new Callback() {
			@Override
			public void onSuccessful() {
				com.vaadin.server.StreamResource.StreamSource source = new com.vaadin.server.StreamResource.StreamSource() {
		 			/**
					 * 
					 */
					private static final long serialVersionUID = 1L;

					@Override
		 			public InputStream getStream() {
		 				FileInputStream inputStream = null;
						try {
							inputStream = new FileInputStream("reports/generates/"+loggedInUser.getUserUniqueId()+"/report.pdf");
						} catch (FileNotFoundException e) {
							e.printStackTrace();
						}
						return inputStream;
		 			}
		 		}; 
				
		        // Create the stream resource and give it a file name
		        String filename = "report.pdf";
		        StreamResource resource = new StreamResource(source, filename);

		        // These settings are not usually necessary. MIME type
		        // is detected automatically from the file name, but
		        // setting it explicitly may be necessary if the file
		        // suffix is not ".pdf".
//		        resource.setMIMEType("application/pdf");
//		        resource.getStream().setParameter(
//		                "Content-Disposition",
//		                "attachment; filename="+filename);
//		        resource.setCacheTime(0);
		        
		        
		        
		        // Extend the print button with an opener
		        // for the PDF resource
		        opener = new BrowserWindowOpener(resource);
		        opener.extend(btnOk);
		        
		        try {
					resource.getStreamSource().getStream().close();
				    resource.getStream().getStream().close();
					 
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		        
				// Update status
				ui.transactionService.updateStatus(trans.getVin(), trans.getUuid(), ui.state().getName("B19"));
			}
		};
		try {
			new TB4Reports().jasperToPDF(beans, loggedInUser.getUserUniqueId(), templateFileName, callback);
		} catch (ReportException e1) {
			e1.printStackTrace();
		}
	}
 
	/**
	 * Deleting report file
	 */
	private void deleteReportFiles() {
//		System.gc();
		new TB4Reports().deleteReportFiles("reports/generates/" + loggedInUser.getUserUniqueId());
	}

把下面注释掉就可以删除pdf文件了。

//		        resource.setMIMEType("application/pdf");
//		        resource.getStream().setParameter(
//		                "Content-Disposition",
//		                "attachment; filename="+filename);
//		        resource.setCacheTime(0);

但不太理解这些set方法为什么占用资源不放。