<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.caelum.com.br &#187; Java</title>
	<atom:link href="http://blog.caelum.com.br/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.caelum.com.br</link>
	<description>blog dos desenvolvedores da Caelum</description>
	<lastBuildDate>Thu, 09 Feb 2012 13:04:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Explorando o Application Resources do Android</title>
		<link>http://blog.caelum.com.br/explorando-o-application-resources-do-android/</link>
		<comments>http://blog.caelum.com.br/explorando-o-application-resources-do-android/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 12:32:23 +0000</pubDate>
		<dc:creator>André Silva</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[fj-57]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[resources]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4805</guid>
		<description><![CDATA[Desenvolver para Android não é uma tarefa fácil. Hoje existem cerca de 700 dispositivos que rodam Android. Além de rodarem diversas versões do android, eles possuem hardwares, telas e tamanhos diferentes. Uma grande dor de cabeça para o desenvolvedor Android, a conhecida fragmentação da plataforma. Para facilitar o desenvolvimento e  aliviar a dor de cabeça do <a href="http://blog.caelum.com.br/explorando-o-application-resources-do-android/#more-4805'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/02/android_service.jpg" width="240" />
		</p><p>Desenvolver para Android não é uma tarefa fácil. Hoje existem cerca de 700 dispositivos que rodam Android. Além de rodarem <a href="http://developer.android.com/resources/dashboard/platform-versions.html">diversas versões do android</a>, eles possuem hardwares, telas e tamanhos diferentes. Uma grande dor de cabeça para o desenvolvedor Android, a conhecida fragmentação da plataforma.</p>
<p>Para facilitar o desenvolvimento e  aliviar a dor de cabeça do desenvolvedor, a plataforma Android desenvolveu uma ferramenta fantástica: <a href="http://developer.android.com/guide/topics/resources/index.html">o Application Resources</a>.</p>
<p>O Application Resources é muito útil no desenvolvimento de aplicativos que serão usados por diversos dispositivos, principalmente se for no caso para smartphones e tablets.</p>
<p><img class="aligncenter" src="http://developer.android.com/images/resources/resource_devices_diagram2.png" alt="" /></p>
<p style="text-align: center">Fonte: http://developer.android.com/images/resources/resource_devices_diagram2.png</p>
<p>Para se utilizar do Application Resources, basta colocar <a href="http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources">qualifiers</a> nas pastas de <a href="http://developer.android.com/guide/topics/resources/available-resources.html">Resources (<code>res/</code>)</a>. Quando criamos um projeto Android ele já tem a pasta layout. Se, por exemplo, formos criar layouts diferentes (mais adequados) para dispositivos de telas pequenas, criaremos a pasta layout<code>-small</code>. Nesse caso, <code>small</code> é seu qualifier.</p>
<p>Quando sua aplicação é executada, ela carregará os resources de acordo com os <em>qualifiers</em> do seu dispositivo. Se você não utilizar nenhum qualifier, a aplicação utilizará os resources defaults (sem qualifiers. Ex: <code>layout</code>, <code>values</code>, etc.). Aplicações podem possuir diferentes diretórios para diferentes qualifiers, como a figura mostra:</p>
<p><img class="aligncenter" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/application-resources-example.png" alt="" /></p>
<p>Se você vai desenvolver sua aplicação para uma grande quantidade de dispositivos, é praticamente obrigatório o uso do Application Resources. Ele vai evitar que você faça arquivos de layouts desnecessários, ou seja, ao invés de ter um arquivo XML dentro da pasta layout para cada tipo de tela, você terá o arquivo com o mesmo nome em uma pasta layout e outro com o <strong>conteúdo diferente</strong> em <code>layout-small</code>. Com isso você pode aproveitar as capacidades (processamento, qualidade e tamanho de telas) dos dispositivos.</p>
<p>Uma curta aplicação de exemplo <a href="https://github.com/andrelrs/ApplicationResourcesExample"> está disponível no github</a>. Nela exibimos um texto diferente para cada tipo de dispositivo: dispositivo com telas pequenas, telas médias, telas médias em landscape, telas grandes e telas grandes com versão 14. O Application Resources não serve só para internacionalização, no exemplo a ideia é exibir qual o tipo de tela que o dispositivo tem <strong>alterando apenas o conteúdo</strong> do arquivo <code>strings.xml</code> de acordo com os qualifiers. Seguindo esta ideia, também podemos utilizar o Application resources principalmente no <code>styles.xml</code>, facilitando trabalhar com os diferentes tipos e orientações de telas.</p>
<p>Uma aplicação que tem muitos detalhes diferentes em dispositivos diferentes pode aparecer com diversos qualifiers grandes, como <code>values-<strong>pt-large-v14-land</strong></code>.</p>
<p>Mas tome cuidado, não saia colocando qualifiers em tudo. Antes disso, procure <a href="http://developer.android.com/guide/topics/resources/providing-resources.html#BestMatch">usar o que realmente você vai precisar</a>. Esperamos te encontrar aqui no <a href="http://www.caelum.com.br/curso/fj-57-desenvolvimento-google-android/">curso de desenvolvimento para Android</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/explorando-o-application-resources-do-android/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>As novidades do Hibernate 4</title>
		<link>http://blog.caelum.com.br/as-novidades-do-hibernate-4/</link>
		<comments>http://blog.caelum.com.br/as-novidades-do-hibernate-4/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 13:23:37 +0000</pubDate>
		<dc:creator>Hanneli Tavante</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[fj-25]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[orm]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4799</guid>
		<description><![CDATA[Um dos mais badalados frameworks de ORM no mundo Java (e popular também no .NET), o Hibernate recentemente ganhou sua versão 4.0 Final, que chega para arrebentar de novidades. O framework surgiu em 2001, por iniciativa de Gavin King, e logo se tornou amplamente utilizado devido a uma grande diversidade de recursos para mapeamento objeto <a href="http://blog.caelum.com.br/as-novidades-do-hibernate-4/#more-4799'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/hibernate-logo.png" width="240" />
		</p><p>Um dos mais badalados frameworks de ORM no mundo Java (e popular também no .NET), o Hibernate recentemente ganhou sua versão 4.0 Final, que chega para <a href="http://in.relation.to/Bloggers/WhatsNewInHibernateCore40">arrebentar de novidades</a>. O framework surgiu em 2001, por iniciativa de Gavin King, e logo se tornou amplamente utilizado devido a uma grande diversidade de recursos para mapeamento objeto relacional. Com a especificação da JPA (Java Persistence API), solidificou-se como  a implementação mais utilizada. Diversos projetos também passaram a ser desenvolvidos pela equipe do Hibernate a fim de aprimorar os recursos existentes no framework. Muitos deles, em vez de serem anexados ao projeto Core, tornaram-se plugins, tais como <a href="http://hibernate.org/subprojects/search.html">Hibernate Search</a>, o <a href="http://hibernate.org/subprojects/ogm.html">Hibernate OGM</a> e o <a href="http://hibernate.org/subprojects/validator.html">Hibernate Validator</a>. Este último, inclusive, teve fortes influências para a criação de uma nova especificação, a Bean Validation (JSR 303).</p>
<p>A partir da <a href="http://blog.caelum.com.br/as-dependencias-do-hibernate-3-5/">versão 3.5</a>, o Hibernate tornou-se uma implementação certificada para a JPA2 (<a href="http://jcp.org/en/jsr/detail?id=317">JSR 317</a>), lançada oficialmente no final de 2009. Várias annotations surgiram e muitos recursos foram aprimorados. Em dezembro de 2011, a versão 4.0 Final veio à tona, trazendo algumas importantes novidades que gostaríamos de destacar:</p>
<h2>Redesign da SessionFactory</h2>
<p>Possivelmente essa é uma das grandes mudanças no Hibernate 4. Estávamos habituados a obter uma <code>SessionFactory</code> da seguinte forma:</p>
<pre class="brush: java; title: ; notranslate">
private static final SessionFactory sessionFactory =
    new Configuration().configure().buildSessionFactory();
</pre>
<p>Entretanto, agora o método <code>buildSessionFactory()</code> está listado como deprecated, bem como as classes de <code>Configuration</code>: <code>org.hibernate.cfg.Configuration</code> e <code>AnnotationConfiguration</code>. A nova forma de se obter uma <code>SessionFactory</code> é através do <code>ServiceRegistry</code>, que explicaremos adiante, lançado para esta versão 4:</p>
<pre class="brush: java; title: ; notranslate">
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
    .configure().buildServiceRegistry();
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
metadataSources.addResource(&quot;algum.hbm.xml&quot;)
    .addAnnotatedClass(SuaEntidade.class);
Metadata metadata = metadataSources.buildMetadata();
SessionFactory sessionFactory = metadata.buildSessionFactory();
</pre>
<p>Para que possamos obter uma <code>SessionFactory</code>, precisamos de um <code>ServiceRegistry</code>, seguido de um <code>MetadataSources</code> (eventualmente podemos adicionar recursos, classes anotadas, entre outros, de forma similar ao <code>Configuration</code>); a partir deste obtemos um <code>Metadata</code> e então finalmente conseguimos uma <code>SessionFactory</code>. </p>
<p>Para obter uma <code>EntityManagerFactory</code> nada muda, podemos usufruir da classe <code>javax.persistence.Persistence</code>.</p>
<h2>ServiceRegistry</h2>
<p>Uma nova forma foi implementada para que o Hibernate gerencie seus serviços. Services são classes que fornecem ao Hibernate diversos tipos de funcionalidades, tais como <code>ClassLoader</code>, conexão com o banco (<code>ConnectionProvider</code>), descoberta de dialetos apropriados, entre outros. Você deve estar se perguntando por que isso é um ponto interessante. O fato chave é que agora todos os serviços possuem uma interface. Caso queira, você pode mudar a forma com que o Hibernate realiza algumas funcionalidades de uma maneira muito simples, apenas fazendo com que suas classes implementem a interface de serviço do Hibernate. É uma forma de desacoplar seu código interno e se tornar mais maleável.</p>
<h2>Suporte a Multi-Tenancy</h2>
<p>Para que não conhece o termo, aí vai um pequeno resumo &#8211; em um modelo multi-tenant, é possível compartilhar os mesmos recursos físicos para clientes/empresas diferentes, mas ao mesmo tempo permite-se que fiquem logicamente isolados. A frase anterior pode parecer abstrata, então imagine diversas aplicações de e-commerce. Muitas delas possuem um core muito similar e diferem apenas em questões de layout e UI. Imagine então que fosse criada uma base de código igual para todas essas lógicas de e-commerce e apenas o design de cada loja diferente fosse mudado; cada uma delas teria seu próprio <code>namespace</code> e um endereço na web; contudo a base de código seria a mesma. Esses websites de lojas de e-commerce seriam cada um, um tenant.</p>
<p>Podemos implementar o Multi-Tenancy de algumas formas: Instâncias de bancos separadas (cada tenant possui sua prórpia instância de banco); Schema separados (os tenants compartilham o mesmo banco físico, entretanto cada um deles possui um schema); e também podemos implementar o Multi-Tenancy através de Particionamento (usamos o mesmo banco físico e o mesmo Schema), onde os tenants são particionados de acordo com algum discriminator value (uma chave que apareceria em toda as tabelas) e uma única tabela guarda os dados de cada um deles. O Hibernate 4 dá suporte a esta última opção de maneira fácil. Para este caso, tomemos como exemplo uma tabela no banco denominada Cliente:</p>
<pre class="brush: plain; title: ; notranslate">
CLIENTE (
  ID BIGINT,
  NOME VARCHAR,
  ...
  TENANT_ID VARCHAR (ou uma chave estrangeira)
)
</pre>
<p>Note que precisamos do campo <code>TENANT_ID</code>, pois ele define a qual tenant nos referimos. Em um exemplo real, esse ID vai dizer a qual loja pertence determinado produto, por exemplo. Essa abordagem via Particionamento ainda dá suporte a cache de segundo nível.</p>
<p>Mas será que sempre precisaremos nos lembrar de criar um TENANT_ID em nossas tabelas? Como poderíamos ter algo como:</p>
<pre class="brush: plain; title: ; notranslate">
CLIENTE (
  ID BIGINT,
  NOME VARCHAR,
  ...
)
</pre>
<p>sem termos um <code>TENANT_ID</code>? Poderíamos ter schemas separados e criarmos uma <code>SessionFactory</code> para cada tenant. Entretanto, isso seria inviável se tivéssemos muitos tenants, pois muitas <code>SessionFactories</code> podem ser extremamente custosas para a memória. Uma outra ideia seria utilizarmos uma abordagem conhecida como <a href="http://relation.to/Bloggers/MultitenancyInHibernate">application-supplied connections</a>, onde abrimos uma Session em cada SessionFactory através de uma Connection específica que fornecemos. Podemos dizer ao Hibernate qual Connection utilizar em cada contexto. Lembra-se de quando explicamos o ServiceRegistry? Um dos Services, é o ConnectionProvider.  Separando os schemas evitamos a necessidade de um <code>TENANT_ID</code> em cada tabela, mas perdemos a possibilidade de usar o cache de segundo nível de maneira fácil, além de ser mais trabalhoso realizar relatórios e estatísticas com mais de um cliente.</p>
<p>O Hibernate 4 fornece essas alternativas básicas para o cenário multi-tenant, de forma quase transparente.</p>
<h2>Usando o Hibernate 4</h2>
<p>Quer ver o Hibernate 4 em ação? A maneira mais fácil de colocá-lo em seu projeto é através do Maven:</p>
<pre class="brush: xml; title: ; notranslate">
  &lt;dependency&gt;
    &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
    &lt;artifactId&gt;hibernate-core&lt;/artifactId&gt;
    &lt;version&gt;4.0.1.Final&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
    &lt;artifactId&gt;hibernate-entitymanager&lt;/artifactId&gt;
    &lt;version&gt;4.0.1.Final&lt;/version&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
    &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
    &lt;artifactId&gt;hibernate-annotations&lt;/artifactId&gt;
    &lt;version&gt;3.5.6-Final&lt;/version&gt;
  &lt;/dependency&gt;
</pre>
<p>Se você utiliza alguma outra ferramenta de build, <a href="http://mvnrepository.com/artifact/org.hibernate">aqui você encontra todas as dependências necessárias </a> declaradas para Ivy, Gradle, SBT, entre outros.</p>
<p>Você também pode baixar os jars necessários <a href="http://sourceforge.net/projects/hibernate/files/hibernate4/4.0.0.Final/hibernate-release-4.0.0.Final.zip/download" target="_blank">para usá-los diretamente</a>. Caso você use o JBoss AS 7 (<a href="http://blog.caelum.com.br/jboss-as-7-inovacao-nos-servidores-java-ee/">conheça mais sobre essa nova versão do servidor</a>), a versão 7.1 (ainda em Beta) já vem com o Hibernate 4 Final. Se você preferir o cloud, pode experimentar o Hibernate 4 no Openshift (<a href="http://blog.caelum.com.br/screencast-sua-app-no-cloud-com-openshift/">aqui há um tutorial no blog da Caelum</a>).</p>
<p>Gostou? Há muito mais nos links abaixo:</p>
<p>Webinar de Hibernate 4 &#8211; <a href="http://www.youtube.com/watch?v=sBBVwOC9o_Y">link</a><br />
Hibernate 4 &#8211; post oficial do <a href="http://relation.to/Bloggers/HibernateCore40IsFinal">in.relation.to</a><br />
Multi-Tenancy &#8211; mais informações (<a href="http://www.developer.com/design/article.php/3801931/Introduction-to-Multi-Tenant-Architecture.htm">tutorial introdutório</a>)<br />
Multi-Tenancy e Hibernate 4 &#8211; <a href="https://community.jboss.org/wiki/Multi-tenancyDesign">Perguntas e Respostas</a></p>
<p>Também não deixe de visitar <a href="http://blog.caelum.com.br/tag/hibernate/">os vários posts da Caelum</a> sobre Hibernate, inclusive o conhecido<a href="http://blog.caelum.com.br/os-7-habitos-dos-desenvolvedores-hibernate-e-jpa-altamente-eficazes/"> 7 hábitos dos desenvolvedores Hibernate e JPA altamente eficazes</a>. Esperamos você no <a href="http://www.caelum.com.br/curso/fj-25-persistencia-jpa2-hibernate/">nosso curso de Hibernate e JPA</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/as-novidades-do-hibernate-4/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Layouts mais flexíveis com Android Fragments</title>
		<link>http://blog.caelum.com.br/layouts-mais-simples-com-android-fragments/</link>
		<comments>http://blog.caelum.com.br/layouts-mais-simples-com-android-fragments/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 16:16:52 +0000</pubDate>
		<dc:creator>Erich Egert</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[fj-57]]></category>
		<category><![CDATA[fragments]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[ui]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4783</guid>
		<description><![CDATA[Desenvolver um aplicativo Android com uma boa interface com o usuário não é fácil: os diferentes tamanhos de tela podem dar trabalho para chegar a um resultado satisfatório em múltiplos dispositivos. Quando levamos em conta os tablets surge um problema ainda maior: como criar uma aplicação para smartphone que, ao rodar em um tablet, aproveite <a href="http://blog.caelum.com.br/layouts-mais-simples-com-android-fragments/#more-4783'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/tablet_vertical_antes_e_depois.png" width="240" />
		</p><p>Desenvolver um aplicativo Android com uma boa interface com o usuário não é fácil: os diferentes tamanhos de tela podem dar trabalho para chegar a um resultado satisfatório em múltiplos dispositivos. Quando levamos em conta os tablets surge um problema ainda maior: como criar uma aplicação para smartphone que, ao rodar em um tablet, aproveite o espaço extra que o dispositivo oferece?  Mais ainda: como fazer isso de maneira fácil?</p>
<p>A partir da versão 3 do Android, através da <a href="http://developer.android.com/guide/topics/fundamentals/fragments.html">a API de Fragments</a>, podemos dividir nossa tela e dar comportamento a cada pedaço (fragmento) de uma view com um <code>Fragment</code>.</p>
<p>Como exemplo vamos usar uma aplicação que contém uma listagem de nomes de arquivos de fotos em um <code>ListView</code>. Queremos que o evento de clique em um item da lista nos mostre a imagem selecionada.</p>
<p>Caso nosso Tablet esteja na horizontal gostaríamos que a listagem e a imagem escolhida apareçam na mesma tela, conforme ilustrado na imagem abaixo:</p>
<div id="attachment_4795" class="wp-caption aligncenter" style="width: 510px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/tablet_horizontal_antes_e_depois.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/tablet_horizontal_antes_e_depois.png" alt="Comportamento da seleção de uma imagem no Tablet na horizontal" title="tablet_horizontal_antes_e_depois" width="500" height="162" class="size-full wp-image-4795" /></a><p class="wp-caption-text">Comportamento da seleção de uma imagem no Tablet na horizontal</p></div>
<p>No caso do tablet estar na vertical gostaríamos de ver apenas a listagem ou a imagem na tela:<br />
<div id="attachment_4796" class="wp-caption aligncenter" style="width: 363px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/tablet_vertical_antes_e_depois.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/tablet_vertical_antes_e_depois.png" alt="Comportamento da seleção da imagem em um Tablet na vertical" title="tablet_vertical_antes_e_depois" width="353" height="250" class="size-full wp-image-4796" /></a><p class="wp-caption-text">Comportamento da seleção da imagem em um Tablet na vertical</p></div></p>
<p>Para que isso seja possível precisamos ter layouts diferenciados para o tablet em landscape. Podemos fazer isso colocando <a href="http://developer.android.com/guide/practices/screens_support.html">qualifiers nas pastas de layout</a>. Em nosso caso telas grandes em landscape.</p>
<p><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/pastas_layout.png" alt="Esquema de qualifiers nas pastas de Layout" /></p>
<p>Na view em landscape podemos usar a tag fragment: </p>
<pre class="brush: xml; title: ; notranslate">
&lt;LinearLayout ...&gt;
  &lt;fragment android:id=&quot;@+id/fragment1&quot;
     android:name=&quot;br.com.caelum.hubbletablet.ListaImagensFragment&quot; .../&gt;

  &lt;fragment android:id=&quot;@+id/fragment2&quot;
     android:name=&quot;br.com.caelum.hubbletablet.ImagemFragment&quot; .../&gt;
&lt;/LinearLayout&gt;
</pre>
<p>Enquanto a outra será apenas um framelayout para inflar:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;LinearLayout ...&gt;
     &lt;FrameLayout android:id=&quot;@+id/ambos_fragments&quot; .../&gt;
&lt;/LinearLayout&gt;
</pre>
<p>Para criarmos um <code>Fragment</code> basta herdarmos da classe e implementar o método <code>onCreateView</code>, onde receberemos um inflater o qual podemos usar para inflar uma view que queremos associar ao <code>Fragment</code>.</p>
<pre class="brush: java; title: ; notranslate">
public class ListaImagensFragment extends Fragment {
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

       View viewLista = inflater.inflate(R.layout.lista, null);

       ListView listaImagens = (ListView) viewLista
           .findViewById(R.id.listaImagens);

       colocaDadosNoListView(listaImagens);
   }
   // ...
}
</pre>
<p>O controle da tela ainda é feito pela Activity e através dela manipularemos os Fragments. Caso o tablet esteja na horizontal, a Activity estará associada à versão do <code>main.xml</code> que usa a tag <code>fragment</code>, que informa ao Android as classes dos Fragments que desejamos usar, então o próprio Android se encarregará de instanciá-los. Caso o tablet esteja na vertical, a Activity estará associada à versão do main.xml que contem apenas uma tag <code>FrameLayout</code>, nesse caso precisaremos criar o fragment que trará a lista e associá-lo ao <code>FrameLayout</code>. Fazemos isso no <code>onCreate</code> da Activity:</p>
<pre class="brush: java; title: ; notranslate">
getFragmentManager().beginTransaction()
    .add(R.id.ambos_fragments, new ListaImagensFragment())
.commit();
</pre>
<p>Para termos a funcionalidade de apertar o botao de back no Android e o mesmo empilhar e desempilhar os fragments, podemos fazer:</p>
<pre class="brush: java; title: ; notranslate">
getFragmentManager().beginTransaction()
    .replace(R.id.ambos_fragments, new ListaImagensFragment())
    .addToBackStack(null)
.commit();
</pre>
<p>O código acima só deve ser executado se o tablet estiver na horizontal, portanto precisamos fazer essa verificação, uma maneira de fazer isso é através do <a href="https://gist.github.com/1664963">Activity.getResources().getConfiguration().orientation</a>.</p>
<p>No <code>onCreateView</code> do <code>ListaImagensFragment</code> podemos guardar em um atributo o endereço da imagem selecionada quando houver um clique em um item na lista. Como fazemos agora para passar essa informação para o <code>ImagemFragment</code> para que ele possa mostrar a imagem?</p>
<p>Quando estamos trabalhando apenas com Activities temos que usar o <code>putExtra</code> em <code>Intents</code> para enviar dados de uma <code>Activity</code> para outra. O envio de informações de um Fragment para o outro pode ser feito na Activity de uma forma menos orientada a Strings e maps, tornando nosso código mais orientado a objetos.</p>
<p>Se o tablet estiver na horizontal:</p>
<pre class="brush: java; title: ; notranslate">
ListaImagensFragment listaFragment = (ListaImagensFragment)
	getFragmentManager().findFragmentById(R.id.fragment1);

ImagemFragment imagemFragment = (ImagemFragment)
	getFragmentManager().findFragmentById(R.id.fragment2);

imagemFragment.setImagem(listaFragment.getImagemSelecionada());
imagemFragment.atualizaImagem();
</pre>
<p>Se estiver na vertical:</p>
<pre class="brush: java; title: ; notranslate">
ListaImagensFragment listaFragment = (ListaImagensFragment)
	getFragmentManager().findFragmentById(R.id.ambos_fragments);

ImagemFragment imagemFragment = new ImagemFragment();
imagemFragment.setImagem(listaFragment.getImagemSelecionada());

getFragmentManager().beginTransaction()
	.replace(R.id.ambos_fragments, imagemFragment)
	.addToBackStack(null)
.commit();
</pre>
<p>Essa solução ficou tão interessante que os desenvolvedores da plataforma resolveram criar <a href="http://developer.android.com/sdk/compatibility-library.html">um pacote de compatibilidade</a> para poder usar praticamente as mesmas ideias nos dispositivos antigos, sem precisar de um dispositivo moderno com versão 3.x ou 4.x, <a href="http://mobile.tutsplus.com/tutorials/android/android-compatibility-working-with-fragments/">de maneira bem simples</a>.</p>
<p>Um grande cuidado que devemos ter com o uso de Fragments é evitar espalhar por toda aplicação if&#8217;s que verificam se a tela é grande ou o aparelho está na horizontal, etc. Podemos criar diferentes classes que implementam o comportamento em aparelhos grandes e em pequenos e então fazê-las implementar uma interface java. Assim podemos utilizar o polimorfismo e chegar a uma solução mais elegante.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/layouts-mais-simples-com-android-fragments/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Screencast: sua App no Cloud com OpenShift</title>
		<link>http://blog.caelum.com.br/screencast-sua-app-no-cloud-com-openshift/</link>
		<comments>http://blog.caelum.com.br/screencast-sua-app-no-cloud-com-openshift/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 12:32:39 +0000</pubDate>
		<dc:creator>Hanneli Tavante</dc:creator>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Inovação]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[openshift]]></category>
		<category><![CDATA[paas]]></category>
		<category><![CDATA[redhat]]></category>
		<category><![CDATA[screencast]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4651</guid>
		<description><![CDATA[O cloud vem se espalhando pelo mercado de TI e em especial entre os desenvolvedores de software. Heroku, Cloud Foundry, Microsoft Azure, Google App Engine, entre outros serviços de cloud no modelo PaaS, (Platform as a Service), popularizaram-se muito nos últimos tempos. Para disponibilizar serviços de cloud, é necessário que haja uma infraestrutura de servidores <a href="http://blog.caelum.com.br/screencast-sua-app-no-cloud-com-openshift/#more-4651'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/11/openshift.png" width="240" />
		</p><p>O cloud vem se espalhando pelo mercado de TI e em especial entre os desenvolvedores de software. Heroku, Cloud Foundry, Microsoft Azure, <a href="http://blog.caelum.com.br/escrevendo-e-migrando-aplicacoes-para-o-google-app-engine/">Google App Engine</a>, entre outros serviços de cloud no modelo PaaS, (<a href="http://blog.caelum.com.br/cloud-computing-na-casa-branca-e-o-paas/">Platform as a Service</a>), popularizaram-se muito nos últimos tempos.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/11/openshift.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/11/openshift.png" alt="" title="openshift" width="332" height="217" class="aligncenter size-full wp-image-4654" /></a></p>
<p>Para disponibilizar serviços de cloud, é necessário que haja uma infraestrutura de servidores bastante robusta e uma ambientação sofisticada. Aproveitando a experiência no ramo, a Red Hat lançou, em maio de 2011, durante o Red Hat Summit, seu serviço de PaaS: o <a href="https://openshift.redhat.com/app/">OpenShift</a>.</p>
<p>O OpenShift possui duas versões &#8211; OpenShift Express, opção simples e rápida para hospedar aplicações Ruby, Python, Perl ou Java do zero; e OpenShift Flex, para ser integrado ao Amazon EC2 em aplicações PHP e Java a fim de propiciar monitoramento avançado e auto-scale.</p>
<p>Havia uma boa disponibilidade de PaaS para linguagens como Ruby e Python, e, em contrapartida, o mercado contava com poucas opções de PaaS para Java. A fim de atacar esse ponto, a equipe do OpenShift lançou suporte para aplicações Java, tanto para aas versões Express quanto para a Flex. Adotando como servidor o JBoss AS 7 (mais informações <a href="http://blog.caelum.com.br/jboss-as-7-inovacao-nos-servidores-java-ee/">neste post</a>), o OpenShift implementou uma maneira muito simples e rápida para deployar aplicações Java para o cloud, aceitando quase qualquer framework disponível.</p>
<p><strong>Primeiros passos com o OpenShift</strong></p>
<p>Para usar o OpenShift Express, inicialmente é preciso <a href="http://openshift.redhat.com">cadastrar uma conta</a>. Feito isso, devemos instalar o conjunto de ferramentas para trabalharmos com o OpenShift. Para Linux ou Mac OS, é necessário que Ruby 1.8 esteja instalado na máquina, e, como root, devemos executar:</p>
<pre class="brush: plain; title: ; notranslate">
gem install json_pure
gem install rhc
</pre>
<p>Fizemos um pequeno screencast para dar uma pequena introdução ao OpenShift Express. Você pode seguir os passos descritos no vídeo abaixo após instalar as gems especificadas acima:</p>
<p><center><iframe src="http://player.vimeo.com/video/32917829?title=0&amp;byline=0&amp;portrait=0" width="541" height="338" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></center></p>
<p>Agora é necessário criar um domínio para hospedar nossas aplicações. Basta digitarmos no terminal:</p>
<pre class="brush: plain; title: ; notranslate">rhc-create-domain -n meu_dominio -l seu_login</pre>
<p>Os parâmetros -n e -l especificam, respectivamente, o nome do domínio que você deseja e seu login no OpenShift. Será solicitada sua senha; digite-a e pronto, seu domínio foi criado.</p>
<p>É importante frisar que o OpenShift utiliza git para controle de versão, por isso é necessário tê-lo instalado em sua máquina antes de criar aplicações.</p>
<p>Em seguida, vamos criar uma aplicação. Além de fornecermos o nome, é necessário também fornecer o tipo da aplicação que iremos deployar &#8211; Ruby, Java, Python, Perl ou PHP. Para tanto, executamos o seguinte comando:</p>
<pre class="brush: plain; title: ; notranslate">rhc-create-app -a minha_app -t jbossas-7.0 -l seu_login</pre>
<p>Os parâmetros -a e -t representam, respectivamente, o nome de sua aplicação e o tipo (linguagem) escolhido. Novamente, -l representa seu login no OpenShift. O tipo da aplicação, indicado por -t, pode receber os seguintes valores:</p>
<p>rack-1.1 &#8211; Aplicações Ruby<br />
wsgi-3.2 &#8211; Aplicações Python<br />
jbossas-7.0 &#8211; Aplicações Java<br />
perl-5.10 &#8211; Aplicações Perl<br />
php-5.3 &#8211; Aplicações PHP</p>
<p>Experimente acessar http://minha_app-meu_dominio.rhcloud.com/. Uma página de index padrão deve aparecer se tudo correu bem.</p>
<p>O OpenShift suporta alguns bancos bastante populares como MySQL e SQLite. Podemos adicionar suporte ao MySQL em nossa aplicação de exemplo digitando o seguinte comando:</p>
<pre class="brush: plain; title: ; notranslate">rhc-ctl-app -a minha_app -e add-mysql-5.1</pre>
<p>O parâmetro -a refere-se ao nome de nossa aplicação, e -e refere-se à ação que desejamos efetuar; no caso, adicionar suporte para MySQL. O OpenShift então irá lhe devolver em seu console alguns dados de sua base, tais como nome, host e senha. Anote e guarde esses dados!</p>
<p>Podemos ainda acessar nosso banco remoto com o auxílio do PHPMyAdmin. Basta digitar o comando:</p>
<pre class="brush: plain; title: ; notranslate">rhc-ctl-app -a minha_app -e add-phpmyadmin-3.4</pre>
<p>Digitamos então o usuário e senha do banco remoto que nos foi fornecido anteriormente e pronto! Temos suporte do PHPMyAdmin.</p>
<p>Todas as etapas até a criação de sua aplicação podem ser realizadas por meio da interface gráfica disponibilizada pelo site do OpenShift. Apenas frisando que criar a aplicação via linha de comando já gera automaticamente um projeto trackeado para a branch remota de sua aplicação no OpenShift. Criar através do assistente gráfico vai requerer que você faça isso manualmente.</p>
<p>Gostou? Atualmente um dos projetos da Caelum, o <a href="http://calopsita.caelum.com.br/">Calopsita</a>, está no OpenShift. Você também pode obter mais informações acessando a <a href="https://docs.redhat.com/docs/en-US/OpenShift_Express/1.0/html/User_Guide/index.html" >documentação oficial</a> e também nos <a href="https://www.redhat.com/openshift/forums">diversos materiais</a> elaborados pela Red Hat e pela comunidade. Será um forte competidor para as outras plataforma?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/screencast-sua-app-no-cloud-com-openshift/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Facilitando seus testes de unidade no Java: um pouco de Mockito</title>
		<link>http://blog.caelum.com.br/facilitando-seus-testes-de-unidade-no-java-um-pouco-de-mockito/</link>
		<comments>http://blog.caelum.com.br/facilitando-seus-testes-de-unidade-no-java-um-pouco-de-mockito/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 12:43:56 +0000</pubDate>
		<dc:creator>Raphael Lacerda</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[mock]]></category>
		<category><![CDATA[mockito]]></category>
		<category><![CDATA[pm-87]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testes]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4622</guid>
		<description><![CDATA[Após um bom tempo de aulas ministradas, encontrei uma linha de aprendizagem que acho interessante para chegar até as consideradas boas práticas. A linha é formada pelos conceitos básicos de Orientação a Objetos, Testes, Injeção de Dependências, Programação orientada a interfaces e Mocks. Obviamente há uma interdependência dos tópicos. Há espaço aí para separação de responsabilidades <a href="http://blog.caelum.com.br/facilitando-seus-testes-de-unidade-no-java-um-pouco-de-mockito/#more-4622'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/mockito.jpg" width="240" />
		</p><p>Após um bom tempo de aulas ministradas, encontrei uma linha de aprendizagem que acho interessante para chegar até as consideradas boas práticas. A linha é formada pelos conceitos básicos de Orientação a Objetos, Testes, Injeção de Dependências, Programação orientada a interfaces e Mocks. Obviamente há uma interdependência dos tópicos. Há espaço aí para separação de responsabilidades com aspectos, além de design patterns.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/mockito.jpg"><img class="aligncenter size-full wp-image-4626" title="mockito" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/mockito.jpg" alt="" width="347" height="161" /></a></p>
<p>Não é a toa que mocks sejam complicados para quem está começando, ele é totalmente obscuro (experiência própria), além de que, dependendo das unidades, <a href="http://www.caelum.com.br/curso/fj-16-laboratorio-java-testes-xml-design-patterns/">é possível testá-las sem mocks</a>. Portanto, é mais interessante lidar com outros conceitos, como injeção de dependências, para só depois partir para Mocks.</p>
<p>O artigo não tem como objetivo explicar o conceito de Mocks, mas sim explicar a aplicabilidade do <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#13">framework de testes Mockito</a> nos seus projetos. Se você está começando agora, uma boa dica é procurar as edições da MundoJ (<a href="http://mundoj.com.br/46conteudo.shtml">em quase toda edição há artigos relacionados a testes e consequentemente mocks</a>) e depois ler o <a href="http://martinfowler.com/articles/mocksArentStubs.html">artigo do Martin Fowler</a>.</p>
<p>Mesmo sem conhecer Mocks, lanço um desafio. Continue lendo o artigo e ao final sentirá quanto absorveu do conteúdo. Certamente terá dificuldades. Faça o bookmark do post, volte aos seus estudos, pratique e retorne depois. Ao reler o texto, perceberá o quanto evoluiu, resultado direto de seus estudos.</p>
<p>Então vamos ao código. Temos uma classe <code>FuncionarioDAO</code> e um método <code>buscarFuncionario</code>. No nosso exemplo, para buscar o <code>Funcionario</code>, o sistema deve se comunicar com um mainframe por meio de uma interface <code>Transacao</code>. Mas perceba aqui que poderia ser uma interface EJB comunicando-se remotamente ou até mesmo uma transação simples JDBC. Essa transação mainframe retorna uma <code>String</code> contendo as informações do usuário, separada por colunas. Então o que devemos fazer é uma lógica para montar um <code>Funcionario</code> a partir dessa resposta. Começando pelos testes, teríamos o seguinte:</p>
<pre class="brush: java; title: ; notranslate">
class FuncionarioDAOTest {

  private FuncionarioDAO funcionarioDAO;

  @Mock
  private Transacao transacao;

  @Before
  public void init(){
    MockitoAnnotations.initMocks(this);
    funcionarioDAO = new FuncionarioDAO(transacao);
  }

  @Test
  public void quandoUmUsuarioValidoForPesquisado(){
    when(transacao.executar(&quot;12345&quot;)).thenReturn(&quot;RAPHAEL   12345 2045 &quot;);
    Funcionario funci = funcionarioDAO.buscarFuncionario(&quot;12345&quot;);
    Assert.assertEquals(&quot;RAPHAEL&quot;, funci.getNome());
    Assert.assertEquals(2045, funci.getSetor());
    Assert.assertEquals(&quot;12345&quot;, funci.getMatricula());
    verify(transacao, atMostOnce()).executar(&quot;12345&quot;);
  }

  @Test(expected=UsuarioInexistenteException.class)
  public void quandoUmUsuarioInexistenteForPesquisado(){
    when(transacao.executar(&quot;123&quot;)).thenThrow(new TransacaoOnlineException());
    Funcionario funci = funcionarioDAO.buscarFuncionario(&quot;123&quot;);
  }
}
</pre>
<p>O grande problema é a interface <code>Transacao</code>. Como estamos testando a unidade, não queremos que um objeto real se comunique com o mainframe: seria lento e difícil de testar o resultado, além de testar mais de uma unidade. Esse assunto já foi bastante discutido em artigos do blog da Caelum <a href="http://blog.caelum.com.br/testes-unitarios-com-jmock-2/">que falam de testes</a>, <a href="http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/">sua influência no design</a>, <a href="http://blog.caelum.com.br/facilitando-a-manutencao-dos-testes-ao-diminuir-o-acoplamento-com-o-codigo/">no acoplamento</a> e na <a href="http://blog.caelum.com.br/perdendo-ou-ganhando-tempo-com-testes-de-unidade/">velocidade do seu projeto</a>. Perceba o uso da annotation <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#9"><code>@Mock</code></a>, ela facilita a criação de mocks, deixando o código mais limpo.</p>
<p>A primeira linha do primeiro teste (<code>when(transacao.executar("12345")).thenReturn(" ... ")</code>)define como queremos que o mock se comporte durante a chamada do método <code>executar</code>. O Mockito leva uma grande vantagem aqui sobre os outros frameworks por ser extremamente refactoring friendly. Para isso, usamos o método <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#2"><code>when</code></a>. Já na primeira linha do segundo teste podemos emular um erro através do <code>thenThrow</code>, ou seja, caso não haja nenhum funcionario, o método deverá lançar uma exceção. Com isso isolamos o teste apenas à unidade em questão, sem que código de outras unidades sejam executados.</p>
<p>Podemos ainda verificar se durante a execução de <code>buscarFuncionario</code> o método do nosso mock foi acionado. Para isso usamos o método <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#2">verify</a>. O segundo argumento pode receber alguns outros métodos do Mockito como <em><a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#4"><code>never</code>, <code>atMostOnce</code>, <code>alLeastOnce</code>, <code>times</code>()</a></em>.</p>
<p>Há algumas pessoas que acham desnecessário verificar se o método do objeto mocado foi realmente invocado. Inclusive a própria <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#2">documentação do mockito</a> comenta a respeito. Porém o uso do <code>verify</code> evita que alguém retire essa linha do seu código, algo bem difícil de acontecer, mas por experiência própria, podemos esquecer algum <code>assert</code>.</p>
<p>Feito os testes, partimos então para a lógica.</p>
<pre class="brush: java; title: ; notranslate">
class FuncionarioDAO {
    private Transacao transacao;
    FuncionarioDAO(Transacao tx) {
       this.transacao = tx;
    }

   public Funcionario buscarFuncionario(String matricula) {
      try {
          String resposta = transacao.executar(matricula);
          return montarFuncionario(resposta);
      }
      catch(TransacaoOnlineException e){
         throw new UsuarioInexistenteException(e);
      }
   }

   private Funcionario montarFuncionario(String resposta) {
      String nome = resposta.substring(0,10);
      String matricula = resposta.substring(10,16);
      String setor = resposta.substring(16,21);
      return new Funcionario(nome.trim(),
         matricula.trim(), Integer.parseInt(setor.trim()));
   }
}
</pre>
<p>Agora, ao rodar os testes, você obterá a <a href="http://www.google.com.br/imgres?q=junit+green+bar&amp;um=1&amp;hl=pt-BR&amp;sa=N&amp;tbm=isch&amp;tbnid=Qn2qc_RY8jDvZM:&amp;imgrefurl=http://static.springsource.org/spring-webflow/docs/1.0.x/reference/flow-execution.html&amp;docid=RaCtDbrS0gKBfM&amp;imgurl=http://static.springsource.org/spring-webflow/docs/1.0.x/reference/images/junit-greenbar.png&amp;w=314&amp;h=111&amp;ei=l8muTtP4AoWAgwe-tZ3oDw&amp;zoom=1&amp;iact=rc&amp;dur=562&amp;sig=104183618692365740319&amp;page=1&amp;tbnh=66&amp;tbnw=186&amp;start=0&amp;ndsp=31&amp;ved=1t:429,r:4,s:0&amp;tx=106&amp;ty=37&amp;biw=1277&amp;bih=952">green bar</a>!.</p>
<p>Vamos imaginar um cenário que você esteja lidando com um sistema com design mais pobre, <a href="http://blog.caelum.com.br/singletons-e-static-perigo-a-vista/">com muito uso de métodos estáticos</a>, e seu design ficasse assim:</p>
<pre class="brush: java; title: ; notranslate">
class FuncionarioDAO {
    public Funcionario buscarFuncionario(String matricula){
       String resposta = TransacaoServiceLocator.executar(matricula);
       return montarFuncionario(resposta);
    }
}
</pre>
<p>Há algumas formas de testar esse código, ou seja, mocar o comportamento estático. A primeira é manipulação de bytecode (<a href="http://gsd.ime.usp.br/~kon/MAC5715/slides/ManipulacaodeBytecodeJava.pdf">finamente explicado </a>pelo meu amigo <a href="http://twitter.com/andrebreves">André Breves</a>). Entretanto, não me arriscaria a fazer isso na mão, já existem frameworks para tal finalidade e um deles é o <a href="http://code.google.com/p/powermock/">PowerMock</a>, que se integra facilmente com Mockito e JUnit. É muito útil principalmente quando o framework que você está usando lhe impõe invocações estáticas a ele. Exemplificando, mesmo tendo D.I, inevitavelmente, uma hora ou outra utilizando o <a href="http://seamframework.org/">Seam 2.2</a>, você invocará <code>Component.getInstance()</code>.</p>
<p>Mas é sempre bom lembrar <a href="http://martinfowler.com/articles/injection.html">que fazer um design mais orientado a interfaces e desacoplado de implementações concretas</a> lhe dará uma maior flexibilidade tanto na programação do sistema quanto na construção de testes. <a href="http://blog.caelum.com.br/singletons-e-static-perigo-a-vista/">A discussão sobre utilização de métodos estáticos já está batida na comunidade</a>, vários argumentos, dentre eles a programação mais estruturada e menos O.O.</p>
<p>A segunda seria encapsular o <code>TransacaoServiceLocator</code> em uma outra classe e mockar essa classe, sem ter de fazer malabarismos.</p>
<p>A terceira forma seria extrair a chamada para um método e na classe <code>FuncionarioDAOTest</code>, na criação de <code>FuncionarioDAO</code>, poderíamos criar uma classe anônima e fazer o override do método <code>buscarTransacao</code>, retornando um mock.</p>
<pre class="brush: java; title: ; notranslate">
public Funcionario buscarFuncionario(String matricula){
       Transacao tx =  buscarTransacao();
       String resposta = tx.executar(matricula) ;
       return montarFuncionario(resposta);
}

public Transacao buscarTransacao() {
      return TransacaoServiceLocator.buscarTransacaoMainFrame();
}
</pre>
<p>Mas tudo isso é muito complicado, como o mockito te ajuda? Aí vêm os <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#2">Spy Objects</a>, a próposito, <a href="http://eclipsesource.com/blogs/2011/10/13/effective-mockito-part-3/">brilhantemente explicado aqui</a>. Em suma, Spy Objects são objetos reais até que se prove o contrário. E provamos o contrário quando definimos algum comportamento para ele. Exemplificando:</p>
<pre class="brush: java; title: ; notranslate">
class FuncionarioDAOTest{

   private FuncionarioDAO funcionarioDAO;

   @Mock
   private Transacao transacao;

   @Before
   public void init(){
        MockitoAnnotations.initMocks(this);
        funcionarioDAO = spy(new FuncionarioDAO(transacao));
        doReturn(transacao).when(funcionarioDAO).buscarTransacao();
   }
</pre>
<p>Agora definimos que todos os métodos de <code>FuncionarioDAO</code> serão invocados normalmente, com exceção do método <code>buscarTransacao</code>, que teve o comportamento alterado. <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#13">É importante reparar que eu usei <code>doReturn</code> ao invés do <code>when</code></a>.</p>
<p>Concluindo, o importante mesmo é saber lidar com as várias ferramentas que existem, tirando o maior proveito delas para construção de testes. Por exemplo, o meu framework não faz injeção de dependências por construtores, então já que eu não tenho construtores para receber os atributos, nos meus testes eu faço a injeção usando o <a href="http://projetos.vidageek.net/mirror/mirror/">Mirror</a>, uma DSL que ajuda na manipulação da API reflection. Hoje mesmo já fui apresentando a uma outra ferramenta, <a href="https://github.com/aparra/fixture-factory">fixture-factory</a>. Indubitavelmente, conhecer o poder que cada ferramenta pode lhe oferecer e principalmente saber quando as utilizar são <a href="http://blog.caelum.com.br/entao-voce-quer-ser-um-arquiteto-java/">duas importantes tarefas de um arquiteto de software</a>.</p>
<p>E quais ferramentas você utiliza para fazer os seus testes?</p>
<p>Créditos especiais ao companheiro de trabalho <a href="http://twitter.com/tacianot">Taciano Tres</a>,que me ajudou com ótimas referências e sempre me obriga a estar atualizado!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/facilitando-seus-testes-de-unidade-no-java-um-pouco-de-mockito/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Agendando tarefas com o TimerService do EJB 3.1</title>
		<link>http://blog.caelum.com.br/agendando-tarefas-com-o-timerservice-do-ejb-3-1/</link>
		<comments>http://blog.caelum.com.br/agendando-tarefas-com-o-timerservice-do-ejb-3-1/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 13:21:41 +0000</pubDate>
		<dc:creator>Nico Steppat</dc:creator>
				<category><![CDATA[Caelum]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[fj-31]]></category>
		<category><![CDATA[javaee]]></category>
		<category><![CDATA[quartz]]></category>
		<category><![CDATA[timer]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4590</guid>
		<description><![CDATA[A versão 3 dos Enterprise Java Beans trouxe grandes mudanças e muitas simplificações para o desenvolvedor. O forte uso de anotações e convenções, que deixaram os XMLs complexos opcionais, entrou no JPA como forma padrão de persistência para substituir os burocráticos entity beans e a injeção de dependências melhora o design para não depender de <a href="http://blog.caelum.com.br/agendando-tarefas-com-o-timerservice-do-ejb-3-1/#more-4590'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/timer.png" width="240" />
		</p><p>A <a href="http://jcp.org/en/jsr/detail?id=220" title="Especificação EJB3">versão 3</a> dos <a href="http://en.wikipedia.org/wiki/Enterprise_JavaBean" title="Wikipedia EJB">Enterprise Java Beans</a>  trouxe <a href="http://www.caelum.com.br/curso/fj-31-java-ee-web-services/" title="Treinamento FJ-31 na Caelum">grandes mudanças e muitas simplificações</a> para o desenvolvedor. O forte uso de anotações e <a href="http://en.wikipedia.org/wiki/Convention_over_configuration" title="Wikipedia Convention over configuration">convenções</a>, que deixaram os XMLs complexos opcionais, entrou no  <a href="http://blog.caelum.com.br/screencast-primeiros-passos-para-a-jpa/" title="Screencast JPA da Caelum">JPA</a> como forma <a href="http://jcp.org/aboutJava/communityprocess/final/jsr317/index.html" title="Especificação JPA ">padrão de persistência</a> para substituir os burocráticos entity beans e a <a href="http://blog.caelum.com.br/customizando-a-producao-de-dependencias-no-cdi/" title="Link CDI no blog da Caelum">injeção de dependências</a> melhora o <a href="http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/" title="Artigo sobre TDD no blog da Caelum">design para não depender de lookups acoplados</a>.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/timer.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/timer-300x300.png" alt="" title="timer" width="300" height="300" class="alignleft size-medium wp-image-4618" /></a> O <a href="http://jcp.org/aboutJava/communityprocess/pr/jsr318/index.html" title="Especificação EJB 3.1">EJB 3.1</a> foi um passo na mesma direção. Nessa versão as interfaces locais ficaram opcionais, os EJBs podem ser utilizados <a href="http://stackoverflow.com/questions/4441237/packaging-ejb-in-javaee-6-war-vs-ear" title="Comparação dos formatos EAR e WAR">dentro de um WAR</a>, o que simplifica o empacotamento (EAR não é mais preciso), e <a href="http://blog.caelum.com.br/novidades-do-ejb-31-do-futuro-java-ee-6/" title="Artigo sobre JavaEE 6 no blog da Caelum">várias outras novidades</a>.</p>
<p>Uma das melhorias do EJB 3.1 está relacionada com o agendamento de terefas dentro do servidor de aplicação, o que é o foco desse post. Mas, para ser exato, o agendamento já era possível nas versões anteriores do EJB (entrou na versão 2.1 da especificação), mas foi muito aperfeiçoado no EJB 3.1.</p>
<p><strong>Como funcionava com EJB 3.0/2.1</strong></p>
<p>Primeiro era preciso definir o método que era chamado quando o <a href="http://java.sun.com/javaee/5/docs/api/javax/ejb/Timeout.html" title="Explicação breve onde usar @Timeout">@Timeout </a> de um agendamento ocorria. Para isso podemos usar um Session Bean Stateless:</p>
<pre class="brush: java; title: ; notranslate">
@Stateless @Remote(Agendador.class) //pode ser @Local também
public class AgendadorBean implements Agendador {

	@Timeout // no EJB 2.1 implementava a interface javax.ejb.TimedObject
	public void timeout(Timer timer) {
		System.out.println(&quot;Timeout: &quot; + timer.getInfo());
	}
</pre>
<p>Para agendar a execução desse método, usamos o <a href="http://download.oracle.com/javaee/5/tutorial/doc/bnboy.html" title="Link para o tutorial do JavaEE 6 sobre o TimerService"><code>TimerService</code></a>. Com ele podemos definir o agendamento e executar um método anotado com <code>@Timeout</code> apenas uma vez, ou em intervalos (<a href="http://www.javabeat.net/articles/3-ejb-30-timer-services-an-overview-1.html">single-action ou interval-action</a>). O <code>TimerService</code> pode ser injetado, com EJB3, da seguinte maneira:</p>
<pre class="brush: java; title: ; notranslate">
@Stateless @Remote(Agendador.class)
public class AgendadorBean implements Agendador {

	@Resource //no EJB 2.1 era preciso usar ejbContext.getTimerService()
	private TimerService timerService;

	public void agenda() {
		//definir o agendamento - daqui 10s, cada 20s
		this.timerService.createTimer(10*1000L, 20*1000L, &quot;alguma info&quot;);
	}
}
</pre>
<p>O método <code>createTimer(..)</code> é <a href="http://java.sun.com/javaee/5/docs/api/javax/ejb/TimerService.html" title="Javadoc TimerService">sobrecarregado</a> e possui variações, mas não tem como fazer mais do que definir <em>single-action-timer</em> ou <em>interval-action</em>. </p>
<p><strong>O que melhorou com EJB 3.1</strong></p>
<p>No EJB 3.1 o <a href="http://download.oracle.com/javaee/6/api/javax/ejb/TimerService.html" title="Tutorial do TimerService no JavaEE 6">TimerService</a> ganhou métodos para deixar o agendamento mais preciso, baseado em expressões de calendar. Isso é bem parecido com <a href="http://blog.caelum.com.br/agendamento-de-tarefas-em-aplicacoes-web-um-truque-com-quartz/" title="link para o artigo sobre Quartz no blog da Caelum">o que o framework Quartz permite</a> no Java, e <a href="http://en.wikipedia.org/wiki/CRON_expression" title="Link wikipedia sobre cron">as expressões cron</a>:</p>
<pre class="brush: java; title: ; notranslate">
public void agenda() {
	// cada segunda e quarta as 8:30
	ScheduleExpression expression = new ScheduleExpression();
	expression.dayOfWeek(&quot;Mon,Wed&quot;);
	expression.hour(&quot;8&quot;);
	expression.minute(&quot;30&quot;);
	this.timerService.createCalendarTimer(expression);
	System.out.println(&quot;Agendado: &quot; + expression);
}
</pre>
<p>Com <a href="http://download.oracle.com/javaee/6/api/javax/ejb/ScheduleExpression.html" title="Javadoc da class ScheduleExpression">essas expressões</a> podemos definir intervalos bem precisos e a mesma definição também pode ser feita de forma declarativa, através da anotação <code>@Schedule</code>. Com ela nem é necessário usar <code>@Timeout</code>. O método anotado com <code>@Schedule</code> é invocado quando o timeout ocorre:</p>
<pre class="brush: java; title: ; notranslate">
//dentro do session bean
@Schedule(dayOfWeek=&quot;Mon,Wed&quot;, hour=&quot;8&quot;, minute=&quot;30&quot;)
void agendado() {
	System.out.println(&quot;agendado pela anotacao @Schedule&quot;);
}
</pre>
<p>O servidor de aplicação chama então o <code>agendado()</code> periodicamente. Importante saber que qualquer timer que definir um intervalo (<em>interval-action-timer</em>) é persistido e será recuperado quando o servidor reiniciar. Mas podemos deixar o agendamento não persistente também:</p>
<pre class="brush: java; title: ; notranslate">
//dentro do session bean
@Schedule(dayOfWeek=&quot;Mon,Wed&quot;, hour=&quot;8&quot;, minute=&quot;30&quot;, persistent=false)
void agendado() {
	System.out.println(&quot;agendado pela anotacao @Schedule&quot;);
}
</pre>
<p>ou ser for agendado programaticamente:</p>
<pre class="brush: java; title: ; notranslate">
ScheduleExpression expression = new ScheduleExpression();
//..
TimerConfig config = new TimerConfig();
config.setPersistent(false);

this.timerService.createCalendarTimer(expression, config);
</pre>
<p>Poderíamos ainda melhorar <a href="http://openejb.apache.org/singleton-ejb.html" title="Descrição sobre @Singleton no site do projeto OpenEJB">o exemplo usando <code>@Singleton</code></a> e <a href="http://openejb.apache.org/3.0/singleton-example.html" title="Exemplo @Startup com @Singleton no site do projeto OpenEJB"><code>@Startup</code></a>, outras novidades do EJB 3.1. Isso pode ser útil se for utilizado o agendamento através do <code>@Schedule</code> não persistente. E claro, isso é apenas mais uma das facilidades que o container EJB e o <a href="http://blog.caelum.com.br/jboss-as-7-inovacao-nos-servidores-java-ee/" title="Artigo sobre JBoss AS 7 no blog da Caelum">servidor de aplicação</a> podem oferecer, todos vistos no treinamento <a href="http://www.caelum.com.br/curso/fj-31-java-ee-web-services/" title="Link para o treinamento FJ-31 da Caelum">Java EE avançado e Web Services</a>.    </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/agendando-tarefas-com-o-timerservice-do-ejb-3-1/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>JSF &#8211; Lidando com o estado da view</title>
		<link>http://blog.caelum.com.br/jsf-lidando-com-o-estado-da-view/</link>
		<comments>http://blog.caelum.com.br/jsf-lidando-com-o-estado-da-view/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 13:02:32 +0000</pubDate>
		<dc:creator>Nico Steppat</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[fj-26]]></category>
		<category><![CDATA[javaee]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[mojarra]]></category>
		<category><![CDATA[myfaces]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4599</guid>
		<description><![CDATA[JSF é um framework web MVC que foi criado para desenvolver aplicações web de maneira stateful (além de vários outros motivos). São os componentes do JSF que guardam este estado e por causa deles JSF consegue se lembrar, por exemplo, qual converter ou validator é para usar, ou qual era o valor que o usuário <a href="http://blog.caelum.com.br/jsf-lidando-com-o-estado-da-view/#more-4599'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/view-ids3.png" width="240" />
		</p><p><a href="http://www.jcp.org/en/jsr/detail?id=314 " title="especificação JSF 2 ">JSF</a> é um <a href="http://en.wikipedia.org/wiki/Web_application_framework" title="Definição de um web framework na wikipedia">framework web MVC</a> que foi criado para desenvolver aplicações web de maneira <strong><em>stateful</em></strong> (<a href="http://download.oracle.com/javaee/6/tutorial/doc/bnapj.html" title="Lista dos possíveis benefícios do JSF">além de vários outros motivos</a>). São os <a href="http://www.ibm.com/developerworks/library/j-jsf1/" title="Link para a série JSF for Nonbelievers da IBM">componentes do JSF</a> que guardam este estado e por causa deles JSF consegue se lembrar, por exemplo, qual <a href="http://download.oracle.com/javaee/6/tutorial/doc/bnast.html" title="Lista de converters JSF do Java EE Tutorial">converter</a> ou <a href="http://download.oracle.com/javaee/6/tutorial/doc/bnatc.html" title="Lista de validators JSF do Java EE Tutorial">validator</a> é <a href="http://www.ibm.com/developerworks/java/library/j-jsf3/" title="Artigo sobre Validation da seria JSF for nonbelievers da IBM">para usar</a>, ou qual era o valor que o usuário <a href="http://www.portalarquiteto.com.br/implementando-valuechangelistener-em-jsf/" title="Artigo com dicas como implementar um ValueChangeListener">digitou na requisição anterior</a>. </p>
<p>O simples formulário abaixo declara um <code><a href="http://www.horstmann.com/corejsf/jsf-tags.html#Table4_7" title="Documentação da tag">h:inputText</a></code> e um <code><a href="http://www.horstmann.com/corejsf/jsf-tags.html#Table4_15" title="Documentação da tag">h:commandButton</a></code>. Quando o JSF recebe a  requisição inicial (<code>HTTP GET</code>) serão instanciados esses componentes que são do tipo <code><a href="http://download.oracle.com/docs/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/api/javax/faces/component/UIForm.html" title="Javadoc da classe">UIForm</a></code>, <code><a href="http://download.oracle.com/docs/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/api/javax/faces/component/UIInput.html" title="Javadoc da classe">UIInput</a></code> (que é associado com um <a href="http://download.oracle.com/docs/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/api/javax/faces/validator/package-summary.html" title="Lista de validators disponíveis">validator</a> <code><a href="http://download.oracle.com/docs/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/api/javax/faces/validator/DoubleRangeValidator.html" title="Javadoc da classe">DoubleRangeValidator</a></code>) e um <a href="http://download.oracle.com/docs/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/api/javax/faces/component/UICommand.html" title="Javadoc da classe"><code>UICommand</code></a>. Cada componente estende a classe <code><a href="http://download.oracle.com/docs/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/api/javax/faces/component/UIComponent.html" title="Javadoc da classe">UIComponent</a></code> e pode ter filhos, assim usando o famoso <a href="http://pt.wikipedia.org/wiki/Padr%C3%A3o_de_projeto_de_software" title="Link para wikipedia">design pattern</a> <em><a href="http://pt.wikipedia.org/wiki/Padr%C3%A3o_de_projeto_de_software" title="Link para Wikipedia">Composite</a></em>, veja o exemplo:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;h:form&gt;
	&lt;h:inputText value=&quot;#{formularioBean.valor}&quot; id=&quot;valor&quot;&gt;
		&lt;f:validateDoubleRange minimum=&quot;0&quot; /&gt;
	&lt;/h:inputText&gt;
	&lt;h:commandButton value=&quot;Enviar&quot; action=&quot;#{formularioBean.mostra}&quot;/&gt;
&lt;/h:form&gt;
</pre>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/component-tree.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/component-tree-300x226.png" alt="" title="JSF Component tree" width="300" height="226" class="alignleft size-medium wp-image-4602" /></a>O resultado é a <strong>árvore de componentes</strong> (também é chamado <code>view</code> ou <code><a href="http://download.oracle.com/docs/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/api/javax/faces/component/UIViewRoot.html" title="Javadoc da classe">UIViewRoot</a></code>). Ela fica salva na <code>HttpSession</code> do usuário. Por isso, JSF sabe se lembrar qual valor (setter) deve ser usado para preencher o nosso modelo (é o componente que guarda isso!) e por isso também não é preciso definir na URI qual método deve ser chamado no bean, que é tão comum nos <a href="http://vraptor.caelum.com.br/" title="Link para o framework VRaptor que é action-based">frameworks action-based</a>. No formulário acima essa informação está encapsulado no <code><a href="http://download.oracle.com/docs/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/api/javax/faces/component/UICommand.html" title="Javadoc da classe">UICommand</a></code> (<code>h:commandButton</code>).</p>
<p>Cada vez que o controlador JSF recebe um novo <code>HTTP GET</code> para uma página (request inicial) será criado uma árvore nova. Para distinguir entre as árvores diferentes, JSF renderiza no HTML sempre um campo a mais que representa a <strong>identificação da árvore</strong> dentro da sessão HTTP:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;input id=&quot;javax.faces.ViewState&quot; value=&quot;-5331242430046946924:4161480279607048884&quot;  type=&quot;hidden&quot; /&gt;
</pre>
<p><code>javax.faces.ViewState</code> guarda a identificação da árvore no lado do cliente e para cada <code>GET</code> se repete este procedimento (<em>nova árvore, nova identificação</em>). Ou seja, todas as página vão ter <strong>uma ou mais árvores de componentes</strong> na sessão (mesmo para uma aplicação com poucas páginas, o usuário poderia usar várias abas da mesma página). Para testar isso basta chamar uma página (<code>GET</code>) e verificar o número do campo <code>javax.faces.ViewState</code> (a identificação deve mudar):</p>
<p>1. HTTP GET -> ViewState ID: 3695116712045768933<br />
2. HTTP GET -> ViewState ID:-7330234494192939826<br />
3. HTTP GET -> ViewState ID: 6490700310803488872<br />
(3 requisições para a mesma página geram 3 árvores diferentes na sessão do usuário)</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/view-ids.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/view-ids-290x300.png" alt="" title="view-ids" width="290" height="300" class="alignright size-medium wp-image-4607" /></a>Isso significa que um usuário mal intencionado poderia enviar milhares de GET para uma página JSF para causar a criação de árvores na sessão até a memória HEAP acabar. Para evitar esse tipo de problema, o controlador JSF <strong>limita a quantidade de árvores</strong> por usuário. Usando a implementação referencial <a href="http://javaserverfaces.java.net/" title="Site da implementação referencial do JSF">Mojarra</a> o padrão é de 15 árvores no máximo por sessão. Caso o usuário abra, por exemplo, mais do que 15 abas no navegador, o controlador JSF automaticamente vai tirar a árvore menos usada (LRU) da sessão. Para testar isso podemos usar um <a href="https://gist.github.com/1286144" title="Filtro simples para imprimir o conteúdo da sessão">filtro que imprime o conteúdo da sessão</a>, como mostra a imagem ao lado. Se o usuário usa uma aba com uma ID que o controlador já tirou recebemos a famosa <code><a href="http://download.oracle.com/javaee/5/api/javax/faces/application/ViewExpiredException.html" title="Javadoc da exception">ViewExpiredException</a></code>:</p>
<p>Através de uma configuração no <code>web.xml</code>, específica para cada implementação JSF, podemos mudar o padrão. Segue a <a href="http://wikis.sun.com/display/GlassFish/JavaServerFacesRI#JavaServerFacesRI-Whatcontextparametersareavailableandwhatdotheydo%3F" title="Link com uma breve descrição dos context-params">definição para Mojarra</a>:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;context-param&gt;
   &lt;param-name&gt;com.sun.faces.numberOfViewsInSession&lt;/param-name&gt;
   &lt;param-value&gt;5&lt;/param-value&gt;
&lt;/context-param&gt;
</pre>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/view-ids2.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/view-ids2-300x163.png" alt="" title="view-ids2" width="300" height="163" class="alignleft size-medium wp-image-4608" /></a>O parâmetro é específico para a implementação Mojarra e só funciona na versão 1.2.  Mojarra 2.x não respeita o parâmetro apesar da <a href="http://docs.jboss.org/jbossas/6/JSF_Guide/en-US/html/jsf.reference.html" title="Documentação do JBoss sobre JSF e Mojarra">documentação</a> indicar que ela sirva para ambas versões. A implementação MyFaces também possui <a href="http://wiki.apache.org/myfaces/Performance" title="Link para a configuração do MyFaces">uma configuração parecida.</a></p>
<p>Conseguimos então limitar a quantidade de árvores na sessão. Dependendo da quantidade de usuários e complexidade das telas comparado com o tamanho disponível de memória no servidor podemos mesmo assim enfrentar problemas. Por isso a especificação JSF oferece um recurso para <b>não gravar a árvore de componentes na sessão</b>. Mas onde fica o estado então? Toda árvore do componentes é serializada   e é devolvida através de um <code>inputHidden</code> na resposta da requisição. Esse não é o comportamento padrão e deve ser configurado no <code>web.xml</code>, mas faz parte da especificação JSF:</p>
<pre class="brush: xml; title: ; notranslate">
  &lt;context-param&gt;
    &lt;param-name&gt;javax.faces.STATE_SAVING_METHOD&lt;/param-name&gt;
    &lt;param-value&gt;client&lt;/param-value&gt; &lt;!-- server é o padrão --&gt;
  &lt;/context-param&gt;
</pre>
<p>Nesse caso não fica mais a identifição da árvore no HTML gerado, e sim <strong>a árvore serializada</strong>:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/viewstateclient1.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/viewstateclient1.png" alt="" title="viewstate no lado do cliente" width="550" height="180" class="aligncenter size-full wp-image-4606" /></a></p>
<p>Em cada requisição trafega a árvore inteira entre navegador e servidor e no início de cada requisição o servidor recria essa tela. Isso aumenta a banda e uso da CPU no servidor, mas diminui o uso da memória. É importante mencionar que apenas o <code>ViewState</code> será serializado (os componentes) e <strong>não o estado da aplicação</strong> (<code>ManagedBean</code>s). Caso colocarmos algum  <code>ManagedBean</code> na sessão, o bean continua não sessão, não fazendo parte da serialização. O filtro mostra esse comportamento e continua imprimindo o <code><a href="https://gist.github.com/1286181" title="Implementação do FormularioBean">FormularioBean</a></code>:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/view-ids3.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/view-ids3-300x78.png" alt="" title="view-ids3" width="300" height="78" class="aligncenter size-medium wp-image-4609" /></a></p>
<p>A <a href="http://wikis.sun.com/display/GlassFish/JavaServerFacesRI#JavaServerFacesRI-WhatarethedifferencesbetweenServerandClientsidestatesavingandwhatarethebenefits%2Fdrawbacksofeach%3F" title="Explicação entre client e server-state">documentação da Mojarra</a> indica que normalmente o <code>client-state</code> é a melhor solução, mas isso é um tradeoff entre desempenho e uso de memoria e deve ser avaliado para cada projeto. Mojarra até oferece soluções misturadas, podemos por exemplo serializar o <code>view-state</code>, mas deixar <strong>a árvore serializada na sessão</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/jsf-lidando-com-o-estado-da-view/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>JBoss AS 7 &#8211; inovação nos servidores Java EE</title>
		<link>http://blog.caelum.com.br/jboss-as-7-inovacao-nos-servidores-java-ee/</link>
		<comments>http://blog.caelum.com.br/jboss-as-7-inovacao-nos-servidores-java-ee/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 19:48:14 +0000</pubDate>
		<dc:creator>Hanneli Tavante</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[ejb]]></category>
		<category><![CDATA[fj-31]]></category>
		<category><![CDATA[javaee]]></category>
		<category><![CDATA[jboss]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4578</guid>
		<description><![CDATA[Desenvolver com Java para web permite a criação de aplicações robustas e escaláveis. Entretanto, uma das principais queixas dos desenvolvedores consiste na questão dos servidores. De modo geral, diferente de Ruby ou PHP, criar e manter aplicações para web com Java consiste em ter que reiniciar o servidor a cada mudança nas classes, uma vez <a href="http://blog.caelum.com.br/jboss-as-7-inovacao-nos-servidores-java-ee/#more-4578'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/Screen-shot-2011-10-13-at-4.44.32-PM.png" width="240" />
		</p><p>Desenvolver com Java para web permite a criação de aplicações robustas e escaláveis. Entretanto, uma das principais queixas dos desenvolvedores consiste na questão dos servidores. De modo geral, diferente de Ruby ou PHP, criar e manter aplicações para web com Java consiste em ter que reiniciar o servidor a cada mudança nas classes, uma vez que Java não é uma linguagem interpretada. Esse &#8220;tempo gasto&#8221; com o servidor originou algumas frases que devem lhe soar de modo familiar, tais como: &#8220;<em>Esse servidor é muito lento para startar!</em>&#8221; ou &#8220;<em>Dá tempo de tomar cinco cafés até que o deploy termine!</em>&#8220;. Outro ponto de incômodo consiste na questão da complexidade de alguns servidores. Você já deve ter ouvido alguma pergunta do tipo &#8220;<em>Qual desses infinitos XMLs  devo modificar para ativar o que eu preciso?</em>&#8220;. Muitas vezes os servidores Java EE, por mais ricos e robustos que fossem, geravam alguma confusão e certo transtorno.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/Screen-shot-2011-10-13-at-4.44.32-PM.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/Screen-shot-2011-10-13-at-4.44.32-PM-245x300.png" alt="" title="Screen shot 2011-10-13 at 4.44.32 PM" width="245" height="300" class="aligncenter size-medium wp-image-4603" /></a></p>
<p>Eis que o <a href="http://www.jboss.org/as7">JBoss AS 7</a> vem para derrubar algumas dessas questões que geravam um enorme incômodo nos desenvolvedores. Usamos o JBoss AS há muito tempo, inclusive no nosso <a href="http://www.caelum.com.br/curso/fj-31-java-ee-web-services/">curso FJ-31</a>, e o primeiro ponto que impressiona no AS 7 é seu tempo de start &#8211; em cerca dois segundos ou menos é possível iniciar uma instância do servidor (levantando alguma aplicação que esteja na pasta de deploys também). Não, você não leu errado, aproximadamente dois segundos. Para usuários de versões antigas do JBoss AS isso pode parecer um pouco absurdo, uma vez que o AS 5, por exemplo, tinha fama de levar muito tempo para iniciar após a realização de um deploy.</p>
<p>O Jboss AS 7 foi completamente reescrito, deixando de utilizar o JBoss Microcontainer para dar lugar ao <a href="https://docs.jboss.org/author/display/MSC/Home">JBoss Modular Service Container</a> (MSC). Basicamente, em vez de adotar dependências de modo hierárquico na hora de iniciar o servidor, o MSC define dependências explícitas de modo similar a um grafo, sendo possível levantar diversos serviços de forma concorrente.</p>
<p><em>Mudanças em relação a versões antigas do JBoss AS</em></p>
<p>Falando em outras versões do JBoss AS, uma das mudanças que ocorreram consta no script de start. Não há mais o <code>run.bat</code> ou <code>run.sh</code>; este foi substituído pelo <code>standalone.bat</code> ou <code>standalone.sh</code>. Essa mudança se deu porque o AS 7 agora pode operar em dois modos: standalone, que é similar às versões anteriores do JBoss AS, onde um único processo é iniciado; ou operar em Managed Domain, onde múltiplas instâncias são iniciadas e regidas por uma instância central, tal qual mostra a figura abaixo:</p>
<div id="attachment_4579" class="wp-caption aligncenter" style="width: 310px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/Screen-shot-2011-10-07-at-8.02.44-AM.png"><img class="size-medium wp-image-4579" title="JBossAS7 - domain" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/10/Screen-shot-2011-10-07-at-8.02.44-AM-300x186.png" alt="" width="300" height="186" /></a><p class="wp-caption-text">JBossAS7 domain</p></div>
<p>Muito simplificadamente, a imagem acima ilustra o funcionamento do JBoss AS 7 em modo domain. Basicamente, um processo central (Domain Controller) rege múltiplas instâncias do AS 7 contidas em hosts diversos. Operar em modo domain é bastante interessante. Você pode obter mais informações na <a href="https://docs.jboss.org/author/display/AS7/Admin+Guide#AdminGuide-Operatingmodes">documentação oficial do JBoss AS 7</a>.</p>
<p><em>JBoss AS 7 em produção</em></p>
<p>A boa notícia é que a maioria das aplicações Java EE que rodavam em versões antigas do JBoss AS e em outros servidores Java EE ou até mesmo servlet contaners, tais como Jetty e Tomcat, provavelmente funcionarão sem nenhuma configuração adicional ao serem movidas para o JBoss AS 7. Entretanto, é possível que seja necessário um ajuste ou outro devido ao Class Loading do AS 7, que é consideravelmente diferente de outros servidores, podendo carregar dependências equivocadas. Na maioria dos casos, declarar explicitamente as dependências no <code>MANIFEST.MF</code> resolve a os problemas. Por exemplo, para utilizar versões antigas ou que não sejam padrão do slf4j, basta adicionar ao <code>MANIFEST.MF</code> a seguinte linha:</p>
<pre class="brush: plain; title: ; notranslate">Dependencies: org.slf4j.jcl-over-slf4j</pre>
<p>Apesar de novo, já há projetos fazendo uso do JBoss AS 7 devido a suas inúmeras vantagens. Por exemplo, o <a href="http://openshift.redhat.com/">Openshift</a>, projeto de Cloud da Red Hat, utiliza o AS 7. Você inclusive pode realizar deploy de suas aplicações Java gratuitamente lá. O <a href="http://torquebox.org/">Torquebox</a>, projeto que possibilita a criação de aplicações com JRuby on Rails, roda no AS 7 a partir da versão 2.</p>
<p>O JBoss AS 7 é bastante promissor para o desenvolvimento Java para web. O vídeo a seguir mostra um pouco dele na prática.</p>
<p><center><iframe src="http://player.vimeo.com/video/30497673?title=0&amp;byline=0&amp;portrait=0" width="400" height="225" frameborder="0" webkitAllowFullScreen allowFullScreen></iframe></center></p>
<p>Você pode baixar o JBoss AS 7 <a href="http://www.jboss.org/jbossas/downloads/">aqui</a>. Caso queira informações extras sobre a estrutura do AS 7, leia <a href="http://relation.to/21328.lace">esse post</a> publicado no In Relation To.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/jboss-as-7-inovacao-nos-servidores-java-ee/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

