• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Trying to generate Large PDF in servlet

 
Anurag Narayan
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
In my enterprise application I'm trying to generate a heavy PDF(around 800MB) and present to client for printing. The problem is that such a huge file is causing Websphere server to crash causing OutOfMemory Error.

Follwoing is the method which is returning the data to browser using response object.


* Utility method that demonstrates how to write an input stream to the server's local file system.
*/
private void writeToBrowser(ByteArrayInputStream byteArrayInputStream, HttpServletResponse response, String mimetype) throws Exception {

//Create a byte[] the same size as the exported ByteArrayInputStream.
byte[] buffer = new byte[byteArrayInputStream.available()];
int bytesRead = 0;

//Set response headers to indicate mime type and inline file.
response.reset();
response.setHeader("Content-disposition", "inline;filename=report.pdf");
response.setContentType(mimetype);

//Stream the byte array to the client.
while((bytesRead = byteArrayInputStream.read(buffer)) != -1) {
response.getOutputStream().write(buffer, 0, bytesRead);
}

//Flush and close the output stream.
response.getOutputStream().flush();
response.getOutputStream().close();

}


I think that the resp.getOutputStream().write is being stored in memory until the data can be sent through to the client. So the entire file might be read and stored in the resp.getOutputStream() causing memory issues and crashing!

I have tried Buffering these streams and also tried using Channels from java.nio, none of which seems to make any bit of difference to my memory issues. I have also flushed the outputstream once per iteration of the loop and after the loop, which didn't help.
 
olivier dutranoit
Ranch Hand
Posts: 81
IBM DB2 Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

just a thought...
try seting your "Content-Length" in your response header.

like

response.setHeader("Content-Length", String.valueOf(lenght-of-your-file));

what happens?
 
Ove Lindström
Ranch Hand
Posts: 326
Android Firefox Browser Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When we generate this kind of files, we have a separate report generation server that handles the work. When it is done, it is stored in a web-container and the url to the file is sent back to the user that can then use the link to get the generated file.

This also allows us to cache the requests and map the request to an already generated report. Often, the same person asks for the same report multiple times or different persons need the same report. So to save clock cycles, we store the reports for a number of days.

Typically, a request ends up under (fake url) http://gendoc.thebigcompany.com/2011/10/10/adosemcaa-ac4082646.pdf and from time to time, we purge the files from the server.
 
William Brogden
Author and all-around good cowpoke
Rancher
Posts: 13077
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Due to the huge number of objects created, a 800 MB pdf will take many many many times more memory during creation. This is most certainly NOT a job for a servlet.

As Ove says, you need to farm out this huge job to a separate server, then you can take advantages of all the cache features.


Bill
 
abani patra
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Instead of using what you are using now if you will use jasper report for producing this pdf file, I think your problem will be solve.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic