Treinamento de JBoss na Dígitro

September 24th, 2008

No dia 12 de setembro começou, no Cliente Dígitro, em Florianópolis-SC, outra versão dos treinamentos de JBoss do Lado Servidor:

  1. Introdução a Java EE utilizando o JBoss AS, dia 12/Set;
  2. Administração básica do JBoss AS, dias 13, 14 e 26/Set;
  3. Arquitetura e funcionamento do JBoss AS, dias 27 e 28/Set, 11 e 12/Out;

Em breve estarei publicando aqui, alguns dos vídeos relativos a tarefas administrativas que desenvolvemos durante o treinamento.

Ant ou Gant?

September 24th, 2008

O Javalobby publicou este artigo com o mesmo título deste post (mas em inglês), escrito por Meera Subbarao. Eu achei bastante interessante e estou experimentando o Gant para tentar simplificar alguns scripts Ant que tenho que manter em meu trabalho.

Ao tentar utilizar o Gant no cygwin de um destkop em meu trabalho, eu obtive a seguinte falha:

  $ gant
  exception while configuring main class loader:
  java.io.FileNotFoundException: C;c:\pj\ferramentas\java\gant-1.4.0\conf\gant-starter.conf
  (A sintaxe do nome do arquivo, pasta ou nome do volume está incorreta)
      at java.io.FileInputStream.open(Native Method)
      at java.io.FileInputStream.<init>(FileInputStream.java:106)
      at java.io.FileInputStream.<init>(FileInputStream.java:66)
      at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:81)
      at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:130)

Fiz a correção modificacando os seguintes arquivos no Groovy e no GAnt:

  $ cd $GANT_HOME/bin
  $ diff gant.original gant
  62,63c62,63
  <     GANT_HOME=`cygpath --path --mixed "$GANT_HOME"`
  <     ANT_HOME=`cygpath --path --mixed "$ANT_HOME"`
  ---
  >     GANT_HOME=`cygpath --mixed "$GANT_HOME"`
  >     ANT_HOME=`cygpath --mixed "$ANT_HOME"`
  $ cd $GROOVY_HOME/bin
  $ diff startGroovy.original startGroovy
  197,199c197,199
  <     GROOVY_HOME=`cygpath --path --mixed "$GROOVY_HOME"`
  <     JAVA_HOME=`cygpath --path --mixed "$JAVA_HOME"`
  <     GROOVY_CONF=`cygpath --path --mixed "$GROOVY_CONF"`
  ---
  >     GROOVY_HOME=`cygpath --mixed "$GROOVY_HOME"`
  >     JAVA_HOME=`cygpath --mixed "$JAVA_HOME"`
  >     GROOVY_CONF=`cygpath --mixed "$GROOVY_CONF"`

Esta mudança se fez necessária em função de que o parâmetro –path do utilitário cygpath só faz sentido quando o parâmetro passado é uma lista contendo um caminho (PATH). Todas as variávies *_HOME não são listas de PATHs e sim um caminho único indicando o diretório de instalação de uma ferramenta.

Encaminhei este email para o Russel Winder, desenvolvedor do Gant, que prontamente respondeu-me dizendo que se a solução estiver OK para mim, ela será incorportada no próximo release do Gant.

Software livre é isto! Colaboração!!

Gerando apresentações S5 com o Txt2tags

June 10th, 2008

Eu já utilizo o Txt2tags para a geração de propostas de trabalho, escritas de artigos, sites, … e agora também, para gerar apresentações no formato S5!

Antes de entrar no assunto deste post propriamente dito, quero expressar minha opinião sobre o Txt2tags: ele é simples, inteligente e faz o que precisa ser feito, possibilitando que seu usuário seja criativo para resolver um problema de diferentes formas. Fabuloso! Apesar de atualmente vermos na Web cada vez mais e mais páginas dinâmicas serem criadas com o auxílio de ferramentas poderosas e cheias de recursos como Wikis, alternativas e flexibilidade tão grandes como as que são fornecidas pelo Txt2tags são menos visíveis nestas ferramentas. O uso de expressões regulares é o que garante tais características. Outro poder dado pelo Txt2tags, e muito importante para mim, é o de gerar, a partir de um único fonte, variados tipos de documentos: Txt, HTML, XHTML, Latex, …, e, com este post, pretendo demonstrar como gerar mais um: o S5.

