Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

HTTP Status 500 – Internal Server Error no primeiro click. Depois funciona normalmente

Nessa atividade, não consegui encontrar nenhuma diferença no meu código em relação ao do professor. No entanto, toda vez que vou remover uma empresa da lista, somente na primeira clicada aparece o seguinte erro:

HTTP Status 500 – Internal Server Error
Type Exception Report

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

java.util.ConcurrentModificationException
    java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    java.util.ArrayList$Itr.next(Unknown Source)
    br.com.alura.gerenciador.modelo.Banco.removeEmpresa(Banco.java:39)
    br.com.alura.gerenciador.acao.RemoveEmpresa.executa(RemoveEmpresa.java:21)
    br.com.alura.gerenciador.servlet.UnicaEntradaServlet.service(UnicaEntradaServlet.java:29)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note The full stack trace of the root cause is available in the server logs.

Apache Tomcat/9.0.37

Alguém tem ideia do que pode estar ocasionando isso?

Porque depois de dar o erro, eu volto na página, clico novamente, e aí a página é removida com sucesso.

PS: isso já estava acontecendo desde a primeira vez que criei o "Remover", na parte 1 do curso de Servlets.

Obrigado.

PS2: O que aparece no console é isto aqui:

set 03, 2020 11:08:10 AM org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [br.com.alura.gerenciador.servlet.UnicaEntradaServlet] in context with path [/gerenciador] threw exception
java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at br.com.alura.gerenciador.modelo.Banco.removeEmpresa(Banco.java:39)
    at br.com.alura.gerenciador.acao.RemoveEmpresa.executa(RemoveEmpresa.java:21)
    at br.com.alura.gerenciador.servlet.UnicaEntradaServlet.service(UnicaEntradaServlet.java:32)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
4 respostas

Olá Henrique, tudo bem com você?

Pode postar os códigos da aula, por favor?

Normalmente esse problema acontece quando tem mais de uma thread tentando mexer na mesma lista, seja para percorrer, adicionar, ou deletar, ai temos essa exceção de ConcurrentModificationException, com o código da classe Banco principalmente pode ajudar bastante :)

Fico no aguardo!

Abraços e Bons Estudos :)

Fala, Geovani. Obrigado pela resposta. Vou postar aqui os códigos de algumas classes. Não vou postar todas para não ficar uma coisa enorme. Se precisar de mais, só avisar.

Classe Banco:

package br.com.alura.gerenciador.modelo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Banco {

    private static List<Empresa> lista = new ArrayList<>();
    private static Integer chaveSequencial = 1;

    static {
        Empresa empresa = new Empresa();
        empresa.setId(chaveSequencial++);
        empresa.setNome("Caelum");

        Empresa empresa2 = new Empresa();
        empresa2.setId(chaveSequencial++);
        empresa2.setNome("Alura");

        lista.add(empresa);
        lista.add(empresa2);
    }

    public void adiciona(Empresa empresa) {
        empresa.setId(Banco.chaveSequencial++);
        Banco.lista.add(empresa);
    }

    public List<Empresa> getEmpresas() {
        return lista;
    }

    public void removeEmpresa(Integer id) {
        //para não iterar e modificar ao mesmo tempo (como se fosse foreach)
        Iterator<Empresa> it = lista.iterator();

        while(it.hasNext()) {
            Empresa emp = it.next();

            if(emp.getId() == id) {
                lista.remove(emp);
            }
        }
    }

    public Empresa buscaEmpresaPeloId(Integer id) {
        for (Empresa empresa : lista) {
            if(empresa.getId() == id) {
                return empresa;
            }
        }
        return null;
    }
}

Classe RemoveEmpresa

package br.com.alura.gerenciador.acao;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import br.com.alura.gerenciador.modelo.Banco;

public class RemoveEmpresa implements Acao {
    public String executa(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("Removendo empresa");

        String paramId = request.getParameter("id");
        Integer id = Integer.valueOf(paramId);

        System.out.println(id);

        Banco banco = new Banco();
        banco.removeEmpresa(id);

        return "redirect:entrada?acao=ListaEmpresas";
    }
}

listaEmpresas.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import="java.util.List,br.com.alura.gerenciador.modelo.Empresa" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Java Standard Taglib da Empresa</title>
</head>
<body>
    <c:if test="${not empty empresa}">
        Empresa ${empresa} cadastrada com sucesso!
    </c:if>
    <br /><br />
    Lista de empresas: <br />

    <ul>
        <c:forEach items="${empresas}" var="empresa">
            <li>
                ${empresa.nome} - <fmt:formatDate value="${empresa.dataAbertura}" pattern="dd/MM/yyyy"/>
                <a href="/gerenciador/entrada?acao=MostraEmpresa&id=${empresa.id}">Editar</a>
                <a href="/gerenciador/entrada?acao=RemoveEmpresa&id=${empresa.id}">Remover</a>    
            </li>    
        </c:forEach>
    </ul>
</body>
</html>

Valeu!

solução!

Opa Henrique,

Aqui no remove

    public void removeEmpresa(Integer id) {
        //para não iterar e modificar ao mesmo tempo (como se fosse foreach)
        Iterator<Empresa> it = lista.iterator();

        while(it.hasNext()) {
            Empresa emp = it.next();

            if(emp.getId() == id) {
                lista.remove(emp);
            }
        }
    }

Na verdade não é lista.remove(emp), dessa forma também estamos acessando a lista, e gerando esse erro de modificação concorrente, na verdade, precisamos excluir o elemento da seguinte forma:

if( emp.getId() == id){
    it.remove();
}

Então no laço do while vamos pulando elemento com o it.next() e quando encontramos o elemento que tem mesmo id pedimos para remover a posição atual do iterator

Conseguiu Compreender?

Abraços e Bons Estudos!

Agora funcionou direitinho! Muito obrigado, Geovani!!