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

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.

Porque recomendei a compra de um software proprietário para a instituição publica que trabalho

Há dois anos a equipe de informática em que eu trabalhava precisou de uma ferramenta especifica para planejamento de sistemas com gráficos UML. Após alguns dias de testes com varias ferramentas, algumas livres e outras pagas, entendemos que as opcoes livres disponíveis eram muito instáveis e que não ofereciam todos os recursos necessários. As ferramentas preferidas foram o Argo UML e o Borland Together, a primeira livre e a segunda comercial. Aquela época o Argo não oferecia o pouco que precisávamos: uma boa ferramenta de diagrama de classes seria o suficiente. A versão testada era instável, tendo fechado varias vezes durante os testes sem nenhum motivo aparente. Optamos pela ferramenta comercial da Borland pois parecia ser a opcao que oferecia o menor custo ao Estado, considerando que a ferramenta era completa e estável e parte da equipe tinha vivencia com o ambiente Borland, o que significa uma importante economia com treinamento de pessoal. Por fim, o Together oferecia uma integração com a ferramenta livre Eclipse, utilizada pela equipe.

Feita a opcao passei um memorando expressando minha recomendação para a administração. Pouco mais de um semestre depois e passado um processo moroso de compra, a mesma foi concluída e recebemos o software, já defasado e incompatível com nossa versão de eclipse. No pedido de compra solicitamos uma versão especifica do Together, sem levar em conta de que durante o processo compra uma nova versão poderia ser lançada, como de fato aconteceu. Mas como eu poderia saber?

O infeliz desfecho é que trabalhos durante muito tempo sem documentação UML em função da ineficácia da administração em comprar o software em temp adequado. Hoje o Argo passou para um outro time de desenvolvedores, e aqueles bugs mais irritantes já foram corrigidos. Consigo gerar meus diagramas de classes tranquilamente e tenho uma exportação para código java bastante útil para projetos recém especificados. Vez por outra me pergunto se eu deveria ter me empenhado mais em fazer o processo de compra do Together andar mais rápido, mas acho que não. Teria sido um desperdício maior ainda me desviar da minha ocupação de desenvolvedor para desbravar o mundo desconhecido do processo administrativo de compra de software. Outras opcoes, como baixar o codigo fonte do Argo e desenvolver as funcionalidade eu mesmo eram custosas demais, e acabei deixando de lado. O software livre é uma tendencia interessante, cujas vantagens para os usuarios é inegavel, e para os desenvolvedores é quase sempre vantajoso. Determinar quais as condicoes em que vale a produzir um software livre é uma tarefa mais dificil do que parece.

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 :-/