0
votes

I am new to File handling in Java. I have written a code which should download a file from the server. The code is working for files upto size 70 MB.If large files are downloaded it throws an Exception.

SRVE0260E: The server cannot use the error page specified for your application to handle the Original Exception printed below.

Original Exception: Error Message: java.lang.OutOfMemoryError Error Code: 500 Target Servlet: null Error Stack: java.lang.OutOfMemoryError " at app.web.webcontroller.webAction.DownloadCsvAction.execute(DownloadCsvAction.java:49)" " at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:422)" " at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)" " at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)" " at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)" " at javax.servlet.http.HttpServlet.service(HttpServlet.java:718)" " at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1530)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1470)" " at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:131)" " at app.systemController.RequestTimerFilter.doFilter_http(RequestTimerFilter.java:73)" " at app.systemController.RequestTimerFilter.doFilter(RequestTimerFilter.java:61)" " at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:188)" " at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:116)" " at com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:77)" " at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:858)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:824)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:458)" " at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)" " at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:91)" " at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:862)" " at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1583)" " at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:178)" " at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:455)" " at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:384)" " at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83)" " at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)" " at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)" " at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)" " at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)" " at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)" " at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)" " at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)" " at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1550)"

Error Page Exception: Error Message: java.lang.IllegalStateException: SRVE0199E: OutputStream already obtained Error Code: 0 Target Servlet: null Error Stack: java.lang.IllegalStateException: SRVE0199E: OutputStream already obtained " at com.ibm.ws.webcontainer.srt.SRTServletResponse.getWriter(SRTServletResponse.java:719)" " at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:187)" " at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:175)" " at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:262)" " at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:177)" " at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:137)" " at com.ibm._jsp._Error500._jspService(_Error500.java:177)" " at com.ibm.ws.jsp.runtime.HttpJspBase.service(HttpJspBase.java:98)" " at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1530)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1470)" " at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:104)" " at com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:77)" " at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:858)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:824)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:458)" " at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)" " at com.ibm.wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:121)" " at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.handleRequest(AbstractJSPExtensionServletWrapper.java:239)" " at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:330)" " at com.ibm.ws.webcontainer.webapp.WebApp.sendError(WebApp.java:3209)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:987)" " at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:458)" " at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:175)" " at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:91)" " at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:862)" " at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1583)" " at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:178)" " at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:455)" " at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:384)" " at com.ibm.ws.http.channel.inbound.impl.HttpICLReadCallback.complete(HttpICLReadCallback.java:83)" " at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)" " at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)" " at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)" " at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)" " at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)" " at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)" " at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)" " at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1550)"

This Exception gets printed in the downloaded file instead of having the original data.

response.setHeader("Content-Disposition","attachment;filename=\""+fileName+"\"");
        response.setContentType("application/octet-stream");
         File downloadFile = new File(fileUrl\fileName);
         OutputStream out = response.getOutputStream();
         FileInputStream in = new FileInputStream(downloadFile); 
         int size=(int)downloadFile.length()+1;
         byte[] buffer = new byte[size];
         int length;
         while ((length = in.read(buffer)) != -1){
            out.write(buffer, 0, length);
         }
         in.close();
         out.flush();

Also in the code snippet ,Please tell me if there is any way to optimise my code to make it faster.

2

2 Answers

2
votes

You create a buffer with the size ofthe file you want to transfer. With big files you will get just what happened: an OutOfMemoryError, since there is not enough space on your heap for that much data.

The easiest fix is to choose a smaller buffer size, like 64k. That should not degrade performance noticeably:

byte[] buffer = new byte[64 * 1024];
1
votes

This code kill your app:

int size=(int)downloadFile.length()+1;
byte[] buffer = new byte[size];

Because you use too large buffer so JVM will be OutOfMemory. You should split your file into small chunk like byte[] buffer = new byte[1024]