Na verdade, o S5 (A Simple Standards-Based Slide Show Systemi) não é um novo formato de documento, mas sim, um código HTML carregado de folhas de estilo (CSS) e código JavaScript, que oferecem ao navegador, a possibilidade de mostrar uma página com marcações (divs) como se fosse uma apresentação escrita em OpenOffice, por exemplo. Eu tenho uma certa antipatia a ferramentas como este último, pela dificuldade que tenho para poder escrever links, e agregar formatos diferentes como vídeos, código, etc. Além disto, eu gosto mesmo de escrever é com o VIM. Como já disse várias vezes para alunos em cursos que ministrei e para colegas de trabalho, se me colocam um editor como gedit nas mãos, para editar algo, eu me sinto de braços e pernas quebradas… Imagina se pedissem pra trabalhar com um notepad ;-) Só pra concluir: um documento Txt2tags também pode ficar coloridinho e com a sintaxe destacada no VIM.

Vamos então ao que interessa, que é a explicação do exemplo que você poderá utilizar para criar suas próprias apresentações em S5, a partir do Txt2tags. Baixe o arquivo para sua máquina e descompacte-o em um diretório qualquer.

O arquivo urls.t2t (no diretório do exemplo) demonstra como eu criei URLs que podem ser adicionadas a um documento t2t qualquer, como no arquivo index.t2t. Lendo com calma o arquivo (sugiro que utilize o VIM, com a sintax para o t2t habilitada), você verá que os links deste documento são gerados através da utilização das expressões regulares comentadas (leia-os!). Analise bem estas expressões, pois elas dão poder e flexibilidade para criação de um documento qualquer, evitando o trabalho enfadonho de ficar escrevendo links de maneira repetida, como num texto HTML qualquer. Note também, as formas de utilizar o link, tanto numa expressão de pré-processamento %!preproc do documento t2t quanto numa com pós-processamento %!posproc.

O arquivo defs.t2t contém definições gerais e mais uma expressão regular mágica, utilizada no pós-processamento do documento (leia com atenção).

O arquivo s5-defs.t2t é responsável por incluir, no cabeçalho do HTML gerado para a apresentação S5, as folhas de estilo, o código JavaScript e também define alguns marcadores (que chamei de tags) para as divs que serão interpretadas pelo S5.

Os arquivos layout.t2t e header.t2t não contém expressões de pré ou pós processamento do Txt2tags mas sim, as tags que definem o layout da apresentação S5 e um cabeçalho que poderá ser compartilhado por várias apresentações neste mesmo formato.

Enfim, veja o exemplo, e ser ele for útil para você, sinta-se a vontade para copiá-lo, modificá-lo e/ou redistribuí-lo. Eu o criei porque precisava de algo simples para construir as apresentação para este curso. Mas, achei que seria uma boa contribuição para a comunidade Txt2tags a disponibilização do código.

Quero agradecer ao Aurélio pelas excelentes ferramentas Txt2tags e FuncoesZZ (que também utilizo bastante) e desejo que o livro Shell Script Profissional seja um sucesso de vendas! (Já adquiri minha cópia e realmente é um excelente livro).

Fontes deste artigo

Thread Dumps

May 30th, 2008

A obtenção de um thread dump ajuda a determinar o que um servidor está fazendo em um dado momento. Um thread dump lista todas as threads sendo executadas por uma aplicação Java e apresenta um stack trace para cada thread. Examinar um thread dump pode dar pistas de se um servidor está parando em determinados momentos. Por exemplo, assumindo que um servidor parou por algum motivo após uma aplicação ter sido iniciada, um thread dump pode ajudar a localizar a causa da parada.

A JVM produz um thread dump quando recebe um sinal QUIT. Este sinal pode ser enviado de várias formas, mas ele é geralmente enviado por um comando que envia sinais ou por uma combinação de teclas executadas na janela da aplicação Java em execução. No Unix/Linux, a combinação <ctrl>\ ou o comando kill -QUIT id-do-processo (equivale ao kill -3 id-do-processo) podem gerar um thread dump. No Windows, utilize a combinação <ctrl><break>. Outra forma, é utilizar a interface GUI do jconsole que vem com o JDK 5.

O jconsole contém seis abas que mostram diversas informações sobre uma aplicação em execução. Uma delas é nomeada Threads e provê as mesmas informações mostradas por um thread dump.

Para executar uma aplicação Java de forma que esta possa ser monitorada pelo jconsole é necessário iniciá-la com o argumento -Dcom.sun.management.jmxremote. No caso do JBoss AS por exemplo, este argumento pode ser informado na variável de ambiente JBOSS_OPTS ou nos scripts de inicialização (run.*).

O jconsole também pode ser utilizado para substituir as funções de gerenciamento oferecidas pelo jmx-console. Você pode ler mais a respeito e ver como realizar a configuração do JBoss para suportar o gerenciamento de seus MBeans pelo jconsole, lendo esta página no wiki do JBoss.

A listagem produzida por um thread dump é longa. Desta forma, para visualizá-la é interessante iniciar o JBoss AS com o comando abaixo que irá gerar toda a saída do console padrão e de erros para o arquivo jboss.log:

  $ run.sh >> jboss.log 2>&1

