Há alguns meses eu passei por dias bem corridos. Precisávamos fazer a entrega de um grande produto e, como sempre, tudo resolve acontecer nos últimos dias, resultando numa lista de bugs que precisam ser corrigidos. O maior problema desta lista era um bug aparentemente simples, um include JSP que não funcionava. Acotnece que este código foi herdado de uma famosa empresa indiana CMM nível 5 e, como tal, está uma porcaria.
Como não havia tempo para refatorar o sistema (diria que 90% dele precisava mudar, isso caracteriza reescrita ou ainda posso chamar de refactoring?), tivemos que trabalhar com o que tínhamos em mãos. E o que tínhamos em mãos era: enderecodosistema.empresa.com.br, o endereço do próprio servidor. Essa era aúnica mensagem de erro, na verdade era algo assim que aparecia no log:
javax.servlet.ServletException: enderecodosistema.empresa.com.br
at atg.portal.framework.taglib.RenderPreparedGearTag.doStartTag()
at jsp_servlet._templates._claclacal._html.__full._jspService()
at weblogic.servlet.jsp.JspBase.service()V(Optimized Method)
at weblogic.servlet.internal(Optimized Method)
...
Detalhe que o erro só ocorria no servidor de produção, justo o que não podíamos manipular sem preecncher 15 formulários em várias vias. Após olhar o código (cada mais fundo que eu ia mais palavrões soltava e minha cara de espanto atraía os transeuntes) eu percebi que o sistema era baseado num padrão de projeto muito famoso em empresas, principalmente as consultorias com CMM, chamado “Vamos-Comer-Esta-Exceção-Com-Farinha”.
O código era mais ou menos assim (claro que isso era copiado e colado algumas milhares de vezes por todo o código, modularidade para quê?):
try{
algumaCoisaQualquer();
}
catch(Exception e){
String msg = e.getMessage();
throw new BussinesRuleException(msg);
}
Muito bom! Nossa mensagem simplesmente podia ser QUALQUER coisa. O tipo da exceção foi perdido, a stacktrace foi perdido… a única coisa que ficou foi o CMM nível 5.
Solução? Primeiro tentamos adicionar mais debugging. Isso podia dar certo mas ia demorar uma semana para conseguirmos colocar o sistema em produção com um log decente (i.e. StackTraces), fora o tempo de correção após termos descoberto o que acotnecia. Como o problema só ocorria em produção, um bom ponto de partida seria verificar se tudo que está neste servidor está em outros (o pessoal de infra sempre diz que tá, maaaas…).
Compara daqui, compara de lá e… dezenas de biblitoecas com versões diferentes. Uma coisa interessante é que haviam duas versões do Jalarta Commons HttpClient, removemos a versão anterior, consolidamos todas as bibliotecas, configurações e DataSources e… nada!
Após a derrota na hipótese das versões de bibliotecas, estava almoçando com meu chefe enquanto fazíamos uma chamada para os gerentes que podiam autorizar nossa versão com log melhorado ir para produção quando me deu um estalo. Ora, se tem HTTP client neste sistema e se a mensagem de erro é o hostname… ELE ESTA TENTANDO FAZER UMA CONEXÃO HTTP LOOPBACK! Acontece que o sistema estava em pré-produção, logo seu DNS não estava registrado. Aquela exceção só podia ser algo do tipo new HostNotFoundException("enderecodosistema.empresa.com.br");.
Relendo todo o código, suspeita confirmada. Uma linha no /etc/hosts e o sistema estava pronto para entrar em produção.
Agora, por que raios ele se conectava a ele mesmo? Lendo direito eu percebi que um dos programadores CMM nível 5 utilizava uma JSP para gerar um arquivo XML que era transformado via XSLT em HTML. Ou seja: ele precisava se conectar novamente para dar um GET na página JSP que retornava o arquivo! Ele usava uma tecnologia utilizada para criar HTML (JSP) apr agerar um XML que era transformado em HTML!
Qualquer API de XML meia-boca vai te dar um método que retorna o XML gerado como uma String mas acho que nosso amigo CMM nível 5 não sabia ler JavaDocs em inglês.
Eu poderia tentar concluir com uma reflexão sobre o design de aplicações, umas dicas básicas para trabalhar com XMl em uma aplicação web ou sei lá o que, mas em vez disso eu vou terminar com uma lição simples: cuidado com as mensagens das suas exceções, você nunca vai saber quando uma consultoria CMM nível 5 vai utilizar seu código.
Faça sua mensagem de exceção contêr pelo menos alguma coisa de útil caso não haja stacktraces nem o tipo da exceção esteja disponível. Eu sei que no caso reportado o problema não foi da API (afinal, HostNotFoundException: “host not found enderecodosistema.empresa.com.br” é, no mínimo, prolixo) mas pense que nem todas as pessoas que vão usar seu código são programadores, alguns são apenas CMM nível 5.