aspose file tools*
The moose likes Servlets and the fly likes Trying to generate Large PDF in servlet Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Servlets
Bookmark "Trying to generate Large PDF in servlet" Watch "Trying to generate Large PDF in servlet" New topic
Author

Trying to generate Large PDF in servlet

Anurag Narayan
Ranch Hand

Joined: Jul 14, 2008
Posts: 41
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.

Anurag Narayan<br />SCJP5,SCEA(OCMJEA)
olivier dutranoit
Ranch Hand

Joined: Aug 20, 2011
Posts: 81

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

Joined: Mar 10, 2008
Posts: 326

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

Joined: Mar 22, 2000
Posts: 12769
    
    5
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

Joined: Oct 11, 2011
Posts: 70
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.
 
 
subject: Trying to generate Large PDF in servlet