Monitore o arquivo jboss.log com o comando tail em um outro teminal e após perceber que o JBoss finalizou seu startup, execute a combinação de teclas <ctrl>\ na janela de execução do JBoss. Isto irá gerar um thread dump e também irá desvincular o JBoss AS do seu terminal corrente (sem entretanto, pará-lo).

Você poderá observar então o conteúdo do arquivo jboss.log que irá conter o thread dump. Ele irá conter uma lista de todas as threads que estão alocadas. Cada thread tem um nome e na maioria das vezes, este nome dá boas dicas da sua função. Você pode por exemplo adivinhar as funções das threads nomeadas “RMI TCP Accept-4444″ e “ScannerThread” não é? As threads listadas no início do thread dump são as que são utilizadas pelo JBoss e geralmente, as que estão no final são das da JVM. Segue uma lista de threads interessantes em execução no JBoss:

Nome da Thread Descrição
CompilerThread1 Utilizada para a compilação de código Java, geralmente JSPs. Pode haver tantas quanto forem os processadores da máquina. Elas não estão presentes se não estiver sendo executada alguma compilação
GC Daemon Utilizada para a execução do Garbage Collector. Esta thread está presente enquanto ele está sendo executado.
http-0.0.0.0-8080-1 Utilizada para processar requisições HTTP de algum cliente. O endereço IP (0.0.0.0) e a porta são variáveis de acordo com a conexão socket aberta. O dígito final varia por requisição

O stack trace abaixo da descrição da thread mostra a pilha de execução dos métodos executados pela thread no momento em que o thread dump foi gerado e é extremamente útil para se descobrir o que estava ocorredo naquele momento. Observando com calma, percebemos o que a thread estava fazendo:

  Name: http-0.0.0.0-8080
  State: RUNNABLE
  Total blocked: 0  Total waited: 0

  Stack trace:
  java.net.PlainSocketImpl.socketAccept(Native Method)
  java.net.PlainSocketImpl.accept(PlainSocketImpl.java:384)
  java.net.ServerSocket.implAccept(ServerSocket.java:450)
  java.net.ServerSocket.accept(ServerSocket.java:421)
  org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60)
  org.apache.tomcat.util.net.PoolTcpEndpoint.acceptSocket(PoolTcpEndpoint.java:407)
  org.apache.tomcat.util.net.PoolTcpEndpoint.run(PoolTcpEndpoint.java:647)
  java.lang.Thread.run(Thread.java:595)

Outra forma de se gerar um thread dump é através do jmx-console do JBoss ou do utilitário de linha de comando twiddle. Para obter um thread dump através do utilitário twiddle em um servidor linux, o seguinte comando poderia ser executado:

  $ twiddle.sh invoke jboss.system:type=ServerInfo listThreadDump

Para buscar mais informações a respeito deste assunto, sugiro que você leia:

Implantando aplicações no JBoss via suporte a WebDAV

May 29th, 2008

O Servidor JBoss AS suporta a implantação de diversos arquivos necessários para a execução de uma aplicação Java (*.[jewsr]ar *-ds.xml …) até mesmo se eles estiverem disponíveis em uma URL como, por exemplo, http://servidor/diretorio-com-suporte-a-WebDAV/. Este mecanismo é útil em diversas situações. Neste post, vou ilustrar um caso prático: suponhamos que você deseje instalar uma única instância do CruiseControl como a ferramenta responsável pelo processo de Integração Contínua de diversas aplicações que precisam ser implantadas em diferentes instâncias de JBoss, sendo executadas em várias máquinas distintas.

Uma possível solução para este problema é:

  • Configurar um servidor Apache na mesma máquina que roda o CruiseControl, ativando os módulos responsáveis pelo suporte ao WebDAV ou, de maneira alternativa, instalando um Servlet que ofereça este suporte ao container que executa o CruiseControl;
  • Configurar no Apache uma URL como, por exemplo, http://cruisecontrol.minhaempresa.com/aplicacaoX/ apontando para o diretório no qual serão gerados os arquivos da aplicação X que precisam ser implantados em uma instância de JBoss;
  • Configurar a URL anterior no JBoss para que o mesmo possa fazer uma busca (scan) (via comando PROPFIND do WebDAV) pelos arquivos da aplicação X, que estão disponíveis na URL;
  • Desabilitar o scan automático do JBoss, para que ele não perca o seu tempo tentando verificar se novas versões dos arquivos precisam ser implantadas ou não (ele será avisado sobre isto, pelo CruiseControl);
  • Fazer o script de controle do CruiseControl para o aplicação X enviar o comando scan para o JBoss, quando for finalizado o processo de geração (build) dos arquivos desta aplicação, a fim de que este servidor possa realizar a implantação destes arquivos;
  • Fazer o processo de testes da aplicação X (via JUnit ou TestNG por exemplo) ser iniciado apenas quando o processo de implantação no servidor terminar. Em alguns casos, principalmente na situação em que a implantação é responsável por gerar várias tabelas em um SGBD (como quando se utiliza a feature schemaexport do Hibernate), este processo pode ser um pouco lento, gerando então um pequeno atraso no início dos testes, que só deverão ser iniciados após a completa verificação de que a implantação foi finalizada e bem sucedida.

