JSF OutOfMemoryError Java heap space ao baixar arquivo!

7 respostas
soul

Tenho o seguinte código que estou usando como teste para implementar um servidor de arquivos, mas ao tentar baixar arquivos de 5mb ou mais ele da o erro OutOfMemoryError Java heap space.
Implementei o mesmo código num servlet separado e não deu o erro.
O problema é no JSF ?

<h:form id="teste">
    <h:commandLink action="#{ArquivoDownload.download}" value="Download Teste" immediate="true"/>
</h:form>
public class ArquivoDownload {

    private File[] fileArray = new File("C:/Users/pirm/Downloads/").listFiles();
    private String path = "C:/Users/pirm/Downloads/netbeans-6.8-ml-windows.exe";

    public File[] getFileArray() {
        return fileArray;
    }

    public void setFileArray(File[] fileArray) {
        this.fileArray = fileArray;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public synchronized void download() {
        System.out.println("Metodo download()");
        File file = new File(path);
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
        response.setHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\"");
        response.setContentLength((int) file.length());
        System.out.println("Arquivo: " + file.getName() + "   " + file.getAbsolutePath() + "   "  + file.length());
        try {
            FileInputStream input = new FileInputStream(file);
            ServletOutputStream out = response.getOutputStream();
            byte[] buffer = new byte[1024];
            int i;
            while ((i = input.read(buffer)) != -1) {
                out.write(buffer, 0, i);  
            }
            out.flush();
            out.close();
            input.close();
            facesContext.getResponseComplete();
        } catch (IOException err) {
            err.printStackTrace();
        }
    }
}

Alguem já passou pelo problema ???

7 Respostas

G

voce precisa dizer qual o tamanho maximo da request.
Se estiver usando richfaces, no seu web.xml tem um parametro chamado maxRequestSize, no tomahawk o nome do parametro é maxFileSize.

soul

Desculpe se nao entendi direito, mas, no caso de um download não seria o response ?

G

:stuck_out_tongue: desconsidere o post de antes ^^
entendi upload, aumentando a memória usada pelo servidor o erro persiste ?

ex:

-Xms256m -Xmx512m
soul

A respeito desse procedimento(almentar a mememória), não tenho noção de como faz.
Existe uma memória da maquina virtual geral ?
Só de um programa específico como o GlassFish por exemplo ?

Teria como dar um exemplo ai?

O que me deixou curioso foi que num servlet ele não da o erro.

Com relação ao FileUpload estou tendo um problema também.
O FileUpload não funciona dentro de um modalPanel, mas isso é outro tópico.

Valeu a ajuda cara.

G

localhost:4848

na pagina do admin
va em server > JVMSettings > JVM options e mude ^^

quanto ao fileupload não funcionar dentro do modal, bom eu tenho alguns projetos com fileupload dentro de modais e funcionam perfeitamente, pode ser mais expecifico no erro ? Vc esta usando tomahawk, rich faces ? na unha mesmo ?

soul

Valeu cara ! Funciou aumentar a memória.
Só que realmente notei uma grande diferença entre pegar o response do faces e redirecionar para outro servlet.
Com o faces, a caixa de dialogo do download trava e com o outro servlet não. Também notei que carrega o arquivo mais rápido.
Alguém saberia por que fica mais rápido desse jeito ?

Código abaixo.

public synchronized void download()  throws ServletException, IOException {
            System.out.println("Metodo download() " + file.getAbsolutePath());
            FacesContext facesContext = FacesContext.getCurrentInstance();
            HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
            
            HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
            request.setAttribute("Arquivo", file);
            RequestDispatcher rd = request.getRequestDispatcher("/download");
            rd.forward(request, response);

             
            
            
        /*
        response.setHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\"");
        response.setContentLength((int) file.length());
        try {
        FileInputStream input = new FileInputStream(file);
        ServletOutputStream out = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int i;
        while ((i = input.read(buffer)) != -1) {
        out.write(buffer, 0, i);
        }
        out.flush();
        out.close();
        input.close();
        facesContext.responseComplete();
        } catch (IOException err) {
        err.printStackTrace();
        }
        *
         *
         */
        
        
    }

Servlet !

public class Download extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        File file = (File)request.getAttribute("Arquivo");
        System.out.println("Servlet download() " + file.getAbsolutePath());
        response.setHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\"");
        response.setContentLength((int) file.length());
        try {
            FileInputStream input = new FileInputStream(file);
            ServletOutputStream out = response.getOutputStream();
            byte[] buffer = new byte[1024];
            int i;
            while ((i = input.read(buffer)) != -1) {
                out.write(buffer, 0, i);
            }
            out.flush();
            out.close();
            input.close();
        } catch (IOException err) {
            err.printStackTrace();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
soul

Se for possível me enviar ou postar esse código do seu modal panel.
[email removido]

Valeu

Criado 9 de janeiro de 2010
Ultima resposta 13 de jan. de 2010
Respostas 7
Participantes 2