Script para iniciar o tomcat

O tomcat costuma apresentar um problema chamado PermGen space Exception quando fazemos muitos undeploys e deploys sem reiniciar o processo do tomcat. Isso acontece por uma característica da jvm da Sun. Não chega a ser propriamente um bug.

Quando executamos uma aplicação java uma instância da jvm é criada exclusivamente para aquela aplicação. Na jvm existe um espaço de memória que nunca é reutilizado. Se chama espaço de memória permanente (PermGen space) e serve para guardar objetos do tipo Class. Quando se carrega uma aplicação, cada casse do jar ou war é instanciado como um objeto que fica alocado neste espaço de memória permanente. Se a aplicação tiver muitíssimas classes a jvm vai lançar uma mensagem de erro indicando que esse espaço está repleto e não é possível carregar a aplicação. Mas se as suas classes se encaixarem neste espaço (e em geral cabe) sua aplicação vai rodar sem problemas. Existem dois tipos de casos onde existe um consumo indevido do espaço de memória permanente:

  1. Programas que geram tipos de classe dinamicamente. O hibernate chega a criar algumas classes em tempo de execução, mas não chega a ser um número tão grande a ponto de gerar problemas. Para encher o espaço de memória permanente seria necessário criar centenas ou milhares de classes dinamicamente. Provavelmente um sistema que roda por muitos dias seguidos e criando classes novas possa chegar preencher todo este espaço. Mas seria um sistema mau escrito.
  2. Programas que carregam muitos tipos de classes dinamicamente. É o caso do tomcat que aceita deploy e undeploy de aplicações. Quando um desenvolvedor faz undeploy todos os objetos das classes da aplicação continuam lá no espaço de memória permanente e quando é feito o deploy da nova versão do context outros tantos objetos do tipo classe vão para a memória permanente. Em algum momento a memória acaba.

É por isso que no ambiente de desenvolvimento é comum ter de reiniciar o tomcat várias vezes ao longo do dia de trabalho. Como meu ambiente é para testes, eu limpo logs e o diretório work antes de rodar o tomcat, e coloco o tomcat.log que é o arquivo do log4j que eu configurei para exibir as mensagens do tomcat. Segue abaixo o meu script para iniciar o tomcat:

#!/bin/sh
TOMCAT_HOME="/opt/tomcat"
TOMCAT_LOGFILE="$TOMCAT_HOME/logs/tomcat.log"

