<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Destaquenet blog</title>
	<atom:link href="http://weblog.destaquenet.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.destaquenet.com</link>
	<description>O Blog da equipe Destaquenet</description>
	<pubDate>Mon, 27 Oct 2008 12:00:24 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Integração Contínua de aplicações Python com Hudson</title>
		<link>http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/</link>
		<comments>http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 12:00:24 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
		
		<category><![CDATA[Programação]]></category>

		<category><![CDATA[build]]></category>

		<category><![CDATA[configuração]]></category>

		<category><![CDATA[hudson]]></category>

		<category><![CDATA[integração contínua]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[open source]]></category>

		<category><![CDATA[plugin]]></category>

		<category><![CDATA[projeto]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[testes]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[unittest]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=166</guid>
		<description><![CDATA[No começo deste mês eu dei dicas sobre como usar o Fabric para automatizar o build e o deployment de aplicações Python.
Essa automatização por si só já quebra uma árvore, mas ela possibilita ainda o uso de Integração Contínua, uma prática extremamente importante que costuma ajudar muitas equipes a manter seus projetos nos trilhos. Para [...]]]></description>
			<content:encoded><![CDATA[<p>No começo deste mês <a href="http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/">eu dei dicas</a> sobre como usar o <a href="http://www.nongnu.org/fab/">Fabric</a> para automatizar o <em>build</em> e o <em>deployment</em> de aplicações <a href="http://python.org/">Python</a>.</p>
<p>Essa automatização por si só já quebra uma árvore, mas ela possibilita ainda o uso de Integração Contínua, uma prática extremamente importante que costuma ajudar muitas equipes a manter seus projetos nos trilhos. Para mais informações sobre Integração Contínua, eu recomendo a leitura <a href="http://martinfowler.com/articles/continuousIntegration.html">deste artigo</a>, até porque este <em>post</em> terá um enfoque mais prático.</p>
<p>Neste texto será mostrado como configurar um projeto Python no <a href="http://hudson.dev.java.net/">Hudson</a>, um servidor de Integração Contínua muito simples de configurar e utilizar. O sistema de controle de versões que eu utilizo aqui é o <a href="http://git.or.cz/">Git</a>, mas usuários de outros sistemas também poderão achar este texto útil.<span id="more-166"></span></p>
<h3>Baixando o Hudson</h3>
<p>Acesse o site do <a href="http://hudson.dev.java.net/">Hudson</a> e baixe o arquivo <code>.war</code> através do link disponível na página principal. Quando o download terminar, basta rodar o comando abaixo para subir o servidor na porta <code>8080</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">java <span style="color: #660033;">-jar</span> hudson.war</pre></div></div>

<div id="attachment_185" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson01.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson01-300x187.png" alt="Tela inicial do Hudson" title="Tela inicial do Hudson" width="300" height="187" class="size-medium wp-image-185" /></a><p class="wp-caption-text">Tela inicial do Hudson</p></div>
<p>Perca uns cinco minutos dando uma navegada no Hudson para ter uma idéia melhor do que é possível de ser feito com ele.</p>
<h3>Hudson e plugins</h3>
<p>O Hudson vem com suporte a <a href="http://maven.apache.org/">Maven</a> e <a href="http://ant.apache.org/">Ant</a>, duas das mais populares ferramentas para <em>build</em> de aplicações Java. Mas não se engane: o Hudson pode ser aproveitado em praticamente qualquer projeto, independente da linguagem e dos <em>frameworks</em> utilizados.</p>
<p>As funcionalidades do Hudson podem ser estendidas através de <em>plugins</em>, sendo que neste artigo utilizaremos dois deles: o <em>Git Plugin</em>, necessário para que o Hudson consiga trabalhar com repositórios Git, e o <em>Violations</em>, que consegue interpretar a saída de diferentes verificadores de código (dentre eles o <a href="http://www.logilab.org/857">pylint</a>, um analisador de código Python!) e exibir informações a respeito da qualidade do código-fonte.</p>
<p>Para instalar esses plugins, basta acessar a tela de gerenciamento de plugins, marcar o <em>Git Plugin</em> e o <em>Violations</em>, e confirmar:</p>
<div id="attachment_186" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson02.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson02-300x187.png" alt="Instalando os plugins" title="Instalando os plugins" width="300" height="187" class="size-medium wp-image-186" /></a><p class="wp-caption-text">Instalando os plugins</p></div>
<p>Assim que a instalação terminar, reinicie o Hudson.</p>
<h3>Integrando testes escritos com PyUnit ao Hudson</h3>
<p>Apesar de existirem várias opções para criação e execução de testes unitários para Python, o <a href="http://pyunit.sourceforge.net/">PyUnit</a> costuma ser o mais usado pelo fato de já estar incluído na distribuição padrão do Python.</p>
<p>Quem já fuçou no código do PyUnit sabe que ele define <strong>apenas um</strong> <code>TestRunner</code>, o <a href="http://pyunit.sourceforge.net/pyunit.html#RUNNING_INT"><code>TextTestRunner</code></a>. O que este <code>TestRunner</code> basicamente faz é gerar em um fluxo qualquer (geralmente no <code>sys.stderr</code>) uma saída parecida com a seguinte:</p>
<pre>.....
----------------------------------------------------------------------
Ran 5 tests in 0.067s</pre>
<p>Apesar de eu me contentar com essa saída mais simples, bom, ferramentas como o próprio Hudson <strong>não se contentam</strong>; elas preferem algo como o bom e velho XML, que, convenhamos, é muito mais fácil de parsear.</p>
<p>Perdi algumas horas na Internet procurando por um <code>TestRunner</code> que conseguisse gerar arquivos XML no mesmo formato que os gerados pelo Ant e Maven, mas não encontrei nenhuma opção que fosse minimamente confiável. Por isso, eu tomei a liberdade de escrever meu próprio <code>TestRunner</code>: <a href="http://github.com/danielfm/unittest-xml-reporting/tree">XMLTestRunner</a>. O código deste &#8220;projeto&#8221;, disponibilizado no <a href="http://github.com/">Github</a>, contém instruções de uso e scripts de exemplo. <strong>Clonem e forkem à vontade!</strong></p>
<p>Antes de prosseguirmos, baixe o módulo <code>xmlrunner.py</code> do <a href="http://github.com/danielfm/unittest-xml-reporting/tree">site do projeto</a> e o copie em algum lugar dentro do seu <code>PYTHONPATH</code>.</p>
<h3>Integrando um projeto Python no Hudson</h3>
<p>Para não perdermos tempo criando do zero um projeto de exemplo em Python, eu mostrarei como fazer para integrar o próprio <code>XMLTestRunner</code> com o Hudson.</p>
<p>Abra o console administrativo do Hudson e clique no link <em>New Job</em>:</p>
<div id="attachment_214" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson03.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson03-300x172.png" alt="Criando um projeto &quot;free-style&quot;" title="Criando um projeto &quot;free-style&quot;" width="300" height="172" class="size-medium wp-image-214" /></a><p class="wp-caption-text">Criando um projeto &quot;free-style&quot;</p></div>
<p>Na próxima tela, precisamos configurar o Job com os dados necessários:</p>
<div id="attachment_215" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson04.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson04-300x172.png" alt="Configuração de projeto" title="Configuração de projeto" width="300" height="172" class="size-medium wp-image-215" /></a><p class="wp-caption-text">Configuração de projeto</p></div>
<div id="attachment_216" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson05.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson05-300x172.png" alt="Configuração de projeto" title="Configuração de projeto" width="300" height="172" class="size-medium wp-image-216" /></a><p class="wp-caption-text">Configuração de projeto</p></div>
<p>Isso é tudo! Confirme as alterações e clique no link <em>Build now</em>. Aguarde alguns segundos enquanto o projeto é baixado do repositório Git e testado:</p>
<div id="attachment_220" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson06.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson06-300x172.png" alt="Exemplos de builds feitos pelo Hudson" title="Exemplos de builds feitos pelo Hudson" width="300" height="172" class="size-medium wp-image-220" /></a><p class="wp-caption-text">Exemplos de builds feitos pelo Hudson</p></div>
<div id="attachment_238" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson07.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson07-300x172.png" alt="Relatório de execução de testes" title="Relatório de execução de testes" width="300" height="172" class="size-medium wp-image-238" /></a><p class="wp-caption-text">Relatório de execução de testes</p></div>
<div id="attachment_239" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson08.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson08-300x172.png" alt="Análise de código feita pelo pylint" title="Análise de código feita pelo pylint" width="300" height="172" class="size-medium wp-image-239" /></a><p class="wp-caption-text">Análise de código feita pelo pylint</p></div>
<h3>Como disparar o <em>build</em> de forma automática?</h3>
<p>Uma vez que o projeto tenha sido configurado corretamente, basta um clique do mouse para que o Hudson faça todo o trabalho sujo. O problema agora é lembrar de fazer o <em>build</em> sempre que alguém modificar código no repositório.</p>
<p>Felizmente, temos duas opções para nos livrar de mais essa tarefa manual: a primeira seria configurar, nas propriedades do Job, uma expressão Cron que indique de quanto em quanto tempo o <em>build</em> deve ser feito; a segunda alternativa é apenas disparar o <em>build</em> quando alguém modificar código no repositório.</p>
<p>Como acontece com outros sistemas de controle de revisão, o Git possui <em>hooks</em> que nos permite executar ações em determinados momentos. Esses <em>hooks</em> nada mais são do que scripts executáveis localizados no diretório <code>.git/hooks</code>.</p>
<p>Mas enfim, quando disparar o <em>build</em>? Se o repositório Git e o servidor Hudson não são capazes de se comunicar diretamente, talvez a única alternativa seja disparar o <em>build</em> periodicamente. Para isso, você deve configurar um ou mais <em>Build Triggers</em>, na tela de configuração do Job.</p>
<p>Entretanto,  se você mantém o repositório Git e o servidor Hudson na mesma máquina, ou mesmo em máquinas diferentes mas capazes de se comunicar via rede, podemos considerar a utilização dos <em>hooks</em> como ferramenta de integração entre o repositório Git e o Hudson.</p>
<p>Agora a pergunta que não quer calar: <strong>como integrar o Git e o Hudson?</strong> Bem, isso ficará como exercício para o leitor.</p>
<p>Dicas:</p>
<ul>
<li>O Hudson <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Remote+access+API">disponibiliza uma API</a> através da qual se pode agendar <em>builds</em>, alterar as configurações do Job, criar Jobs, entre outras coisas.</li>
<li>Para conhecer os <em>hooks</em> oferecidos pelo Git, consulte a <a href="http://www.kernel.org/pub/software/scm/git/docs/githooks.html">documentação</a>.</li>
</ul>
<h3>Conclusão</h3>
<p>Já faz algum tempo que eu venho utilizando o Hudson para integrar projetos Java, e esta ferramenta vem se mostrando muito útil no meu dia-a-dia. Só quem pratica Integração Contínua sabe o quanto é complicado não contar com a segurança que ela proporciona ao desenvolvimento.</p>
<p>O problema, no entanto, começou quando eu optei pelo Python em vez do Java em certos projetos. Obviamente, eu queria aproveitar o ambiente de Integração Contínua que eu já utilizava, o que foi bastante complicado já que o PyUnit, <em>framework</em> de testes que eu costumo utilizar, não oferece uma forma de gerar relatórios XML, da mesma forma que Ant e Maven fazem.</p>
<p>Depois de estudar o funcionamento interno do PyUnit, eu decidi implementar um <code>TestRunner</code> que fosse capaz de gerar arquivos XML no formato esperado pelo Hudson. Deu um bocado de trabalho, é verdade, mas pelo menos agora eu consigo utilizar os excelentes relatórios gerados pelo Hudson para acompanhar a execução dos meus testes PyUnit.</p>
<p>Como o Brasil é grande, seria burrice achar que eu fui o único a enfrentar esse tipo de dificuldade. Por esse motivo, eu resolvi escrever este texto e, quem sabe, ajudar àqueles que enfrentam um problema semelhante.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails Summit Latin America &#8216;08: eu vou!</title>
		<link>http://weblog.destaquenet.com/2008/10/13/rails-summit-latin-america-08-eu-vou/</link>
		<comments>http://weblog.destaquenet.com/2008/10/13/rails-summit-latin-america-08-eu-vou/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 03:01:41 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
		
		<category><![CDATA[Off Topic]]></category>

		<category><![CDATA[brasil]]></category>

		<category><![CDATA[evento]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[rails summit]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=157</guid>
		<description><![CDATA[Todos já devem estar sabendo, mas vale a pena repetir que irá rolar em Sampa, nos dias 15 e 16 de Outubro, o evento Rails Summit Latin America.
Minha expectativa em relação a este evento em particular é muito boa. Apesar de já terem ocorrido outros eventos dedicados ao Ruby on Rails aqui no Brasil, os [...]]]></description>
			<content:encoded><![CDATA[<p>Todos já devem estar sabendo, mas vale a pena repetir que irá rolar em Sampa, nos dias 15 e 16 de Outubro, o evento <a href="http://www.locaweb.com.br/railssummit/">Rails Summit Latin America</a>.</p>
<p>Minha expectativa em relação a este evento em particular é muito boa. Apesar de já terem ocorrido outros eventos dedicados ao <a href="http://rubyonrails.org/">Ruby on Rails</a> aqui no Brasil, os organizadores desse evento em particular resolveram levar a coisa toda a um outro nível.</p>
<p>Citando o site do evento:</p>
<blockquote><p>
O Rails Summit Latin America surge para completar a agenda dos grandes eventos mundiais de Ruby on Rails™. Inspirado na RailsConf americana que reúne cerca de 2.000 desenvolvedores e tomadores de decisão, o Rails Summit Latin America trará os principais palestrantes e especialistas no assunto do mundo inteiro incluindo participação especial do criador do Ruby on Rails™, David Hansson.</p>
<p>Com diversos palestrantes internacionais e empreendedores brasileiros, o evento será referência sobre o assunto na América Latina, trazendo o que há de melhor na plataforma para o Brasil.
</p></blockquote>
<p>Para quem não se inscreveu, corra que ainda dá tempo. (eu acho!) <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Nos vemos por lá!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/10/13/rails-summit-latin-america-08-eu-vou/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Deployment de aplicações Python com Fabric</title>
		<link>http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/</link>
		<comments>http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 10:00:05 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
		
		<category><![CDATA[Programação]]></category>

		<category><![CDATA[capistrano]]></category>

		<category><![CDATA[deployment]]></category>

		<category><![CDATA[dicas]]></category>

		<category><![CDATA[django]]></category>

		<category><![CDATA[fabric]]></category>

		<category><![CDATA[ferramenta]]></category>

		<category><![CDATA[python]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=101</guid>
		<description><![CDATA[Uma coisa é fato: subir uma nova versão de uma aplicação é um procedimento que, se feito manualmente, costuma demandar tempo precioso, independente do tamanho da aplicação e dos frameworks utilizados no projeto. Não há o que discutir.
Na verdade, ninguém parecia se importar em automatizar tarefas &#8220;mecânicas&#8221; como o deployment, coisa que mudou de figura [...]]]></description>
			<content:encoded><![CDATA[<p>Uma coisa é fato: subir uma nova versão de uma aplicação é um procedimento que, se feito manualmente, costuma demandar tempo precioso, independente do tamanho da aplicação e dos <em>frameworks</em> utilizados no projeto. Não há o que discutir.</p>
<p>Na verdade, ninguém parecia se importar em automatizar tarefas &#8220;mecânicas&#8221; como o <em>deployment</em>, coisa que mudou de figura ao passo que <a href="http://en.wikipedia.org/wiki/Agile_software_development">metodologias ágeis</a> &#8212; juntamente com técnicas como <a href="http://martinfowler.com/articles/continuousIntegration.html">Integração Contínua</a> &#8212; passaram a se tornar populares. Desde então, algum esforço vem sendo investido para criar ferramentas para automatização de muitas dessas tarefas. <span id="more-101"></span></p>
<h3>Fabric: ferramenta Python para deployment</h3>
<p>Apesar de já ter utilizado algumas dessas <a href="http://maven.apache.org/">ferramentas</a> no desenvolvimento de projetos em <a href="http://java.sun.com/">Java</a>, plataforma na qual eu possuo uma experiência maior, eu ainda não conhecia nenhuma ferramenta em <a href="http://python.org/">Python</a> que me permitisse automatizar o <em>deployment</em> de uma aplicação.</p>
<p>Como eu estava começando a ficar de saco cheio de ter que atualizar os arquivos de uma aplicação <a href="http://djangoproject.org/">Django</a> via SCP, eu resolvi que já era hora de ir atrás de alguma ferramenta que me ajudasse a automatizar esse processo. Finalmente, depois de muita procura, eu encontrei <a href="http://www.nongnu.org/fab/index.html">Fabric</a>, uma ferramenta mais ou menos parecida com um <a href="http://www.capify.org/">Capistrano</a> &#8220;capado&#8221;.</p>
<p>A instalação do Fabric é bem simples para quem costuma usar o <a href="http://peak.telecommunity.com/DevCenter/EasyInstall">easy_install</a>:</p>
<pre>daniel ~ $ sudo easy_install Fabric</pre>
<p>Basta executar esse comando para que os fontes da última versão do Fabric (0.0.9 no momento da publicação deste texto) sejam baixados e instalados.</p>
<p><strong>Atenção</strong>: Quem utiliza máquinas Windows, provavelmente precisará do <a href="http://www.cygwin.com/">Cygwin</a>, já que o Fabric assume o uso de ambientes Unix.</p>
<h3>Fabric a 3.000 pés</h3>
<p>Neste momento você já deve conseguir executar o comando <code>fab</code> no terminal. Se tudo correu bem até aqui, estamos prontos continuar.</p>
<p>Vamos começar criando o arquivo <code>fabfile.py</code> no diretório-raíz da aplicação. Coloque o seguinte conteúdo neste arquivo:</p>

<div class="wp_syntax"><div class="code"><pre class="python python" style="font-family:monospace;"><span style="color: #008000;">set</span><span style="color: black;">&#40;</span>
    project = <span style="color: #483d8b;">'project_name'</span>,
&nbsp;
    package     = <span style="color: #483d8b;">'$(project).zip'</span>,
&nbsp;
    <span style="color: #808080; font-style: italic;"># Remote servers</span>
    fab_user    = <span style="color: #483d8b;">'usuario_ssh'</span>,
    fab_hosts   = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'servidor1.com'</span>, <span style="color: #483d8b;">'servidor2.com'</span><span style="color: black;">&#93;</span>,
<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> deploy<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Deploy the application to the production servers.&quot;</span>
    build<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> build<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Build the application.&quot;</span>
    prepare<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> prepare<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Prepare the build directory.&quot;</span>
    clean<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> clean<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Remove the build directory.&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

<p>Cada método definido no arquivo é equivalente a uma <em>task</em> do Capistrano. No início temos o método <code>set</code> que nos permite configurar as variáveis necessárias para o <em>script</em>. Veja que, neste método <code>set</code>, indicamos na variável <code>fab_hosts</code> os servidores nos quais os comandos remotos devem ser executados.</p>
<p>Ok, tente executar o comando <code>fab</code> no terminal, no mesmo diretório onde se encontra o arquivo <code>fabfile.py</code>. Se tudo correr bem, você receberá a seguinte saída:</p>
<pre>daniel ~  $  fab
   Fabric v. 0.0.9, Copyright (C) 2008 Christian Vest Hansen.
   Fabric comes with ABSOLUTELY NO WARRANTY; for details type `fab warranty'.
   This is free software, and you are welcome to redistribute it
   under certain conditions; type `fab license' for details.

No commands given.
Available commands are:
   build    : Build the application.
   clean    : Remove the build directory.
   deploy   : Deploy the application to the production servers.
   help     : Display Fabric usage help, or help for a given command.
   license  : Display the Fabric distribution license text.
   list     : Display a list of commands with descriptions.
   prepare  : Prepare the build directory.
   set      : Set a Fabric variable.
   shell    : Start an interactive shell connection to the specified hosts.
   warranty : Display warranty information for the Fabric software.
Done.</pre>
<p>Veja que as <em>tasks</em> que criamos estão disponíveis para serem executadas via linha de comando. Para executar as <em>tasks</em> <code>clean</code> e <code>deploy</code>, por exemplo, utilizaríamos o seguinte comando:</p>
<pre>daniel ~  $  fab clean deploy</pre>
<p>Simples, não é? Antes de vermos um exemplo de script completo, vamos conhecer os três principais métodos utilizados em <em>scripts</em> Fabric: <code>local</code>, <code>run</code> e <code>put</code>:</p>
<ul>
<li><code>local</code>: Serve para executar comandos na máquina local. Ex: <code>local('mkdir build')</code>;</li>
<li><code>run</code>: Igual ao <code>local</code>, mas executa os comandos nas máquinas remotas (indicadas na variável <code>fab_hosts</code>);</li>
<li><code>put</code>: Envia um arquivo para as máquinas remotas. Ex: <code>put('arquivo.zip', '/home/user/app.zip')</code>.</li>
</ul>
<p>Antes de prosseguirmos, vamos voltar a olhar a chamada ao método <code>set</code>, no início do código. Nele, eu usei um recurso do Fabric conhecido como <em>lazy evaluation</em>. No caso, temos a variável <code>package</code> que recebe o valor <code>'$(project).zip'</code>. Esse <code>$(project)</code> indica que queremos que o valor da variável <code>project</code> substitua o <em>placeholder</em>. Isso permite que variáveis sejam interpoladas umas dentro das outras.</p>
<p>Por exemplo, se dentro de uma <em>task</em> executarmos o comando <code>local('rm $(package)')</code>, isso significa que o Fabric irá parsear a string, transformando-a em <code>'rm project_name'</code> para só então executar tal comando na máquina local.</p>
<p>Como veremos a seguir, eu utilizei este recurso exaustivamente no meu <em>script</em>. Em caso de dúvidas, consulte a <a href="http://www.nongnu.org/fab/user_guide.html">documentação</a> do Fabric.</p>
<h3>Finalmente, o script completo!</h3>
<p>Antes de mostrar o <em>script</em> que eu venho utilizando para fazer o deployment <a href="http://www.destaquenet.com/">de uma aplicação</a> Django, veja como seus arquivos e diretórios estão organizados: (isso deve ajudar a entender melhor o <em>script</em>)</p>
<div id="attachment_131" class="wp-caption aligncenter" style="width: 214px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/destaqueweb_structure.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/destaqueweb_structure-204x300.png" alt="Estrutura do projeto" title="Estrutura do projeto" width="204" height="300" class="size-medium wp-image-131" /></a><p class="wp-caption-text">Estrutura do projeto</p></div>
<p>E, finalmente, o <em>script</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="python python" style="font-family:monospace;"><span style="color: #008000;">set</span><span style="color: black;">&#40;</span>
    project = <span style="color: #483d8b;">'destaqueweb'</span>,
&nbsp;
    <span style="color: #808080; font-style: italic;"># Build output directory</span>
    build_path  = <span style="color: #483d8b;">'build'</span>,
    package     = <span style="color: #483d8b;">'$(project).zip'</span>,
&nbsp;
    <span style="color: #808080; font-style: italic;"># Media</span>
    media_src   = <span style="color: #483d8b;">'media'</span>,
    media_root  = <span style="color: #483d8b;">'public_html'</span>,
    media_path  = <span style="color: #483d8b;">'$(media_root)/$(project)/$(media_src)'</span>,
    media_build = <span style="color: #483d8b;">'$(build_path)/$(media_path)'</span>,
&nbsp;
    <span style="color: #808080; font-style: italic;"># Application code</span>
    app_root  = <span style="color: #483d8b;">'wsgi_apps'</span>,
    app_path  = <span style="color: #483d8b;">'$(app_root)/$(project)'</span>,
    app_build = <span style="color: #483d8b;">'$(build_path)/$(app_path)'</span>,
&nbsp;
    <span style="color: #808080; font-style: italic;"># Remote servers</span>
    fab_user    = <span style="color: #483d8b;">'destaquenet'</span>,
    fab_hosts   = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'destaquenet.com'</span><span style="color: black;">&#93;</span>,
&nbsp;
    destination = <span style="color: #483d8b;">'/home/destaquenet'</span>,
    touch       = <span style="color: #483d8b;">'$(destination)/$(media_root)/$(project)/index.wsgi'</span>,
<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> deploy<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Deploy the application to the production server.&quot;</span>
    build<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Upload the zip file</span>
    put<span style="color: black;">&#40;</span><span style="color: #483d8b;">'$(build_path)/$(package)'</span>, <span style="color: #483d8b;">'$(destination)/$(package)'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Extract the zip file</span>
    run<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cd $(destination); unzip -uo $(package); rm $(package)'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Reload the application</span>
    run<span style="color: black;">&#40;</span><span style="color: #483d8b;">'touch $(touch)'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> build<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Build the application.&quot;</span>
    prepare<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Copy application files to the build directory</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cp -R $(project)/* $(build_path)/$(app_path)'</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cp -R $(media_src)/* $(build_path)/$(media_path)'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Remove unecessary files</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'find $(build_path) -name *.pyc -delete'</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'find $(build_path) -path *upload* -delete'</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'find $(build_path) -path *fixtures* -delete'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Create the zip file</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'cd $(build_path);zip -r $(package) $(media_root) $(app_root)'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> prepare<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Prepare the build directory.&quot;</span>
    clean<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'mkdir -p $(media_build)'</span><span style="color: black;">&#41;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'mkdir -p $(app_build)'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> clean<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;Remove the build directory.&quot;</span>
    local<span style="color: black;">&#40;</span><span style="color: #483d8b;">'rm -fR $(build_path)'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Este código deve ser facilmente entendido por quem tem trabalha com uma certa facilidade no terminal.</p>
<p>Basicamente o que o código faz é organizar os arquivos da aplicação para que estes fiquem dispostos da mesma forma utilizada pelo servidor de produção, enviar os arquivos dentro de um pacote ZIP para os servidores e descompactá-los no local correto, além de executar um <code>touch</code> no <em>script</em> <acronym title="Web Server Gateway Interface">WSGI</acronym> para que o <a href="http://apache.org/">Apache</a> recarregue a aplicação.</p>
<p>Tudo pronto. Agora basta executar <code>fab deploy</code> no terminal para subir a aplicação para o(s) servidor(es) desejado(s).</p>
<h3>Fabric e ambiente de homologação</h3>
<p>Uma coisa que vem se tornando comum é o uso de diferentes ambientes onde uma aplicação costuma ser implantada (ex: ambiente de homologação). Se sua empresa costuma trabalhar dessa forma, o Fabric ainda pode te ajudar.</p>
<p>Por exemplo, vamos supor que sua empresa possua um servidor de produção e um servidor de homologação. Podemos, então, adequar o <em>script</em> para que ele possa trabalhar com ambos os ambientes:</p>

<div class="wp_syntax"><div class="code"><pre class="python python" style="font-family:monospace;"><span style="color: #008000;">set</span><span style="color: black;">&#40;</span>
    <span style="color: #808080; font-style: italic;"># ...</span>
    fab_user = <span style="color: #483d8b;">'production'</span>,
    fab_hosts = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'app.com'</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> staging<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># deploy to staging servers</span>
    <span style="color: #008000;">set</span><span style="color: black;">&#40;</span>fab_user = <span style="color: #483d8b;">'staging'</span>, fab_hosts = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'staging.app.com'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># other tasks...</span></pre></div></div>

<p>Fazendo as mudanças mostradas acima, para executar o <em>deployment</em> no ambiente de homologação basta rodar o comando <code>fab staging deploy</code>; o deployment em ambiente de produção continua disponível através do comando <code>fab deploy</code>.</p>
<p>Isso é possível pois podemos substituir o valor de uma variável (ou configurar novas variáveis) a qualquer momento, através do método <code>set</code>. Então, quando executamos o comando <code>fab staging deploy</code>, o Fabric executa a <em>task</em> <code>staging</code>, substituindo o valor das variáveis <code>fab_user</code> e <code>fab_hosts</code>, fazendo com que os comandos contidos na <em>task</em> <code>deploy</code> sejam executados nos servidores de homologação em vez de nos servidores de produção.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Seaside: um framework web de verdade</title>
		<link>http://weblog.destaquenet.com/2008/09/30/seaside-um-framework-web-de-verdade/</link>
		<comments>http://weblog.destaquenet.com/2008/09/30/seaside-um-framework-web-de-verdade/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 01:44:39 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
		
		<category><![CDATA[Programação]]></category>

		<category><![CDATA[aplicação]]></category>

		<category><![CDATA[componentes]]></category>

		<category><![CDATA[continuations]]></category>

		<category><![CDATA[framework]]></category>

		<category><![CDATA[jogo]]></category>

		<category><![CDATA[seaside]]></category>

		<category><![CDATA[smalltalk]]></category>

		<category><![CDATA[squeak]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[web]]></category>

		<category><![CDATA[workflow]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=78</guid>
		<description><![CDATA[Provavelmente isso não é novidade para alguns de vocês, mas já faz algum tempo que eu venho me  aventurando pelo incrível mundo do Smalltalk. Dando prosseguimento à esta saga, tenho o orgulho de anunciar a minha próxima vítima: o framework Seaside!
O Seaside é um impressionante framework web escrito em Smalltalk focado no desenvolvimento de [...]]]></description>
			<content:encoded><![CDATA[<p>Provavelmente isso não é novidade para alguns de vocês, mas já faz algum tempo que eu venho me  aventurando pelo incrível mundo do <a href="http://en.wikipedia.org/wiki/Smalltalk">Smalltalk</a>. Dando prosseguimento à esta saga, tenho o orgulho de anunciar a minha próxima vítima: o <em>framework</em> <a href="http://seaside.st/">Seaside</a>!</p>
<p>O Seaside é um impressionante <em>framework web</em> escrito em Smalltalk focado no desenvolvimento de <del datetime="2008-10-01T00:58:21+00:00">sites</del> aplicações <em>stateful</em>. Mesmo conhecendo muito pouco a respeito do seu funcionamento &#8212; até então, nada além de um mísero <em>hello world</em> &#8212; resolvi tentar criar uma aplicação que realmente fizesse algo a mais do que simplesmente escrever um texto na tela.</p>
<p>A experiência foi muito boa, mas poderia ter sido melhor se o projeto contasse com uma documentação decente. O código do <em>framework</em> propriamente dito é muito bem documentado e é possível aprender bastante, mesmo tendo apenas o <em>Class Browser</em> do <a href="http://www.squeak.org/">Squeak</a> como recurso de pesquisa. Mas convenhamos: uma documentação <a href="http://djangobook.com/">como esta</a> ainda faz falta, principalmente para os aventureiros que, como eu, não fazem parte do <em>core team</em> do Seaside. <span id="more-78"></span></p>
<h3>Entendendo o exemplo</h3>
<p>Não mostrarei nada de muito complexo aqui, até porque eu também estou aprendendo. Mas o exemplo é interessante para conhecermos algumas das características principais do Seaside, que serão explicadas no decorrer deste <em>post</em>.</p>
<div id="attachment_79" class="wp-caption alignright" style="width: 215px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/state.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/state-205x300.png" alt="Diagrama de estados" title="Diagrama de estados" width="205" height="300" class="size-medium wp-image-79" /></a><p class="wp-caption-text">Diagrama de estados</p></div>Você conhece aquele jogo de &#8220;adivinhar o número&#8221;? Pois então&#8230; criaremos aqui algo parecido. Ao lado, você pode conferir uma imagem que ilustra como a aplicação deverá funcionar.</p>
<p>Ao abrir a aplicação, o usuário irá ver uma mensagem, que deverá confirmar para que o jogo comece. Quando o usuário confirma, o sistema gera um número aleatório entre 1 e 10 e mostra um formulário, que o usuário deve preencher com seu palpite. Em seguida, o sistema checa se o palpite do usuário corresponde ao número gerado aleatoriamente: se sim, o sistema mostra uma mensagem parabenizando o usuário; caso contrário, o sistema re-exibe o formulário, mostrando a contagem de &#8220;chutes&#8221; até o momento, além de uma mensagem com uma dica, para ajudar o usuário a adivinhar o número.</p>
<p>Esse ciclo continua até o usuário acertar. Por fim, o sistema pergunta se o usuário deseja jogar novamente: em caso afirmativo, um novo número é sorteado e o formulário re-exibido; senão, a mensagem de boas vindas é mostrada.</p>
<p>Ainda em relação ao diagrama, perceba que há um quadrado vermelho em torno de algumas atividades. Basicamente, isso quer dizer que a aplicação não deve permitir que o usuário volte (com o botão <em>back</em> do <em>browser</em>) e re-submeta um palpite após já tê-lo acertado. Em outras palavras, eu quero que as atividades dentro do quadrado vermelho representem um <em>workflow</em>, ou transação.</p>
<h3>Introdução</h3>
<p>O Seaside trabalha com o conceito de componentes. Neste exemplo, criaremos dois componentes para implementar a aplicação proposta. Um será responsável por controlar o fluxo de navegação do usuário pela aplicação, e o outro que receberá o <em>input</em> do usuário através de um formulário. Mas, antes de prosseguirmos, vamos aprender para que servem duas das mais importantes classes do Seaside: <code>WAComponent</code> e <code>WATask</code>.</p>
<p>A classe <code>WAComponent</code> será sua melhor amiga em um projeto Seaside, pois é através da criação de sub-classes de <code>WAComponent</code> que construímos a aplicação, pedaço por pedaço. Toda sub-classe de <code>WAComponent</code> deve implementar o método <code>#renderContentOn:</code>, pois é através deste que definimos como o componente deve ser renderizado no <em>browser</em> do usuário.</p>
<p>A classe <code>WATask</code>, por sua vez, é parecida com a classe <code>WAComponent</code> (de fato, ela a estende), com a diferença que ela não é usada para nada além de definir uma tarefa, ou melhor, a ordem com que outras tarefas e componentes devem ser chamados de modo a cumprir um determinado objetivo. Em poucas palavras: estenda <code>WATask</code> para definir <em>workflows</em>!</p>
<h3>Entendendo a interação entre os componentes</h3>
<p>Como pôde ser visto no diagrama de atividades mostrado anteriormente, o fluxo começa quando o usuário confirma que deseja jogar, passando o controle para o fomulário. O formulário é então renderizado no <em>browser</em> do usuário para que ele possa enviar um palpite. Em seguida, quando o usuário submete o formulário, o componente chamador (que é o próprio fluxo) recebe o palpite do usuário e o compara com o número gerado no início. Dependendo do resultado dessa comparação, o formulário é exibido novamente ou a mensagem de sucesso é mostrada.</p>
<p>Certo&#8230; talvez tenha ficado confusa a parte em que um componente &#8220;passa o controle&#8221; para outro. Esse é um conceito muito importante em um <em>framework</em> como o Seaside. Para entender essa coisa do &#8220;passa o controle&#8221;, imagine uma chamada de método comum:</p>

<div class="wp_syntax"><div class="code"><pre class="c c" style="font-family:monospace;"><span style="color: #993333;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span><span style="color: #339933;">**</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>; <span style="color: #666666; font-style: italic;">// chama o método (&quot;passa o controle&quot;)</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// faz algo aqui</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Neste exemplo de código C, quando chamamos um método, o fluxo de execução é modificado, fazendo com que o método chamado assuma o controle. Então, quando o método termina, o fluxo retorna ao método chamador.</p>
<p>Simples não? Agora imagine isso <strong>funcionando na web</strong>. Imagine que o método <code>main</code> do exemplo fosse um componente da nossa aplicação, e que esse componente pudesse passar o controle para <strong>outros</strong> componentes, assim como a chamada de método no exemplo, só que com a possibilidade de manter essa pilha de execução entre as requisições HTTP! Isso resolveria um monte de problemas, não é?</p>
<p>Felizmente, é assim que o Seaside trabalha. O conceito por trás disso é chamado de <a href="http://en.wikipedia.org/wiki/Continuation">Continuation</a>. A imagem a seguir tenta ilustrar o funcionamento disso no contexto do nosso exemplo:</p>
<p><div id="attachment_80" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/sequence.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/sequence-300x189.png" alt="Sequência de requisições" title="Sequência de requisições" width="300" height="189" class="size-medium wp-image-80" /></a><p class="wp-caption-text">Sequência de requisições</p></div>
<p>Se desconsiderarmos por um momento o modelo (limitado) de <em>request/response</em> no qual o protocolo HTTP se baseia, a sequência de interações do usuário para com a aplicação se parece com o especificado no diagrama acima. No diagrama, é como se tivéssemos uma pilha de chamadas que não se perde entre as requisições!</p>
<p>O foco deste <em>post</em> não é explicar a teoria por trás desses conceitos todos, portanto, se você tem interesse em saber mais sobre o assunto, use o Google! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Definindo o fluxo da aplicação</h3>
<p>Vamos criar o componente responsável por controlar o fluxo de navegação da aplicação. O componente a seguir estende <code>WATask</code> e possui as variávies de instância <code>number</code> e <code>form</code> que servem, respectivamente, para armazenar o número gerado e o formulário usado para receber o <em>input</em> do usuário:</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk smalltalk" style="font-family:monospace;"><span style="color: #0000ff;">WATask</span> subclass: <span style="color: #7f0000;">#GuessingAppComponent</span>
    instanceVariableNames: <span style="color: #7f0000;">'number form'</span>
    classVariableNames: <span style="color: #7f0000;">''</span>
    poolDictionaries: <span style="color: #7f0000;">''</span>
    category: <span style="color: #7f0000;">'GuessingApp'</span>
&nbsp;
<span style="color: #0000ff;">GuessingAppComponent</span> class&gt;&gt;canBeRoot
    ^<span style="color: #7f007f;">true</span>
&nbsp;
<span style="color: #007f00; font-style: italic;">&quot;Accessors for instance variables&quot;</span>
&nbsp;
<span style="color: #0000ff;">GuessingAppComponent</span>&gt;&gt;children
    ^ <span style="color: #0000ff;">Array</span> with: <span style="color: #7f007f;">self</span> form
&nbsp;
<span style="color: #0000ff;">GuessingAppComponent</span>&gt;&gt;initialize
    <span style="color: #007f00; font-style: italic;">&quot;Configure initial values&quot;</span>
&nbsp;
    <span style="color: #7f007f;">self</span> number: <span style="color: #00007f;">10</span> atRandom;
        form: <span style="">&#40;</span><span style="color: #0000ff;">GuessNumberForm</span> new<span style="">&#41;</span>
&nbsp;
<span style="color: #0000ff;">GuessingAppComponent</span>&gt;&gt;go
    <span style="color: #007f00; font-style: italic;">&quot;Start application workflow&quot;</span>
&nbsp;
    <span style="color: #7f007f;">self</span> inform: <span style="color: #7f0000;">'Start the game pushing the button below!!'</span>.
    <span style="">&#91;</span><span style="color: #7f007f;">self</span> initialize;
        <span style="">&#91;</span><span style="color: #7f007f;">self</span> call: <span style="color: #7f007f;">self</span> form.
            <span style="color: #7f007f;">self</span> form number &lt; <span style="color: #7f007f;">self</span> number
                ifTrue: <span style="">&#91;</span><span style="color: #7f007f;">self</span> form message: <span style="color: #7f0000;">'Try a higher value'</span><span style="">&#93;</span>
                ifFalse: <span style="">&#91;</span><span style="color: #7f007f;">self</span> form message: <span style="color: #7f0000;">'Try a lower value'</span><span style="">&#93;</span><span style="">&#93;</span>
                doWhileFalse: <span style="">&#91;</span><span style="color: #7f007f;">self</span> form number <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #7f007f;">self</span> number<span style="">&#93;</span><span style="">&#93;</span>
        doWhileTrue: <span style="">&#91;</span><span style="color: #7f007f;">self</span> confirm: <span style="color: #7f0000;">'You won the game using '</span> , <span style="color: #7f007f;">self</span> form guesses asString , <span style="color: #7f0000;">' guess(es)!! Play again?'</span><span style="">&#93;</span></pre></div></div>

<p>Todo o código é bem simples de se entender, com exceção do método <code>#go</code>. Veja que o corpo do método não passa de uma transcrição dos diagramas mostrados anteriormente. Atenção especial para a chamada <code>self call:</code>, que é o equivalente ao exemplo de chamada de método, com a diferença que estamos transferindo o controle para que outro componente possa executar no lugar do componente corrente. Perceba também que este método <strong>ainda não está pronto</strong>, pois, do jeito que está, a aplicação não está preparada para caso o usuário queira re-submeter um palpite após já tê-lo acertado&#8230; faremos isso depois! </p>
<h3>Recebendo o <em>input</em> do usuário</h3>
<p>Abaixo segue o código do componente usado para receber o palpite do usuário. O componente estende <code>WAComonent</code> e tem as variáveis de instância <code>number</code>, <code>message</code> e <code>guesses</code>. Essas variáveis servem, respectivamente, para: guardar o palpite do usuário quando o formulário é submetido; guardar a dica a ser exibida para o usuário (algo do tipo &#8220;chute um valor mais alto&#8221;, ou &#8220;mais baixo&#8221;); e guardar o número de vezes que o formulário foi submetido:</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk smalltalk" style="font-family:monospace;"><span style="color: #0000ff;">WAComponent</span> subclass: <span style="color: #7f0000;">#GuessNumberForm</span>
    instanceVariableNames: <span style="color: #7f0000;">'message number guesses'</span>
    classVariableNames: <span style="color: #7f0000;">''</span>
    poolDictionaries: <span style="color: #7f0000;">''</span>
    category: <span style="color: #7f0000;">'GuessingApp'</span>
&nbsp;
<span style="color: #007f00; font-style: italic;">&quot;Accessors for instance variables&quot;</span>
&nbsp;
<span style="color: #0000ff;">GuessNumberForm</span>&gt;&gt;increment
    <span style="color: #007f00; font-style: italic;">&quot;Increments the number of guesses&quot;</span>
&nbsp;
    <span style="color: #7f007f;">self</span> guesses: <span style="color: #7f007f;">self</span> guesses + <span style="color: #00007f;">1</span>
&nbsp;
<span style="color: #0000ff;">GuessNumberForm</span>&gt;&gt;initialize
    <span style="color: #007f00; font-style: italic;">&quot;Configure initial values&quot;</span>
&nbsp;
    <span style="color: #7f007f;">self</span> number: <span style="color: #00007f;">1</span>;
        message: <span style="color: #7f0000;">'Try a number between 1 and 10'</span>;
        guesses: <span style="color: #00007f;">0</span>.
&nbsp;
<span style="color: #0000ff;">GuessNumberForm</span>&gt;&gt;renderContentOn: <span style="color: #00007f;">html</span>
    <span style="color: #007f00; font-style: italic;">&quot;Render component&quot;</span>
&nbsp;
    html heading: <span style="color: #7f007f;">self</span> message level: <span style="color: #00007f;">4</span>.
    <span style="color: #00007f;">html</span> heading: <span style="color: #7f0000;">'You did '</span> , <span style="color: #7f007f;">self</span> guesses asString , <span style="color: #7f0000;">' guess(es) until now'</span> level: <span style="color: #00007f;">5</span>.
    <span style="color: #00007f;">html</span> form
        with: <span style="">&#91;</span><span style="color: #00007f;">html</span> textInput value: <span style="color: #7f007f;">self</span> number;
                callback: <span style="">&#91;</span>:<span style="color: #00007f;">value</span> | <span style="color: #7f007f;">self</span> increment; number: <span style="color: #00007f;">value</span> asInteger; answer<span style="">&#93;</span>.
            <span style="color: #00007f;">html</span> submitButton value: <span style="color: #7f0000;">'check my guess!!'</span><span style="">&#93;</span></pre></div></div>

<p>Novamente, a simplicidade impera. <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> A única coisa deste código que vale explicar é o método <code>#renderContentOn:</code>, que serve para que possamos definir o que deve ser retornado ao usuário quando o componente precisar ser renderizado. O método recebe um objeto <code>WAHtmlCanvas</code> por parâmetro, responsável por gerar código <acronym title="eXtended Hyper Text Markup Language">XHTML</acronym> automaticamente. Para quem tem conhecimentos em <acronym title="Hyper Text Markup Language">HTML</acronym>, o código é bem trivial, com exceção do método <code>#callback</code>, onde colocamos algum código para ser executado quando o formulário for submetido. Perceba a chamada a <code>self answer</code> no final da linha, que é responsável por devolver o controle ao componente chamador (o que executou <code>self call: form</code>).</p>
<h3>Demarcando uma transação</h3>
<p>Se lembra do quadrado vermelho no diagrama de atividades? Então&#8230; precisamos dar um jeito de impedir que o usuário volte a dar palpites após ter descoberto o número. Ou seja: precisamos definir uma <strong>transação</strong>.</p>
<p>Isso é feito utilizando o método <code>#isolate:</code>, conforme pode ser visto abaixo:</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk smalltalk" style="font-family:monospace;"><span style="color: #0000ff;">GuessingAppComponent</span>&gt;&gt;go
    <span style="color: #007f00; font-style: italic;">&quot;Start application workflow&quot;</span>
&nbsp;
    <span style="color: #7f007f;">self</span> inform: <span style="color: #7f0000;">'Start the game pushing the button below!!'</span>.
    <span style="">&#91;</span><span style="color: #7f007f;">self</span> initialize;
        isolate: <span style="">&#91;</span><span style="">&#91;</span><span style="color: #7f007f;">self</span> call: <span style="color: #7f007f;">self</span> form.
            <span style="color: #7f007f;">self</span> form number &lt; <span style="color: #7f007f;">self</span> number
                ifTrue: <span style="">&#91;</span><span style="color: #7f007f;">self</span> form message: <span style="color: #7f0000;">'Try a higher value'</span><span style="">&#93;</span>
                ifFalse: <span style="">&#91;</span><span style="color: #7f007f;">self</span> form message: <span style="color: #7f0000;">'Try a lower value'</span><span style="">&#93;</span><span style="">&#93;</span>
                doWhileFalse: <span style="">&#91;</span><span style="color: #7f007f;">self</span> form number <span style="color: #000066; font-weight:bold;">=</span> <span style="color: #7f007f;">self</span> number<span style="">&#93;</span><span style="">&#93;</span><span style="">&#93;</span>
        doWhileTrue: <span style="">&#91;</span><span style="color: #7f007f;">self</span> confirm: <span style="color: #7f0000;">'You won the game using '</span> , <span style="color: #7f007f;">self</span> form guesses asString , <span style="color: #7f0000;">' guess(es)!! Play again?'</span><span style="">&#93;</span></pre></div></div>

<p>Não tem mais código, não! É só envolver o trecho desejado em um bloco e passá-lo ao método <code>#isolate:</code>! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<h3>O resultado</h3>
<p>Confira abaixo algumas <em>screenshots</em> da aplicação em funcionamento:</p>
<div id="attachment_82" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/02.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/02-300x183.png" alt="Tela inicial" title="Tela inicial" width="300" height="183" class="size-medium wp-image-82" /></a><p class="wp-caption-text">Tela inicial</p></div>
<div id="attachment_84" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/03.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/03-300x183.png" alt="Lendo o palpite do usuário" title="Lendo o palpite do usuário" width="300" height="183" class="size-medium wp-image-84" /></a><p class="wp-caption-text">Lendo o palpite do usuário</p></div>
<div id="attachment_85" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/04.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/04-300x183.png" alt="Tela de acerto" title="Tela de acerto" width="300" height="183" class="size-medium wp-image-85" /></a><p class="wp-caption-text">Tela de acerto</p></div>
<div id="attachment_86" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/05.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/05-300x183.png" alt="Back button não permitido após término do jogo" title="Back button não permitido após término do jogo" width="300" height="183" class="size-medium wp-image-86" /></a><p class="wp-caption-text">Back button não permitido após término do jogo</p></div>
<p>O que há de errado com a última <em>screenshot</em>? Nada&#8230; é isso que acontece quando o usuário, após já ter adivinhado o número secreto, volta algumas telas com o botão <em>back</em> do <em>browser</em> e tenta re-submeter um formulário. Não cheguei a pesquisar, mas acredito que esta página seja customizável.</p>
<h3>Desafio</h3>
<p>Mesmo em uma aplicação simples como a que foi descrita aqui, fica evidente o quanto o Seaside é produtivo e simples (embora eu ainda não saiba usá-lo direito). <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>Portanto, proponho aos leitores deste <em>blog</em> que pensem no que deve ser feito para se criar uma aplicação <strong>igual</strong> (com as <strong>mesmas funcionalidades</strong>) a mostrada aqui (com a sua linguagem e <em>framework</em> preferidos). Tirando um ou outro, imagino que dê para contar nos dedos de uma só mão os <em>frameworks</em> capazes de fazer tanto com tão pouco. Enfim, sintam-se a vontade para expressar suas opiniões a respeito disso.</p>
<h3>Conclusão</h3>
<ul>
<li>Não precisei apelar para <em>frameworks</em> externos só para definir o <em>workflow</em> da aplicação;</li>
<li>Não precisei fazer gambiarras para controlar o estado da aplicação (lembrando que a aplicação <strong>suporta diversas instâncias</strong> do <em>browser</em> acessando a mesma aplicação <strong>concorrentemente</strong>);</li>
<li>Não precisei fazer gambiarras para tratar o botão <em>back</em> do <em>browser</em>;</li>
<li>Não precisei fazer gambiarras para que o código <acronym title="eXtended Hyper Text Markup Language">XHTML</acronym> gerado fosse válido;</li>
<li>Não precisei ficar reiniciando o servidor web ou fazendo <em>re-deploy</em> o tempo todo;</li>
<li>Não precisei pagar para conseguir um bom ambiente de desenvolvimento, pois o Squeak sozinho faz muito bem o serviço;</li>
</ul>
<p>É&#8230; acho que esses motivos já são o suficiente para que você dê uma olhada no Seaside. Se não for, santo Deus, o que mais você quer?! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/09/30/seaside-um-framework-web-de-verdade/feed/</wfw:commentRss>
		</item>
		<item>
		<title>6 lições que aprendi sobre desenvolvimento de softwares</title>
		<link>http://weblog.destaquenet.com/2008/09/28/6-licoes-que-aprendi-sobre-desenvolvimento-de-softwares/</link>
		<comments>http://weblog.destaquenet.com/2008/09/28/6-licoes-que-aprendi-sobre-desenvolvimento-de-softwares/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 15:30:20 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
		
		<category><![CDATA[Off Topic]]></category>

		<category><![CDATA[Programação]]></category>

		<category><![CDATA[dicas]]></category>

		<category><![CDATA[lições]]></category>

		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=60</guid>
		<description><![CDATA[É natural do ser humano aprender com os seus próprios erros. Quem aqui nunca vivenciou uma situação inusitada na qual mesmo tendo a impressão de que algo está errado, acabamos ignorando e seguindo em frente. E assim continua até que, num belo dia, a bomba explode e você pensa consigo mesmo: &#8220;eu sabia!&#8221;.
Essas situações, embora [...]]]></description>
			<content:encoded><![CDATA[<p>É natural do ser humano aprender com os seus próprios erros. Quem aqui nunca vivenciou uma situação inusitada na qual mesmo tendo a impressão de que algo está errado, acabamos ignorando e seguindo em frente. E assim continua até que, num belo dia, a bomba explode e você pensa consigo mesmo: &#8220;<strong>eu sabia</strong>!&#8221;.</p>
<p>Essas situações, embora aparentam ser ruins em um primeiro momento, são excelentes oportunidades para nos ensinar algumas coisas que provavelmente não aprenderíamos de outra forma. Aliás, talvez seja até mais fácil aprender com nossos próprios erros do que ler sobre isso em algum livro ou artigo. O problema é que nem sempre é fácil saber tirar algo de bom de situações problemáticas.</p>
<p>Por isso, tentarei fazer um gancho entre esse assunto e a área de desenvolvimento de <em>softwares</em>, mostrando algumas das lições em que aprendi errando. Também seria interessante se os leitores que se identificarem com o assunto também compartilhassem algumas lições que aprenderam em períodos turbulentos. Afinal, errar <strong>faz bem</strong>! <span id="more-60"></span></p>
<h3>Lição número 1: confie no código e não no documento</h3>
<p>Deixe-me contar uma experiência interessante que tive na faculdade. Certa vez, um de nossos professores chegou na aula, colocou no projetor um Diagrama de Classes e um Modelo Entidade-Relacionamento e disse para a sala:</p>
<blockquote><p>
Esse é o modelo de um sistema de locadora. Nesses diagramas vocês tem tudo o que é preciso pra fazer isso funcionar. Não quero nem saber se vocês não gostam do cara que está sentado do seu lado, se acha que ele tem chulé ou mau hálito; eu quero que vocês aí se organizem e me entreguem isso funcionando até o final da aula.
</p></blockquote>
<p>Enfim, todo mundo se levantou e começou a andar de um lado para o outro e, alguns momentos depois, tínhamos nos organizado para dar início a programação. Pois bem&#8230; depois de algum tempo programando o que estava nos diagramas, o professor se volta para a sala e diz, em tom de sarcasmo:</p>
<blockquote><p>
Vem cá, vocês não encontraram nada estranho, não?
</p></blockquote>
<p>Praticamente todo mundo da sala havia percebido que alguns relacionamentos estavam faltando, outros sobrando, outros com a multiplicidade incorreta, entre outras coisas. Ninguém só não havia dito nada antes por pensar que o diagrama era <strong>indefectível</strong>. Se isso aconteceu em um &#8220;projeto de mentira&#8221; com duas dúzias de pessoas, quem imagina o que pode acontecer em projetos com dezenas e dezenas de pessoas envolvidas?</p>
<p>O fato é que os erros foram colocados lá propositalmente e isso acabou me fazendo perceber que nem sempre um documento representa fielmente um sistema. O que <strong>sempre</strong> representa fielmente um sistema é o seu <strong>código-fonte</strong>!</p>
<p>Durante um tempo, trabalhei numa empresa onde praticamente tudo o que precisava ser desenvolvido era entregue aos programadores na forma de textos (para fins de documentação, diziam). Para você perceber a gravidade da situação, se eu implementasse exatamente o que estava escrito nas folhas que recebia, a chance do sistema sequer compilar era altíssima. Além do mais, as especificações normalmente vinham incompletas, o que fazia com que nós tivéssemos de nos preocupar não em simplesmente programar, mas também de tentar driblar possíveis falhas na especificação.</p>
<p>Eu confesso que, naquele tempo, a minha vontade era dar um tiro na minha própria cabeça. Mas hoje, olhando para trás, percebo que isso fez com que eu adquirisse algumas habilidades que não seriam desenvolvidas se as especificações chegassem perfeitas em minhas mãos.</p>
<h3>Lição número 2: escreva testes automatizados</h3>
<p>Novamente remetendo aos tempos da faculdade, eu não poderia ter escolhido um tema melhor para o meu <acronym title="Trabalho de Conclusão de Curso">TCC</acronym> do que o desenvolvimento de um <em>framework</em>. Me lembro que fui alertado dezenas de vezes pelos professores de que tratava-se de algo inusitado e que eu não teria direito de reclamar caso algo saísse errado. Bem ameaçador, não acha?</p>
<p>Apesar de assumir o desafio <strong>sozinho</strong> - pois a faculdade não dispunha de um orientador com experiência em <em>design</em> de <em>frameworks</em> - tudo correu bem nas primeiras semanas de desenvolvimento, afinal o código estava bonito e funcionava bem. O que mais eu poderia querer? Entretanto, um sério (e óbvio) problema foi se instalando sem que eu percebesse: <strong>a ausência de testes automatizados</strong>.</p>
<p>No começo, quando o <em>framework</em> possuía apenas algumas dezenas de classes - era fácil localizar e corrigir os problemas que apareciam. Mas, quanto mais o código crescia, menos controle eu tinha sobre ele. Fazer experimentações no código já não era mais seguro.</p>
<p>Nessa época eu já sabia como escrever testes e tudo mais. O meu grande equívoco foi pensar que, se poupasse o tempo utilizado na escrita dos testes, eu teria mais tempo para entregar aquilo que prometi no começo do ano. Obviamente, eu não poderia estar mais <strong>errado</strong>.</p>
<p>Escrever testes automatizados (e até mesmo levá-los a outro nível, como <a href="http://weblog.destaquenet.com/2008/09/18/test-driven-development-com-java-swing/">acontece</a> com o <a href="http://en.wikipedia.org/wiki/Test-driven_development"><acronym title="Test Driven Development">TDD</acronym></a>) é <strong>essencial</strong> para que as aplicações evoluam de forma consistente. Sem a segurança que tais testes proporcionam, é impossível garantir que o que foi feito hoje continue funcionando amanhã. Não testar o código é comparável a um <a href="http://en.wikipedia.org/wiki/Monopoly_%28game%29#Board">jogo de tabuleiros</a>, onde, num momento de azar, você acaba caindo numa casa que diz &#8220;volte à primeira casa&#8221;.</p>
<p>A grande lição que eu tirei disso foi aprender que os testes não servem unicamente para comprovar que tudo está funcionando (pois isso eu já sabia). Eu aprendi que deixar de escrever testes alegando falta de tempo é <strong>burrice</strong>. Falando nisso, ainda encontramos pessoas que dizem que testes são ruins porque &#8220;é mais código para dar manutenção&#8221;, ou &#8220;escrever testes consome tempo que não temos&#8221; ou ainda &#8220;mas quem vai testar os testes?&#8221;. Não irei responder a essas perguntas, mas posso dizer que são poucas as coisas que fazem tão bem a um <em>software</em> quanto a criação de testes automatizados.</p>
<h3>Lição número 3: desenvolva <em>software</em> para o cliente, não para a infraestrutura</h3>
<p>Algumas pessoas, ao se iniciar um novo projeto, já tenta desde o início juntar e configurar o <em>framework</em> de injeção de dependências, o <em>framework</em> web, o <em>framework</em> <acronym title="Object-Relational Mapping">ORM</acronym>, e por aí vai. A minha pergunta é: <strong>pra quê</strong>? Confesso que eu mesmo já fiz isso, mas devo dizer que trabalhar dessa forma não faz muito sentido na maioria dos casos.</p>
<p>Voltando aos tempos de faculdade, uma outra coisa que eu gostava era que nós montávamos os sistemas sem pensar em bancos de dados, latência da rede, essas coisas. Nosso banco de dados era nada mais que algumas instâncias de <code>LinkedHashSet</code>! Então, considerando que algumas <strong>boas práticas</strong> foram usadas e que  o sistema esteja funcionando em memória, trocar o mecanismo de persistência (ou lidar com qualquer outra questão de infraestrutura) era fácil.</p>
<p>Por exemplo, em um sistema de locadora, o caso de uso <strong>Alugar Filme</strong> não fará nada de diferente caso estejamos persistindo os objetos em um banco de dados em vez da memória. Da mesma forma, o caso de uso <strong>Reservar Filme</strong> (que envia uma mensagem para o usuário informando quando o filme está disponível) não mudará se trocarmos a implementação atual - que executa&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Filme disponível&quot;</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>&#8230;para uma outra que utiliza a <acronym title="Application Programming Interface">API</acronym> <a href="http://java.sun.com/products/javamail/">JavaMail</a> para enviar uma mensagem via <acronym title="Simple Mail Transfer Protocol">SMTP</acronym>. O que importa é que os objetos estão sendo armazenados em algum lugar e que o usuário é notificado de algum jeito quando o filme que ele reservou está disponível. Acredite, isso é o bastante durante boa parte do desenvolvimento de uma aplicação.</p>
<h3>Lição número 4: seja preguiçoso</h3>
<p>Uma coisa interessante que aprendi foi que nem todo programador preguiçoso é um bom programador, mas <strong>todo bom programador é preguiçoso</strong>!</p>
<p>Os bons desenvolvedores possuem um faro aguçado que os permite identificar situações nas quais soluções melhores podem ser adotadas de modo a diminuir esforços, tornando o código (e a aplicação de um modo geral) mais conciso e organizado. Alguns chamam tais situações de <strong>cheiros</strong> (ou <em>smells</em>), termo este que &#8220;pegou&#8221; após a publicação do livro <a href="http://www.amazon.com/exec/obidos/ASIN/0201485672">Refactoring: Improving the Design of Existing Code</a>, de <a href="http://www.martinfowler.com/">Martin Fowler</a>.</p>
<p>Para identificar tais situações, vamos começar do básico: o que um desenvolvedor de <em>software</em> mais costuma odiar em seu trabalho? <strong>Trabalho repetitivo</strong>. Se você precisa fazer uma determinada tarefa e tal tarefa exige a repetição de procedimentos que você suspeita serem supérfluos, então faça um favor para si mesmo: deixe sua preguiça <strong>trabalhar por você</strong>!</p>
<p>Não sei se você é assim, mas eu costumo aprender as coisas mais rapidamente através de exemplos&#8230; então, vamos a eles.</p>
<p>Imagine que você tenha sido selecionado para trabalhar no <em>deployment</em> de uma aplicação. Se você já tentou implantar uma aplicação &#8220;no braço&#8221;, certamente sabe que, se você for fazer o trabalho manualmente, terá de fazer sempre as mesmas coisas, <strong>indefinidamente</strong>. O <em>deployment</em> de uma aplicação simples poderia ser exemplificada da seguinte forma:</p>
<ol>
<li>Organizar as classes compiladas em uma estrutura de diretórios específica;</li>
<li>Copiar bibliotecas que devem estar disponíveis a nível de servidor (como <em>drivers</em> JDBC) no diretório de bibliotecas do <em>Container</em>;</li>
<li>Disponibilizar as bibliotecas usadas pela aplicação em um diretório específico;</li>
<li>Mover os descritores e arquivos de configuração aos locais apropriados;</li>
<li>Gerar um <acronym title="Web ARchive">WAR</acronym> ou <acronym title="Enterprise ARchive">EAR</acronym>;</li>
<li>Implantar o WAR ou EAR no <em>Container</em>;</li>
<li>(Re)iniciar o <em>Container</em> (caso este não suporte <em>hot deployment</em>).</li>
</ol>
<p>Veja que fazer o <em>deployment</em> de uma aplicação não é assim tão complicado, mas perceba que você terá de fazer essas mesmas tarefas <strong>sempre</strong> que você precisar rodar a aplicação. Trata-se de algo completamente <strong>mecânico</strong> e <strong>chato</strong>.</p>
<p>Neste exemplo, você teria <strong>duas opções</strong>: continuar fazendo isso manualmente até o dia da sua morte, ou criar um <em>script</em> para automatizar essa tarefa para você. O que você prefere?</p>
<h3>Cuidado com os extremos!</h3>
<p>Uma coisa importante é não levar essa lição ao <strong>extremo</strong> (como qualquer outra coisa). Querer achar uma solução mais simples para <strong>todos</strong> os problemas nem sempre é a melhor saída. Já dizia <a href="http://en.wikipedia.org/wiki/Albert_einstein">Albert Einstein</a>:</p>
<blockquote><p>
Faça as coisas o mais simples que você puder, porém não se restrinja às mais simples.
</p></blockquote>
<h3>Lição número 5: não tente adivinhar o futuro</h3>
<p>Um dos meus professores de faculdade nos contou sobre uma experiência que ele havia feito com outra classe. Ele propôs que os alunos, em grupos, implementassem um <strong>sistema qualquer</strong>, cuja única restrição era, ao se partir para a fase de implementação, o código <strong>deveria</strong> refletir <strong>exatamente</strong> o modelo criado no início do processo, e este, por sua vez, não <strong>poderia mais ser alterado</strong>! Bem no estilo <a href="http://en.wikipedia.org/wiki/Waterfall_model">Waterfall</a> mesmo. Loucura, não? Embora a tarefa não parecesse difícil para os alunos em um primeiro momento, nem é preciso dizer o quanto estavam enganados em relação a isso.</p>
<p>Adivinhem o resultado da experiência? Sistemas que pareciam &#8220;faltar uma perna&#8221;. Quer dizer, todos os sistemas funcionavam, mas <strong>não resolviam os problemas que deveriam</strong>. O interessante é que todos os projetos acabaram <strong>falhando</strong>, apesar de a maioria desses alunos terem escolhido desenvolver algo que conheciam <strong>bem</strong> (por terem experiências profissionais e tudo mais).</p>
<p>Graças às metodologias ágeis, essa coisa de se tentar prever o futuro está perdendo a força. Acho que todo mundo já entendeu que isso não serve de nada, que mudanças são inevitáveis. O melhor a fazer, então, é saber reagir frente a elas.</p>
<h3>Lição 6: aprenda que sempre&#8230;</h3>
<p>&#8230; há algo a aprender.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/09/28/6-licoes-que-aprendi-sobre-desenvolvimento-de-softwares/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Em tempos de Mega Sena acumulada&#8230;</title>
		<link>http://weblog.destaquenet.com/2008/09/27/em-tempos-de-mega-sena-acumulada/</link>
		<comments>http://weblog.destaquenet.com/2008/09/27/em-tempos-de-mega-sena-acumulada/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 01:06:11 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
		
		<category><![CDATA[Off Topic]]></category>

		<category><![CDATA[Programação]]></category>

		<category><![CDATA[desafio]]></category>

		<category><![CDATA[groovy]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[meme]]></category>

		<category><![CDATA[smalltalk]]></category>

		<category><![CDATA[squeak]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=56</guid>
		<description><![CDATA[Há algum tempo atrás eu acabei me deparando com um desafio bastante interessante proposto por Rodrigo Sol. O desafio em questão pede a criação do menor programa possível &#8212; em qualquer linguagem &#8212; para gerar um jogo da Mega Sena. Hehe, impressionante o poder de uma loteria acumulada sobre as pessoas!  
Seguem as regras [...]]]></description>
			<content:encoded><![CDATA[<p>Há algum tempo atrás eu acabei me deparando com <a href="http://macacochefe.blogspot.com/2007/08/code-contest-em-tempos-de-mega-sena.html">um desafio</a> bastante interessante proposto por <a href="http://macacochefe.blogspot.com/">Rodrigo Sol</a>. O desafio em questão pede a criação do menor programa possível &#8212; em qualquer linguagem &#8212; para gerar um jogo da Mega Sena. Hehe, impressionante o poder de uma loteria acumulada sobre as pessoas! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Seguem as regras do desafio nas palavras do próprio Rodrigo:</p>
<blockquote><p>
Escrever em qualquer linguagem de programação um programa que realize 100.000 sorteios de um numero entre 1 e 60 e mostre na tela os 6 mais freqüentes.</p>
<p>Ganha quem fizer o programa com o menor numero de linhas possíveis, lembrando que a linha considerada é a linha da unidade léxica da linguagem, portanto a seguinte linha em Java seria considerada duas: int i =0; sysout(i);
</p></blockquote>
<p>Como na época eu estava aprendendo <a href="http://groovy.codehaus.org/">Groovy</a>, não podia deixar esta oportunidade passar. E, de fato, não deixei! <span id="more-56"></span></p>
<p>Veja, abaixo, uma solução para o &#8220;problema&#8221; proposto, usando a linguagem Groovy:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">def</span> hist <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span>:<span style="color: #66cc66;">&#93;</span>, v
100000.<span style="color: #993399;">times</span><span style="color: #66cc66;">&#123;</span>hist<span style="color: #66cc66;">&#91;</span>v <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">+</span> <span style="color: #aaaadd; font-weight: bold;">Math</span>.<span style="color: #006600;">random</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">60</span> <span style="color: #000000; font-weight: bold;">as</span> <span style="color: #993333;">int</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">!</span>hist<span style="color: #66cc66;">&#91;</span>v<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">?</span> <span style="color: #cc66cc;">1</span> : hist<span style="color: #66cc66;">&#91;</span>v<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#125;</span>
<span style="color: #993399;">println</span> hist.<span style="color: #006600;">keySet</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #663399;">toList</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #663399;">sort</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">-</span>hist<span style="color: #66cc66;">&#91;</span>it<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#91;</span>0..5<span style="color: #66cc66;">&#93;</span>.<span style="color: #663399;">join</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">','</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Será que dá para reduzir ainda mais esse código?</p>
<p><strong>Update:</strong> Resolvi tentar resolver o mesmo problema, só que agora usando Smalltalk:</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk smalltalk" style="font-family:monospace;">|<span style="color: #00007f;"> s </span>|
<span style="color: #00007f;">s</span> <span style="color: #000066; font-weight:bold;">:=</span> <span style="">&#40;</span><span style="">&#40;</span><span style="color: #0000ff;">OrderedCollection</span> withAll: <span style="">&#40;</span><span style="">&#40;</span><span style="color: #00007f;">1</span> to: <span style="color: #00007f;">100000</span><span style="">&#41;</span> collect: <span style="">&#91;</span>:<span style="color: #00007f;">each</span> | <span style="color: #7f0000;">60</span> atRandom<span style="">&#93;</span><span style="">&#41;</span><span style="">&#41;</span> groupBy: <span style="">&#91;</span>:<span style="color: #00007f;">each</span> | each<span style="">&#93;</span> having: <span style="">&#91;</span>:<span style="color: #00007f;">each</span> | <span style="color: #7f007f;">true</span><span style="">&#93;</span><span style="">&#41;</span> asSortedCollection: <span style="">&#91;</span>:<span style="color: #00007f;">a</span> :<span style="color: #00007f;">b</span> | b size &lt; a size<span style="">&#93;</span>.
<span style="color: #00007f;">1</span> to: <span style="color: #00007f;">6</span> do: <span style="">&#91;</span>:<span style="color: #00007f;">each</span> | <span style="color: #0000ff;">Transcript</span> show: <span style="">&#40;</span><span style="">&#40;</span><span style="color: #00007f;">s</span> at: <span style="color: #00007f;">each</span><span style="">&#41;</span> at: <span style="color: #00007f;">1</span><span style="">&#41;</span>; cr<span style="">&#93;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/09/27/em-tempos-de-mega-sena-acumulada/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Debugando aplicações JavaEE no Glassfish v2</title>
		<link>http://weblog.destaquenet.com/2008/09/22/debugando-aplicacoes-javaee-no-glassfish-v2/</link>
		<comments>http://weblog.destaquenet.com/2008/09/22/debugando-aplicacoes-javaee-no-glassfish-v2/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 01:51:40 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
		
		<category><![CDATA[Programação]]></category>

		<category><![CDATA[debugging]]></category>

		<category><![CDATA[dicas]]></category>

		<category><![CDATA[glassfish]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[javaee]]></category>

		<category><![CDATA[netbeans]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=50</guid>
		<description><![CDATA[Este post, na verdade, é uma dica rápida para quem possui aplicações JavaEE rodando em servidores Glassfish e está tendo dificuldades na hora de rastrear a origem de possíveis bugs no código. 
Habilitando o modo de debug
Existem duas maneiras de se habilitar o modo de debug no Glassfish: através do painel de administração ou durante [...]]]></description>
			<content:encoded><![CDATA[<p>Este <em>post</em>, na verdade, é uma dica rápida para quem possui aplicações <a href="http://java.sun.com/javaee/">JavaEE</a> rodando em servidores <a href="http://glassfish.dev.java.net/">Glassfish</a> e está tendo dificuldades na hora de rastrear a origem de possíveis <em>bugs</em> no código. <span id="more-50"></span></p>
<h3>Habilitando o modo de debug</h3>
<p>Existem duas maneiras de se habilitar o modo de <em>debug</em> no Glassfish: através do painel de administração ou durante a inicialização do domínio.</p>
<p>Para habilitar o modo de <em>debug</em> por padrão, através do painel de administração, basta marcar o campo <em>Debug</em> na tela <em>JVM Settings</em> e clicar em <em>Save</em>:</p>
<div id="attachment_51" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/debug_mode.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/debug_mode-300x254.png" alt="Habilitando o modo de Debug" title="Modo de Debug" width="300" height="254" class="size-medium wp-image-51" /></a><p class="wp-caption-text">Habilitando o modo de Debug</p></div>
<p>Basta reiniciar o domínio para ver que o servidor abre a porta <code>9009</code>, através da qual podemos conectar um <em>debugger</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">asadmin start-domain domain1</pre></div></div>

<p>Eis um resumo da saída ecoada pelo Glassfish:</p>
<pre>
Starting Domain domain1, please wait.
Log redirected to .../server.log.
Redirecting output to .../server.log
Listening for transport dt_socket at address: 9009
Application server is listening at address 9009 for debugger to attach using transport dt_socket
...
</pre>
<p>A outra forma de se habilitar o modo de <em>debug</em> é fornecer o parâmetro <code>--debug</code> ao iniciar o domínio. Por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="bash bash" style="font-family:monospace;">asadmin start-domain <span style="color: #660033;">--debug</span> domain1</pre></div></div>

<h3>Conectando o debugger da IDE ao servidor</h3>
<p>Agora, basta usar os recursos de <em>debugging</em> presentes na sua IDE Java para debugar o código. Por exemplo, se você usa o <a href="http://netbeans.org/">NetBeans</a> 5.5, basta acessar o menu <em>Run - Attach Debugger&#8230;</em> e o configurar da seguinte forma:</p>
<div id="attachment_52" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/screenshot-attach.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/screenshot-attach-300x152.png" alt="Anexando o debugger do NetBeans" title="Anexando o debugger" width="300" height="152" class="size-medium wp-image-52" /></a><p class="wp-caption-text">Anexando o debugger do NetBeans</p></div>
<p>O procedimento é semelhante em outras IDEs Java.</p>
<p>Pronto! Feito isso, é só colocar os <em>breakpoints</em> e disparar a execução do código problemático.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/09/22/debugando-aplicacoes-javaee-no-glassfish-v2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>JavaEE 5 interceptors</title>
		<link>http://weblog.destaquenet.com/2008/09/21/javaee-5-interceptors/</link>
		<comments>http://weblog.destaquenet.com/2008/09/21/javaee-5-interceptors/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 03:30:58 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
		
		<category><![CDATA[Programação]]></category>

		<category><![CDATA[annotations]]></category>

		<category><![CDATA[aop]]></category>

		<category><![CDATA[container]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[ejb]]></category>

		<category><![CDATA[ioc]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[javaee]]></category>

		<category><![CDATA[reflection]]></category>

		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=41</guid>
		<description><![CDATA[É inegável que a não-tão-nova versão 5 da especificação JavaEE veio numa hora mais do que necessária. Todo mundo parecia &#8212; e com razão &#8212; evitá-la ao máximo, pois seu uso demandava muito tempo e caixas de calmante.
Hoje, criar e manter uma aplicação com EJBs é relativamente simples. E, por este motivo, a adoção da [...]]]></description>
			<content:encoded><![CDATA[<p>É inegável que a não-tão-nova <a href="http://jcp.org/aboutJava/communityprocess/pfd/jsr244/">versão 5</a> da especificação JavaEE veio numa hora mais do que necessária. Todo mundo parecia &#8212; e com razão &#8212; evitá-la ao máximo, pois seu uso demandava muito tempo e caixas de calmante.</p>
<p>Hoje, criar e manter uma aplicação com <acronym title="Enterprise JavaBeans">EJBs</acronym> é relativamente simples. E, por este motivo, a adoção da tecnologia passou a ser mais expressiva, mesmo em projetos menores.</p>
<p>Alguns aspectos da especificação, entretanto, ainda deixam a desejar. Um exemplo seria a parte de injeção de dependências, que é limitada apenas a componentes gerenciados pelo <em>container</em>. O que isso quer dizer? Isso quer dizer que, para você poder tirar proveito do esquema de injeção de dependências, todos os seus componentes precisam ser EJBs.</p>
<p>Mas, nesta versão, os EJBs não são <acronym title="Plain Old Java Object">POJO</acronym>s? Sim, mas ter de expor classes simples como EJBs &#8212; só para ganhar essa &#8220;injetabilidade&#8221; de presente &#8212; não parece correto. E, da mesma forma, espalhar instanciações de objetos pelos vários componentes da aplicação definitivamente também não parece.<span id="more-41"></span></p>
<p>Por isso, mostrarei a seguir um exemplo de como melhorar a parte de injeção de dependências para que possamos injetar POJOs declarativamente em objetos gerenciados. Como o <a href="http://www.springframework.org/">Spring</a> é (de longe) o <em>framework</em> mais conhecido, eu o usarei para me ajudar nesta tarefa.</p>
<h3>O exemplo</h3>
<p>Para demonstrar o efeito desejado, veja o trecho de código a seguir:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> Calculator <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">int</span> mult<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> a, <span style="color: #000066; font-weight: bold;">int</span> b<span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CalculatorImpl <span style="color: #000000; font-weight: bold;">implements</span> Calculator <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> mult<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> a, <span style="color: #000066; font-weight: bold;">int</span> b<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> a<span style="color: #339933;">*</span>b;
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
@<span style="color: #003399;">Remote</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> MultiplicationRuler <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> rulerFor<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> number, <span style="color: #000066; font-weight: bold;">int</span> from, <span style="color: #000066; font-weight: bold;">int</span> to<span style="color: #009900;">&#41;</span>;
<span style="color: #009900;">&#125;</span>
&nbsp;
@Stateless
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MultiplicationRulerBean <span style="color: #000000; font-weight: bold;">implements</span> MultiplicationRuler <span style="color: #009900;">&#123;</span>
&nbsp;
    @InjectBean
    <span style="color: #000000; font-weight: bold;">private</span> Calculator calculator;
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> rulerFor<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> number, <span style="color: #000066; font-weight: bold;">int</span> from, <span style="color: #000066; font-weight: bold;">int</span> to<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">int</span> total <span style="color: #339933;">=</span> to<span style="color: #339933;">-</span>from<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span>;
        <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> ruler <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span>total<span style="color: #009900;">&#93;</span>;
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> 0; i <span style="color: #339933;">&lt;</span> total; i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            ruler<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> calculator.<span style="color: #006633;">mult</span><span style="color: #009900;">&#40;</span>number, from<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> ruler;
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>O objetivo aqui é implementar um componente POJO que multiplica dois números. Este componente é usado por um segundo &#8212; este sim um EJB &#8212; que fornece um método que funciona mais ou menos igual aquelas réguas de tabuada; o método recebe o número desejado e dois outros números que representam os limites da tabuada. Por exemplo, a chamada abaixo retorna os resultados da tabuada de 10, começando no número 1 e indo até o 15:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;">MultiplicationRulerBean ruler <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MultiplicationRulerBean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
ruler.<span style="color: #006633;">rulerFor</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">10</span>,<span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>Note, na classe <code>MultiplicationRulerBean</code>, que o atributo <code>Calculator</code> está anotado com <code>@InjectBean</code>. Esta anotação servirá para indicar que este campo representa uma dependência que deve ser resolvida injetando-se uma instância de <code>Calculator</code>.</p>
<h3>Usando o Spring para obter dependências</h3>
<p>Segue um exemplo de arquivo de contexto <code>appcontext-services.xml</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;beans<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;bean</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;calculatorBean&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;CalculatorImpl&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/beans<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Como nossa única dependência externa é uma instância de <code>Calculator</code>, então o arquivo se resume a apenas uma entrada <code>&lt;bean&gt;</code>. Agora, precisamos criar uma classe que será usada para obter os objetos declarados no arquivo mostrado:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SpringBeanContext <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> SpringBeanContext instance;
    <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #009900;">&#123;</span>
        instance <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SpringBeanContext<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> ApplicationContext context;
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> SpringBeanContext<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        context <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ClassPathXmlApplicationContext<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;META-INF/spring/appcontext-*.xml&quot;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> getBean<span style="color: #009900;">&#40;</span>Class<span style="color: #339933;">&lt;?&gt;</span> clazz<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        Map<span style="color: #339933;">&lt;?</span>,<span style="color: #339933;">?&gt;</span> beans <span style="color: #339933;">=</span> context.<span style="color: #006633;">getBeansOfType</span><span style="color: #009900;">&#40;</span>clazz<span style="color: #009900;">&#41;</span>;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>beans <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> beans.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> 0<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">return</span> beans.<span style="color: #006633;">values</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">iterator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> NoSuchBeanDefinitionException<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;There's no bean of type &quot;</span> <span style="color: #339933;">+</span> clazz<span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> SpringBeanContext getInstance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> instance; <span style="color: #666666; font-style: italic;">// retorna o singleton</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Como apenas precisamos de um objeto da classe <code>SpringBeanContext</code>, esta foi programada como sendo um <a href="http://en.wikipedia.org/wiki/Singleton_pattern">Singleton</a>. Podemos ver que, quando o Singleton é instanciado, os arquivos de contexto &#8212; que seguem a convenção <code>appcontext-[modulo].xml</code> &#8212; são carregados pelo Spring. O método <code>getBean()</code> foi criado para que possamos obter objetos gerenciados pelo Spring.</p>
<h3>Definindo a anotação @InjectBean</h3>
<p>Agora, precisamos criar uma anotação que utilizaremos para indicar as dependências de nossos EJBs:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;">@Retention<span style="color: #009900;">&#40;</span>RetentionPolicy.<span style="color: #006633;">RUNTIME</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> @<span style="color: #000000; font-weight: bold;">interface</span> InjectBean <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>A anotação <code>@InjectBean</code>, que não possui parâmetros e é visível em <em>Runtime</em>, servirá para indicar os atributos que representam dependências. O <em>interceptor</em>, que definiremos a seguir, irá procurar por essa anotação nos EJBs interceptados. Então, para cada campo anotado com essa anotação, o <em>interceptor</em> irá obter o objeto correspondente do contexto do Spring e injetá-lo.</p>
<h3>O Interceptor</h3>
<p>Finalmente chegamos à classe que é responsável por fazer o trabalho pesado:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SpringBeanInterceptor <span style="color: #009900;">&#123;</span>
&nbsp;
    @PostConstruct
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> injectSpringBean<span style="color: #009900;">&#40;</span>InvocationContext context<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">Object</span> target <span style="color: #339933;">=</span> context.<span style="color: #006633;">getTarget</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Field</span> field <span style="color: #339933;">:</span> getAnnotatedFields<span style="color: #009900;">&#40;</span>target.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            injectBean<span style="color: #009900;">&#40;</span>target, field<span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
        context.<span style="color: #006633;">proceed</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> List<span style="color: #339933;">&lt;</span>Field<span style="color: #339933;">&gt;</span> getAnnotatedFields<span style="color: #009900;">&#40;</span>Class<span style="color: #339933;">&lt;?&gt;</span> clazz<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        List<span style="color: #339933;">&lt;</span>Field<span style="color: #339933;">&gt;</span> fields <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> LinkedList<span style="color: #339933;">&lt;</span>Field<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Field</span> field<span style="color: #339933;">:</span> clazz.<span style="color: #006633;">getDeclaredFields</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>field.<span style="color: #006633;">getAnnotation</span><span style="color: #009900;">&#40;</span>InjectBean.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                fields.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>field<span style="color: #009900;">&#41;</span>;
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> fields;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> injectBean<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> target, <span style="color: #003399;">Field</span> field<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">Object</span> bean <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span>;
        bean <span style="color: #339933;">=</span> SpringBeanContext.<span style="color: #006633;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getBean</span><span style="color: #009900;">&#40;</span>field.<span style="color: #006633;">getType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>field.<span style="color: #006633;">isAccessible</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            field.<span style="color: #006633;">setAccessible</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>;
        <span style="color: #009900;">&#125;</span>
        field.<span style="color: #006633;">set</span><span style="color: #009900;">&#40;</span>target, bean<span style="color: #009900;">&#41;</span>;
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Nada de outro mundo, não? Perceba que usamos a anotação <code>@PostConstruct</code>, o que indica que o método anotado deve ser executado para um EJB após sua criação pelo <em>container</em>. Todo método interceptador deve retornar <code>void</code> e esperar um parâmetro do tipo <code>InvocationContext</code>. Neste método, utilizamos um pouco de <a href="http://en.wikipedia.org/wiki/Reflection_%28computer_science%29">Reflection</a> para injetar o objeto fornecido pelo Spring. Por fim, para que outros possíveis <em>interceptors</em> (e o próprio método sendo interceptado) possam ser invocados, chamamos <code>InvocationContext.proceed()</code>.</p>
<p>Para finalizar o exemplo, nos resta associar este <em>interceptor</em> com o EJB da aplicação. Uma forma simples de fazer isso seria através do uso da anotação <code>@Interceptors</code> nas classes e métodos desejados. Por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;">@Stateless
@Interceptors<span style="color: #009900;">&#40;</span>SpringBeanInterceptor.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MultiplicationRulerBean <span style="color: #000000; font-weight: bold;">implements</span> MultiplicationRuler <span style="color: #009900;">&#123;</span>
&nbsp;
    @InjectBean
    <span style="color: #000000; font-weight: bold;">private</span> Calculator calculator;
&nbsp;
    <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Claro que, para este pequeno exemplo, esta abordagem poderia ser utilizada sem nenhum problema. Porém, definir o <em>interceptor</em> dessa forma é muito trabalhoso em situações onde temos muitos EJBs.</p>
<p>Para que possamos evitar o uso repetido da anotação <code>@Interceptors</code>, podemos fazer a configuração via <acronym title="eXtensible Markup Language">XML</acronym>, o que nos permite associar um <em>interceptor</em> a vários EJBs através do uso de curingas. Para isso, basta modificar o arquivo <code>ejb-jar.xml</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ejb-jar<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;description<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Spring-aware interceptor<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/description<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptor-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.destaquenet.tutorial.interceptor.SpringBeanInterceptor<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptor-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptors<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;assembly-descriptor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptor-binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ejb-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>*<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ejb-name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;interceptor-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.destaquenet.tutorial.interceptor.SpringBeanInterceptor<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptor-class<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/interceptor-binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/assembly-descriptor<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ejb-jar<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Neste caso, estamos associando o <em>interceptor</em> automaticamente a <strong>todos</strong> os EJBs, nos livrando de ter que configurar manualmente a associação do <em>interceptor</em> com possíveis novos EJBs que a aplicação venha a ter.</p>
<h3>Conclusão</h3>
<p>Venho observando que <em>frameworks</em> como o Spring e a especificação JavaEE estão trilhando caminhos diretamente opostos; enquando os primeiros estão crescendo descontroladamente e ficando cada vez mais complexos, o segundo está tirando a gordura e ficando mais simples de usar. Claro que cada desenvolvedor tem seus motivos para escolher um ou outro, mas eu particularmente já não vejo tanta vantagem em se adotar o Spring ao EJB. Por outro lado, penso ser mais interessante a <strong>junção</strong> dessas tecnologias de modo que cada uma contribua com o seu melhor.</p>
<p>Como vimos, a especificação JavaEE 5 &#8212; que foi projetada para ser estensível e fácil de usar &#8212; conta com componentes denominados <em>interceptors</em>, que nos fornecem um recurso <em>à la</em> <acronym title="Aspect Oriented Programming">AOP</acronym>, nos permitindo executar código em pontos bem definidos durante a execução da aplicação.</p>
<p>Eu nem preciso dizer que os <em>interceptors</em> podem ser usados para outras coisas além da mostrada aqui. Apenas para citar um exemplo, o <em>framework</em> <a href="http://www.jboss.com/products/seam">Seam</a> usa <em>interceptors</em> para implementar o que seus autores chamam de <a href="http://docs.jboss.com/seam/2.0.0.CR1/reference/en/html/concepts.html#d0e2958">Bijeção</a> &#8212; que permite que um componente qualquer possa receber/ejetar dependências de/para um contexto.</p>
<p>Os conceitos apresentados aqui podem ser adaptados para uso com outros <em>frameworks</em> de injeção de dependências, como <a href="http://code.google.com/p/google-guice/">Guice</a> e <a href="http://www.picocontainer.org/">PicoContainer</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/09/21/javaee-5-interceptors/feed/</wfw:commentRss>
		</item>
		<item>
		<title>2 (boas) formas de testar clientes JavaMail</title>
		<link>http://weblog.destaquenet.com/2008/09/20/2-boas-formas-de-testar-clientes-javamail/</link>
		<comments>http://weblog.destaquenet.com/2008/09/20/2-boas-formas-de-testar-clientes-javamail/#comments</comments>
		<pubDate>Sat, 20 Sep 2008 04:00:27 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
		
		<category><![CDATA[Programação]]></category>

		<category><![CDATA[email]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[javaee]]></category>

		<category><![CDATA[javamail]]></category>

		<category><![CDATA[maven]]></category>

		<category><![CDATA[mock-javamail]]></category>

		<category><![CDATA[mocking]]></category>

		<category><![CDATA[smtp]]></category>

		<category><![CDATA[subethasmtp wiser]]></category>

		<category><![CDATA[testes]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=29</guid>
		<description><![CDATA[Sem sombra de dúvidas, a API Java mais usada para resolver a questão do envio e recebimento de emails é o JavaMail. Apesar de existirem outras opções, como o Spring Mail e Commons Email, no fim das contas é o próprio JavaMail quem faz todo o trabalho sujo, já que tais APIs são baseadas no [...]]]></description>
			<content:encoded><![CDATA[<p>Sem sombra de dúvidas, a <acronym title="Application Programming Interface">API</acronym> Java mais usada para resolver a questão do envio e recebimento de emails é o <a href="http://java.sun.com/products/javamail/">JavaMail</a>. Apesar de existirem outras opções, como o <a href="http://static.springframework.org/spring/docs/2.0.x/reference/mail.html">Spring Mail</a> e <a href="http://commons.apache.org/email/">Commons Email</a>, no fim das contas é o próprio JavaMail quem faz todo o trabalho sujo, já que tais APIs são baseadas no próprio JavaMail.</p>
<p>Apesar de dar conta do recado, a referida API conta com alguns problemas bastante complicados, dentre os quais eu destaco o <em>design</em> (horrível, diga-se de passagem) de <a href="http://java.sun.com/products/javamail/javadocs/index.html">suas classes e interfaces</a>, que parecem fazer o possível para dificultar a testabilidade dos seus &#8220;clientes&#8221;. <span id="more-29"></span></p>
<h3>Entendendo o problema</h3>
<p>Uma técnica de testes bastante utilizada atualmente consiste no uso de <em>frameworks</em> para <a href="http://en.wikipedia.org/wiki/Mock_object">Mocking de objetos</a>. Esses <em>frameworks</em> permitem testar código que faça uso de quaisquer recursos externos e que são, por natureza, difíceis de testar. Classes que necessitam acessar recursos de infraestrutura, como arquivos em disco, impressoras e bancos de dados, são ótimas candidatas a serem &#8220;mockadas&#8221;.</p>
<p>O grande problema é que, para que tais <em>frameworks</em> possam ser usados, o código a ser &#8220;mockado&#8221; tem de seguir <a href="http://www.artima.com/interfacedesign/contents.html">algumas regrinhas de codificação</a>. Por exemplo, alguns <em>frameworks</em> não conseguem &#8220;mockar&#8221; uma classe concreta; outros por sua vez, conseguem &#8220;mockar&#8221; classes concretas desde que elas não sejam finais.</p>
<p>Bom, só para resumir, o ideal seria que o código todo &#8212; tanto das classes de infraestrutura quanto das classes que fazem uso das primeiras &#8212; seja orientado a interfaces. Isso é necessário pois <a href="http://www.jmock.org/">grande</a> <a href="http://www.easymock.org/">parte</a> dos <em>frameworks</em> Java para Mocking de objetos se apoiam na <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Proxy.html">API Proxy</a> para fazer seu trabalho e, como muitos já devem saber, não é possível criar <em>proxies</em> de classes contretas através do uso dessa API.</p>
<p>Para ilustrar melhor o que estou tentando dizer, segue um exemplo de código que envia um e-mail com a API JavaMail:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;"><span style="color: #003399;">Properties</span> props <span style="color: #339933;">=</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">getProperties</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
props.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;mail.smtp.host&quot;</span>, <span style="color: #0000ff;">&quot;smtp.middlenet.com&quot;</span><span style="color: #009900;">&#41;</span>;
Session session <span style="color: #339933;">=</span> Session.<span style="color: #006633;">getDefaultInstance</span><span style="color: #009900;">&#40;</span>props<span style="color: #009900;">&#41;</span>;
&nbsp;
MimeMessage message <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MimeMessage<span style="color: #009900;">&#40;</span>session<span style="color: #009900;">&#41;</span>;
message.<span style="color: #006633;">setFrom</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> InternetAddress<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Frodo&quot;</span>, <span style="color: #0000ff;">&quot;frodo@theshire.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
message.<span style="color: #006633;">addRecipient</span><span style="color: #009900;">&#40;</span>RecipientType.<span style="color: #006633;">TO</span>, <span style="color: #000000; font-weight: bold;">new</span> InternetAddress<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Gandalf&quot;</span>, <span style="color: #0000ff;">&quot;blog@gandalf.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;
message.<span style="color: #006633;">setSubject</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Be careful&quot;</span><span style="color: #009900;">&#41;</span>;
message.<span style="color: #006633;">setText</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Sauron is looking for the One Ring!&quot;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
Transport.<span style="color: #006633;">send</span><span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span>;</pre></div></div>

<p>Veja, por exemplo, que o objeto <code>Session</code> é obtido através da chamada ao método estático <code>getDefaultInstance()</code>; de modo semelhante, temos também a chamada ao método estático <code>send()</code>, na última linha do código. Ah claro, sem contar que a classe <code>Session</code> é <code><strong>final</strong></code>! Como podemos fazer para testar o que vai para e o que volta da API JavaMail?</p>
<h3>Uma solução</h3>
<p>Apesar de não ser possível testar o código anterior usando um <em>framework</em> para Mocking de objetos &#8220;tradicional&#8221;, felizmente há uma luz no fim do túnel.</p>
<p>Uma opção bastante interessante é a utilização de um servidor <acronym title="Simple Mail Transfer Protocol">SMTP</acronym> &#8220;de mentirinha&#8221;, para o qual as mensagens são enviadas. Assim, podemos verificar o que acontece quando o código &#8220;conversa&#8221; com um servidor.</p>
<p>A boa notícia é que não precisamos <a href="http://www.faqs.org/rfcs/rfc821.html">implementar</a> um servidor SMTP do zero! Uma opção de servidor como esse é o <a href="http://subethasmtp.tigris.org/wiser.html">SubEthaSMTP Wiser</a> (!). Com ele, podemos subir um servidor SMTP numa porta qualquer. Então, basta configurar nossa classe de envio de e-mails de modo que tal servidor seja usado no lugar do servidor de produção. As mensagens enviadas a esse servidor podem ser consultadas e verificadas através de asserções no código de testes.</p>
<h4>Usando o SubEthaSMTP Wiser com o Maven</h4>
<p>Se você usa o <a href="http://maven.apache.org/">Maven</a>, então basta adicionar a dependência no seu POM para tornar as classes do SubEthaSMTP Wiser disponíveis no seu ambiente de testes:</p>

<div class="wp_syntax"><div class="code"><pre class="xml xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.subethamail<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>subethasmtp-wiser<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;scope<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>test<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/scope<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Talvez você veja uma mensagem de erro indicando que a dependência <code>javax.activation:1.0.2</code> não foi encontrada. Se isso acontecer, você deverá baixar essa versão do <a href="http://java.sun.com/products/archive/javabeans/jaf102.html">site da Sun</a> e fazer a instalação manualmente no seu repositório local. (o Maven informa qual comando rodar para fazer essa instalação).</p>
<h4>Exemplo de uso</h4>
<p>Usar esse servidor é uma tarefa bem simples. A maior dificuldade é configurar a nossa classe de envio de e-mails para se conectar nesse servidor em vez do servidor de produção. Veja só:</p>

<div class="wp_syntax"><div class="code"><pre class="java java" style="font-family:monospace;">EmailMessage message <span style="color: #339933;">=</span> ... ; <span style="color: #666666; font-style: italic;">// objeto com os dados da mensagem</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* inicia o servidor */</span>
Wiser server <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Wiser<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
server.<span style="color: #006633;">setPort</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2500</span><span style="color: #009900;">&#41;</span>;
server.<span style="color: #006633;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;
&nbsp;
<span style="color: #666666; font-style: italic;">/* configura o cliente */</span>
<span style="color: #003399;">Properties</span> prop <span style="color: #339933;">=</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">getProperties</span><span st