Uma observação sob esta solução é que, as máquinas que rodam as instâncias de JBoss que serão responsáveis pelas implantações das aplicações X, Y, …, não precisarão ter serviços como SSH remoto, FTP, NFS, ou quaisquer outros que possibilitem a cópia remota dos arquivos a serem implantados. Esta característica pode ser vista com bons olhos por analistas de segurança já que ela praticamente elimina a necessidade de acesso remoto ao servidor para fins de cópias de arquivo.

Ficaria muito extenso este post, se eu fosse entrar em detalhes sobre como realizar a configuração do CruiseControl, do Apache e de seu suporte ao WebDAV. Desta forma, vou apenas apenas dar algumas dicas de como proceder a configuração do JBoss para a realização de algumas tarefas:

  • Para desabilitar o scan automático do JBoss é necessário ajustar o valor do atributo ScanEnabled do MBean jboss.deployment:flavor=URL,type=DeploymentScanner para false. Isto é realizado no arquivo jboss-service.xml da configuração que será executada pelo JBoss;
  • Para incluir a URL que será acessada pelo JBoss a fim de que o mesmo possa verificar que arquivos estão em um diretório-com-suporte-a-WebDAV/ é necessário adicionar ao atributo URLs do mesmo MBean a URL a ser utilizada para o scan no servidor HTTP (note a barra final no fim da URL pois ela é ESSENCIAL). Exemplo:
      <attribute name="URLs">
          deploy/,http://servidor/diretorio-com-suporte-a-WebDAV/
      </attribute>
  • Para enviar o comando scan para o JBoss, ao final do processo de build da aplicação X, será necessário a execução de da operação operação scan do mesmo MBean. Isto pode ser feito de diversas formas, sendo que, uma delas é, através da inclusão das seguintes tasks em um script Ant (disponíveis em jars do diretório client do JBoss):
      <jmx>
          <invoke target="jboss.deployment:flavor=URL,type=DeploymentScanner" operation="scan"/>
      </jmx>
  • Para instanciar o JBoss (na versão 4.0.5) com o suporte ao scan de URLs com o suporte a WebDAV é preciso executar o run.{sh,bat} passando os parâmetros do exemplo abaixo (ATENÇÃO: se você esquecê-los tomará um TOCO ;-) do JBoss). E mais um pouco de atenção ainda: a informação abaixo é MUIIITOO difícil de ser encontrada em algum manual do JBoss. Fábio Sbano, um amigo Linuxer e Geek de trabalho na Andima, também colaborador do Lado Servidor, encontrou este detalhe no JIRA do JBoss para que pudesse fechar a solução abaixo. Desta forma, acho que seria legal a Red Hat rever a documentação e acertar com um pouco mais de ênfase pequenos detalhes como este nesta página ou nesta.
      $ run.sh -L commons-logging.jar -L commons-httpclient.jar -L webdavlib.jar
  • Caso você esteja utilizando a versão 4.2.2 do JBoss, para que o suporte ao WebDAV funcione, também é necessário que a biblioteca webdavlib.jar esteja disponível no diretório $JBOSS_HOME/lib (por algum motivo ela desapareceu nesta versão) e a linha de execução do run também deverá conter o parâmetro -L commmons-codec.jar, caso contrário, você também irá ter problemas.

É isto… em próximos posts, mais dicas!

Vídeo sobre as novas características do Glassfish v3

May 27th, 2008

Treinamento de JBoss na Cabal

May 16th, 2008

No sábado passado iniciei um treinamento de JBoss para o Cliente Cabal Brasil, em Brasília.
A Cabal foi minha Cliente em treinamentos que ministrei em parceria com a Argo Navis enquanto eu ainda possuia uma infra-estrutura para cursos abertos, no Terraço Shopping, em Brasília.
Agora, é com grande satisfação que posso atendê-los novamente, oferencendo os seguintes treinamentos:

  1. Introdução a Java EE utilizando o JBoss AS, de 10 a 17 de maio;
  2. Administração básica do JBoss AS, de 17 de maio a 7 de junho;
  3. Arquitetura e funcionamento do JBoss AS, de 26 de julho a 23 de agosto;

Este curso, fechado para a Cabal, ocorre aos sábados, das 10:00 às 17:00.