cd $TOMCAT_HOME
rm logs/* -rf
rm work/Catalina/localhost/* -rf
bin/catalina.sh jpda start
ps aux|grep tomcat
echo "tomcat iniciado..."

sleep 5

while [ ! -f "$TOMCAT_LOGFILE" ]; do
sleep 1
echo "arquivo de log ainda não foi criado..."
done

echo "log do tomcat existe e será exibido a seguir:"
tail -f logs/tomcat.log

Memorando

A emissão de memorandos costuma ter um controle de numeração por série. Este sistema controla o número de um memorando dentro de uma série específica, indicando além do autor do documento outros dados básicos como a identificação do interessado e a data de criação.

Mapa de Idéias

Estudo de caso de uso de memorando

Componentes

  • FiltroDeAutenticação: verifica se o usuário está autenticado no tomcat.
  • Action
  • /SelecionaSerie: carrega uma lista de séries de memorandos e o nome do autor do memorando. Encaminha para selecionaSeria.jsp. O jsp aponta para a action /Lista.
  • /Lista: carrega os memorandos da série escolhida e encaminha para lista.jsp.

Os plugins que eu utilizo no eclipse

Eu utilizo o eclipse wtp europa que possui todos os plugins que eu preciso. Esta versão do eclipse pode ser baixada por este link:

Versão para o Windows
Todas as versões, inclusive linux e Windows

O eclipse wtp europa é a consolidação de diversos plugins. Com ele dá para programar em java, editar qualquer arquivo xml, arquivos jsp e sql. Existem uma perspectiva que permite a conexão com qualquer banco de dados jdbc, e a partir daí posso rodar queries sql simples. Para tarefas mais exigentes eu utilizo um programinha externo chamado Squirrel SQL. Prefiro utilizar o wtp com o Squirrel ao plugin quantum, que também é um bom plugin.

Dificilmente eu trabalho com o hibernate. Quando isso acontece eu utilizo um segundo plugin para o eclipse que é o hibernate tools, do grupo jboss. Fora isso não instalo nenhum plugin. É comum o eclipse ficar instável após a instalação de muitos plugins. Por isso eu prefiro uma instalação mais enxuta que normalmente se limita ao wtp.

Um outro plugin que muitos colegas usam é o sysdeo. O papel desse plugin é iniciar e derrubar o tomcat e facilitar o debug. Eu não gosto nada nada desse plugin, e prefiro fazer o debug dispensando o uso de quaisquer plugins. Para fazer isso, veja esse link: .

Por fim, existe o plugin para o struts chamado Easy Struts. Esse plugin dá uma visão gráfica do struts-config.xml. Eu deixei de utilizar o plugin assim que eu entendi como funciona o xml, porque eu sempre achei, e continuo achando que o struts-config.xml é uma aberração da natureza. Agora com o struts 2 ficou bem mais fácil de mapear as ações, e eu não sinto necessidade alguma de plugin.

Bem, esses são os plugins que eu utilizo ou que já utilizei no eclipse.

Hotdeploy no tomcat

Voltei a acreditar no hotdeploy do tomcat.

O tomcat tem o recurso de deploy de aplicativos com o tomcat rodando. Isso economiza muito tempo de desenvolvimento, pois o processo de ligar o tomcat pode demorar bastante tempo. Acontece que quando algo de errado acontece vários problemas imprevisíveis se propagam, consumindo tempo de desenvolvimento (a toa). É por este motivo que a maioria dos desenvolvedores java que conheço sempre desligam o tomcat para realizar um novo deploy. Além de chato é ineficiente.

Descobri que este problema é mais comum no Windows. Vou explicar o porquê. Quando um deploy é feito com um arquivo war, o seu conteúdo é descompactado na pasta webapps, e um arquivo de configurações xml é criado na pasta conf do tomcat. O processo de undeploy apaga o xml, o arquivo war e toda a pasta do context. Até aí tudo bem.

É comum, também, abrir com um navegador de pastas e arquivos, como o Windows Explorer, a pasta do contexto que se está desenvolvendo para verificar se está tudo correto, ou mesmo para atualizar arquivos jsp, por exemplo. Aí que está o problema. Se no Windows um arquivo fica aberto em um notepad, por exemplo, toda a estrutura de diretórios fica presa pelo processo do notepad, e o tomcat falha ao tentar efetuar o undeploy. Parte dos arquivos são apagados, e outros tantos ficam para trás.

Depois de um processo de undeploy falho como este o context não estará mais disponível para consulta no seu browser, mas se o mesmo context for reinstalado com um deploy, é bem provável que problemas estranhos surjam. Conheço gente que faz um undeploy no tomcat, um clean no projeto do eclipse, outro clean no ant, fecha o tomcat, abre o tomcat e finalmente faz o deploy. Outros, menos superticioso se contentam em fechar e abrir o tomcat. Chamo este processo, tanto o completo quanto o resumido, de macumbate. Uma espécie de padrão no desenvolvimento java para web.

No meu linux eu não tenho este problema. Dificilmente fecho o tomcat, e quando o faço é porque preciso atualizar alguma biblioteca do common/lib ou porque já fiz algumas dezenas de deploy e ocorre um problema de espaço em memória (PermGen).

Discussão sobre padrão Struts

No guj está rolando uma discussão sobre o padrão de desenvolvimento web com struts 1.

http://www.guj.com.br/posts/list/58008.java

Eu não gosto do Struts 1 porque vejo todo mundo confuso com os conceitos dele, e simplesmente ignorando a maior parte das automatizações do framework.

Infelizmente ainda não vejo um novo padrão despontar no lugar do Struts 1. Como “os grandes” devem apontar para o Struts 2 ou jsf, estou estudando para entender melhor estes dois frameworks.

Quando a distribuição sugere pacotes incompatíveis

Distribuições linux trazem um conjunto de coeso de componentes de sistema operacional e assessórios que juntos funcionam sem que haja conflitos. Ou pelo menos na teoria é assim.

Por acaso passei pelo mesmo problema duas vezes em menos de 24h. Primeiro ao instalar o tomcat no ubuntu 6.10 que opero na Assembléia, e hoje ao instalar o mesmo tomcat em um servidor Suse.

Ambas distribuições sugerem o uso do tomcat 5.0.30, mas quando se instala as ferramentas de administração do tomcat, o admin simplesmente não roda devido a uma incompatibilidade entre o struts da distribuição e os arquivos de configuração do admin. Em outras palavras: o sistema recomenda um struts incompatível com a recomendação do admin do tomcat.

Solução? Fazer como qualquer mortal faria, baixando o tomcat estável (5.0.28) do site da apache, que vem com o strutus adequado, processo relativamente tranquilo e rápido, apesar de não manter o santo padrão das distribuições (diretórios, autorizações…).

Agora, quando me argumentarem que tomcat só se instala em servidor com os YaSTs e apt-gets, posso dizer por experiência própria que nem sempre é o melhor.

Por último, para quem ainda não se convenceu: quando vou instalar o tomcat no SUSE o YaST sugere que se instale o java open source. Resultado: incompatibilidade com vários códigos java. Solução: instalar outro pacote do SUSE com o java da sun…

E se você só usa a tal distribuição só porque lhe garantiram que era a distribuição mais estável e que usar outra distribuição vai contra a política da empresa? Bem, daí só resta ficar resmungando nos blogs afora :-/