<?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</title>
	<atom:link href="http://blog.caelum.com.br/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.caelum.com.br</link>
	<description>blog dos desenvolvedores da Caelum</description>
	<lastBuildDate>Mon, 13 Feb 2012 16:16:45 +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>Código expressivo e programação funcional em Java com LambdaJ</title>
		<link>http://blog.caelum.com.br/codigo-expressivo-e-programacao-funcional-em-java-com-lambdaj/</link>
		<comments>http://blog.caelum.com.br/codigo-expressivo-e-programacao-funcional-em-java-com-lambdaj/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 15:46:15 +0000</pubDate>
		<dc:creator>Raphael Lacerda</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[expressividade]]></category>
		<category><![CDATA[fj-16]]></category>
		<category><![CDATA[fj-91]]></category>
		<category><![CDATA[funcional]]></category>
		<category><![CDATA[lambdaj]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4816</guid>
		<description><![CDATA[Há um certo tempo refatoramos o sistema que trabalhamos. Migramos de uma arquitetura definida pelo Fowler como Transaction Script (explicada nesse edição da MundoJ) para uma arquitetura essencialmente O.O Domain Model. Por incrível que pareça, o que mais nos chamou a atenção nesse processo não foi o fato de transferir a lógica de negócios para <a href="http://blog.caelum.com.br/codigo-expressivo-e-programacao-funcional-em-java-com-lambdaj/#more-4816'" 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/Screen-shot-2012-02-13-at-12.38.33-AM.png" width="240" />
		</p><p>Há um certo tempo refatoramos o sistema que trabalhamos. Migramos de uma arquitetura definida pelo Fowler como <a href="http://takacsot.freeblog.hu/Files/martinfowler/transactionScript.html">Transaction Script</a> (<a href="http://www.mundoj.com.br/44conteudo.shtml">explicada nesse edição da MundoJ</a>) para uma arquitetura essencialmente <a href="http://www.mundoj.com.br/42conteudo.shtml">O.O Domain Model</a>. Por incrível que pareça, o que mais nos chamou a atenção nesse processo não foi o fato de transferir a lógica de negócios para as entidades responsáveis, visto que delegar responsabilidades é complicado e é isso que faz do O.O tão desafiante, mas sim a qualidade na <a href="http://geraldoferraz.blogspot.com/2011/11/seu-codigo-e-legivel.html">expressividade do código</a> que atingimos.</p>
<p>Alguns sinais de que seu código não esteja expressivo são os <a href="http://www.infoq.com/br/news/2010/03/To-Comment-or-Not-to-Comment">comentários</a>. A lógica é que, se você está explicando com comentários algo que o próprio código deveria dizer, é um smell, neste caso um forte sinal da falta de expressividade (não para a linguagem, mas não está se expressando bem para outro programador).</p>
<p>Sabemos que <a href="http://tecnoblog.net/58041/pesquisa-comprova-programar-em-c-gera-mais-xingamentos/">programador odeia ver código de outro programador</a>, e nos tempos atuais onde a agilidade e ideia de código coletivo estão cada vez mais em alta, código expressivo passa a ser uma exigência, quase que um requisito não funcional. Vamos considerar o código abaixo, tente lê-lo você mesmo:</p>
<pre class="brush: java; title: ; notranslate">
public void imprimirEstatisticasDeVenda(Vendedor vendedor) {
	BigDecimal total = BigDecimal.ZERO;
	BigDecimal comissao = BigDecimal.ZERO;
	for (Venda venda : vendedor.getVendas()) {
		total = total.add(venda.getQuantidade().multiply(venda.getPreco()));
		if(venda.getQuantidade().doubleValue() &gt;= 5) {
			if(venda.getPreco().doubleValue() &gt;= 5) {
				comissao = comissao.add(venda.getQuantidade().
					multiply(venda.getPreco()).multiply(new BigDecimal(0.05)));
				venda.priorizarDespache();
			}
		}
	}
	System.out.println(vendedor.getNome() + &quot; - Total arrecadado: &quot;
		+ df.format(total) + &quot; - Comissao: &quot; + df.format(comissao));
}
</pre>
<p>Se analisarmos linha a linha, veremos que este código calcula o total arrecadado a partir das vendas, o total de comissão que deve ser pago ao vendedor que efetuou as vendas, e finalmente prioriza aquelas vendas que tiveram quantidade e preço maior que cinco.</p>
<p>Ele poderia ser melhorado? Sim, de diversas formas: poderíamos ter extraído varias partes desse código para métodos menores e com nomes significativos para torná-lo mais limpo. Outra opção é buscar por bibliotecas ou criar <a href="http://blog.caelum.com.br/domain-specific-languages-em-acao/">suas próprias</a> <a href="http://martinfowler.com/bliki/DomainSpecificLanguage.html">DSL&#8217;s</a>. </p>
<p>Para não esperar as <a href="http://blog.caelum.com.br/trabalhando-com-closures-no-java-8/">closures</a> do <a href="http://www.infoq.com/br/news/2011/12/java8-lambda">Java 8</a>, conseguimos um pouco  de programação funcional utilizando a biblioteca <a href="http://code.google.com/p/lambdaj/">LambdaJ</a>, dando um toque de <a href="http://blog.caelum.com.br/comecando-com-o-calculo-lambda-e-a-programacao-funcional-de-verdade/">cálculo de lambda</a> ao Java. Ao reesrever o código utilizando essa biblioteca, temos algo mais enxuto:</p>
<pre class="brush: java; title: ; notranslate">
public void imprimirEstatisticasDeVenda(Vendedor vendedor) {
	List&lt;Venda&gt; vendas = vendedor.getVendas();
	BigDecimal totalArrecadado = sumFrom(vendas).getValorDaVenda();

	List&lt;Venda&gt; vendasComissionaveis = select(vendas,
		comQuantidadeMaiorOuIgualA(5).and(comPrecoMaiorOuIgualA(5)));
	forEach(vendasComissionaveis).priorizarDespache();

	BigDecimal comissao = sumFrom(vendasComissionaveis)
	        .getValorDaVenda().multiply(new BigDecimal(0.05));

	System.out.println(vendedor.getNome() + &quot; - Total arrecadado: &quot;
		+ df.format(totalArrecadado) + &quot; - Comissao: &quot; + df.format(comissao));
}
</pre>
<p>Seria esse um código mais expressivo? Consideramos que sim, mas alguns vão criticar que estamos escondendo uma certa complexidade do sistema, que deveria estar a vista dos programadores. E a performance? O LambdaJ tem suas inicializações e objetos temporários, sendo <a title="LambdaJ" href="http://code.google.com/p/lambdaj/wiki/PerformanceAnalysis">um pouco mais lento</a> que a versão anterior, podendo trazer problemas em laços. Há também o problema de ser uma biblioteca de fora da API padrão, e os desenvolvedores precisam de um tempo, mesmo que curto, para se adaptar às novas ideias trazidas por ela. Se você já cursou o FJ-16, <a href="http://blog.caelum.com.br/modelando-as-classes-do-fj-16-em-scala/">pode conferir a modelagem em Scala</a>, mais funcional. </p>
<p>Expressividade de código derruba alguns <a href="http://blog.caelum.com.br/design-patterns-um-mau-sinal/">conceitos que aprendemos</a>, principalmente sobre <a href="http://www.guj.com.br/java/101563-o-que-leva-as-pessoas-a-criar-vos-anemicas#548092">Design Patterns</a>. Afinal, o que o seu cliente entende: <a href="http://fragmental.com.br/wiki/index.php/Evitando_VOs_e_BOs.html">Usar um BO para alterar o VO</a> e persistir usando o DAO no MYSQL ou &#8220;<a href="http://domaindrivendesign.org/books">salvar cliente </a> no <a href="http://blog.caelum.com.br/repository-seu-modelo-mais-orientado-a-objeto/">repositório de cadastros</a>&#8220;?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/codigo-expressivo-e-programacao-funcional-em-java-com-lambdaj/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<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>10</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>Passo a passo para começar com GIT e novo curso online</title>
		<link>http://blog.caelum.com.br/passo-a-passo-para-comecar-com-git-e-novo-curso-online/</link>
		<comments>http://blog.caelum.com.br/passo-a-passo-para-comecar-com-git-e-novo-curso-online/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 12:49:20 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Caelum]]></category>
		<category><![CDATA[controle de versão]]></category>
		<category><![CDATA[cvs]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[pm-89]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4765</guid>
		<description><![CDATA[Quando iniciamos com desenvolvimento profissional, uma das primeiras perguntas que surge é: &#8220;onde os arquivos desse projeto ficarão armazenados?&#8221;. É necessário, principalmente quando trabalhamos em conjunto com outros desenvolvedores, que o projeto esteja armazenado em um local acessível a todos os membros da equipe, com as respectivas permissões para que os mesmos sejam alterados, para <a href="http://blog.caelum.com.br/passo-a-passo-para-comecar-com-git-e-novo-curso-online/#more-4765'" 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/git.png" width="240" />
		</p><p>Quando iniciamos com desenvolvimento profissional, uma das primeiras perguntas que surge é: &#8220;onde os arquivos desse projeto ficarão armazenados?&#8221;. É necessário, principalmente quando trabalhamos em conjunto com outros desenvolvedores, que o projeto esteja armazenado em um local acessível a todos os membros da equipe, com as respectivas permissões para que os mesmos sejam alterados, para que novos arquivos sejam criados e que arquivos existentes possam ser modificados e excluídos.</p>
<p>Tendo em vista esse cenário, podemos definir que qualquer computador, numa rede onde todos os membros da equipe tenham acesso, é candidato a &#8220;local de armazenamento do projeto&#8221;. Mas e se ocorrer algum problema com esse computador?</p>
<p>Então podemos pensar em armazenar os arquivos do projeto em um servidor, com redundância de dispositivos de armazenamento e backups constantes. Uma pasta compartilhada na rede em uma máquina mais segura do que uma estação de trabalho torna-se uma opção melhor. Já podemos chamar esse local de <b>repositório de código</b>?</p>
<p>Apesar dessa segurança adicional, ficamos um pouco restritos quanto a recuperar arquivos excluídos, não temos como desfazer alterações no nosso projeto seletivamente e também não temos informações suficientes sobre o projeto para saber &#8220;qual versão desse arquivo eu devo recuperar do backup?&#8221;. Podemos criar um histórico (<i>log</i>) textual e adicioná-lo como parte do projeto. Agora perceba que ficamos com um ambiente com requisitos demais para um simples &#8220;local de armazenamento de projeto&#8221;?</p>
<p>Pensando nesse problema foram criadas ferramentas de <b>controle de versão</b>, e <a href="http://www.caelum.com.br/curso/online/git/">nosso novo curso online</a> apresentará uma das mais utilizadas hoje em dia, o <b>Git</b>, que ainda possui a vantagem de ser distribuído, em relação ao CVS e SVN. O Git é utilizado por muitos projetos de código aberto, podemos citar o <a href="http://git.kernel.org/">kernel do Linux</a>, o <a href="https://github.com/rails/rails">Rails</a> e o <a href="https://github.com/hibernate/hibernate-orm">Hibernate</a> como exemplos. É possível, porém, utilizá-lo para projetos privados com  restrições e permissões de acesso.</p>
<p>Uma grande vantagem do Git é a existência de ferramentas comerciais de hospedagem de código na Web. A maior provedora de hospedagem de repositórios Git, abertos ou privados, é o <a href="http://www.github.com/">Github</a>. Para projetos aberto, ele é gratuito. A Caelum hospeda <a href="http://www.github.com/caelum">seus projetos dentro do github</a>, que por sua vez hospeda toda sua aplicação no cloud. Dessa forma, para você começar a utilizar o git, não é necessário instalar o seu servidor. Vamos então instalar o cliente.</p>
<p>O Git é uma ferramenta baseada em linha de comando, ou seja, realizamos as operações de controle dos arquivos pelo prompt de comando. Se você é adepto de ferramentas gráficas não se preocupe, existem algumas opções para facilitar seu trabalho e plugins para o Eclipse.</p>
<p>Durante <a href="http://www.caelum.com.br/curso/online/git/">o curso de repositórios remotos e Git</a> aprenderemos outros comandos que o Git nos fornece para solucionar diversos problemas desde o trabalho básico de criação de um repositório, commits, branches, conflitos, como trabalhar no repositório sem conexão com a internet, trabalhar em diferentes implementações simultaneamente num mesmo projeto, modificação de um arquivo por mais de uma pessoa simultaneamente no projeto e tratar os conflitos, entre outros.</p>
<h2>Download e instalação do Git</h2>
<p>A instalação do Git é diferente para cada sistema operacional. A seguir, mostraremos como todo o<br />
processo é feito em cada um deles, para depois iniciarmos com os comandos básicos. </p>
<h2>Windows</h2>
<p><iframe src="http://player.vimeo.com/video/34909539?title=0&amp;byline=0&amp;portrait=0" width="541" height="304" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
<p>Você pode acompanhar o processo de instalação do Git no Windows no vídeo acima ou os passos a seguir.</p>
<p>Para instalar o Git, iniciaremos acessando a página <a href=http://code.google.com/p/msysgit/>http://code.google.com/p/msysgit/</a> e baixando o instalador do msysgit. O instalador da versão mais recente, no momento, é o <code>Git-1.5.6.1-preview20080701.exe</code>. Uma vez baixado, basta executar o programa e seguir as instruções.</p>
<p>Na primeira tela de boas vindas, apenas clique em <em>Next</em> e, na próxima tela, indique o diretório onde deseja instalar o Git em seu computador.</p>
<p>Em seguida, indique quais utilitários serão instalados junto do Git. Marque todas as opções, exceto <em>git-cheetah shell extension</em>. A seguir, defina o nome do menu do Git para o menu <em>Iniciar</em> do Windows, podendo deixar o valor padrão.</p>
<p>O msysgit instala por padrão em seu computador um programa próprio chamado Git Bash, onde é possível manipular os repositórios de arquivos que trabalharemos no futuro. Caso você prefira, é possível usar o próprio prompt do Windows. Basta na próxima janela marcar a opção <em>Run Git from the Windows Command Prompt</em>, como indicado na imagem a seguir:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-windows-5.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-windows-5.png" alt="" title="instalacao-windows-5" width="400" height="313" class="alignnone size-full wp-image-4767" /></a></p>
<p>Na janela a seguir, indique que queremos que as quebras de linha sejam consideradas da mesma maneira, independente do sistema operacional trabalhado. Para isso, marque a primeira opção:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-windows-6.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-windows-6.png" alt="" title="instalacao-windows-6" width="400" height="313" class="alignnone size-full wp-image-4767" /></a></p>
<p>Nesse instante, a cópia dos arquivos será feita para o computador, e em seguida a mensagem de que a instalação foi finalizada aparecerá.</p>
<h2>MacOS</h2>
<p><iframe src="http://player.vimeo.com/video/35134612?title=0&amp;byline=0&amp;portrait=0" width="541" height="304" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
<p>Você pode acompanhar o processo de instalação do Git no Mac OS/X no vídeo acima ou os passos a seguir.</p>
<p>Para instalar o Git no Mac OS X (Snow Leopard ou superior), há um instalador pronto, basta baixá-lo em <a href="http://code.google.com/p/git-osx-installer/downloads/list?can=3">http://code.google.com/p/git-osx-installer/downloads/list?can=3</a>. Na listagem, selecione o arquivo <code>git-1.7.7.3-intel-universal-snow-leopard.dmg</code>.</p>
<p>Após baixá-lo clique duas vezes para ter acesso ao pacote de instalação. Agora é só clicar duas vezes no arquivo <code>.pkg</code> de dentro do <code>.dmg</code> para iniciar o processo de instalação.</p>
<p>Na tela seguinte, selecione a opção &#8220;<em>Instalar para todos os usuários desse computador</em>&#8221; para continuar. Depois é só prosseguir com a instalação padrão.</p>
<p>Para testar a instalação, abra a aplicação &#8220;Terminal&#8221; e digite o comando &#8220;git&#8221;. A saída deve ser similar à imagem:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-mac-5.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-mac-5.png" alt="" title="instalacao-mac-5" width="535" height="429" class="alignnone size-full wp-image-4777" /></a></p>
<p>Opcionalmente, é possível configurar o Terminal para completar os comandos do Git ao pressionarmos a tecla &#8220;tab&#8221;, além de mostrar na linha de comando se a pasta atual está sendo rastreada pelo Git. Para isso é necessário adicionar as seguintes linhas ao arquivo de perfil do usuário para o prompt de comando, habitualmente encontrado na pasta <code>home</code> do usuário com o nome de <code>.bash_profile</code>. Adicione as seguintes linhas ao fim do arquivo:</p>
<pre class="brush: plain; title: ; notranslate">
if [ -f /usr/local/git/contrib/completion/git-completion.bash ]; then
	. /usr/local/git/contrib/completion/git-completion.bash
fi
GIT_PS1_SHOWDIRTYSTATE=true

PS1='\u@\h:\w $(__git_ps1 &quot;(%s)&quot;)\$ '
</pre>
<p>Ao iniciar uma nova janela ou aba do Terminal, as alterações estarão aplicadas. Caso queira aplicar as alterações imediatamente no Terminal digite <code>source ~/.bash_profile</code>.</p>
<h2>Linux</h2>
<p><iframe src="http://player.vimeo.com/video/34909502?title=0&amp;byline=0&amp;portrait=0" width="541" height="304" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
<p>Você pode acompanhar o processo de instalação do Git no Linux no vídeo acima ou os passos a seguir.</p>
<p>Em qualquer sistema Linux, podemos utilizar o gerenciador de pacotes da respectiva distribuição para instalar o Git. No Ubuntu e no Debian, por exemplo, basta instalar o pacote <code>git-core</code> para ter o Git instalado. No Fedora, o pacote <code>git</code>. E no Gentoo, o pacote <code>dev-util/git</code>.</p>
<p>Portanto, por exemplo, para fazer a instalação do Git no Ubuntu, basta executar o comando:</p>
<pre class="brush: plain; title: ; notranslate">sudo apt-get install openssl git-core</pre>
<p>Siga as instruções do prompt de comando, primeiro confirmando a instalação dos pacotes e suas dependências, depois confirmando a instalação do pacote <code>git-core</code>, como demonstrado na imagem:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-linux-1.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-linux-1.png" alt="" title="instalacao-linux-1" width="501" height="348" class="alignnone size-full wp-image-4778" /></a></p>
<p>É possível testar se o Git foi corretamente instalado rodando o comando <code>git</code> no prompt de comando. A saída deve ser uma mensagem de ajuda, similar à demonstrada na imagem:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-linux-2.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/instalacao-linux-2.png" alt="" title="instalacao-linux-2" width="501" height="347" class="alignnone size-full wp-image-4779" /></a></p>
<p>Ao instalar o Git, um script de ajuda que completa os comandos do Git no terminal é instalado, juntamente com um script que demonstra na linha de comando se estamos em um diretório que é um projeto rastreado pelo Git. Para ativá-los é necessário modificar o arquivo de perfil do prompt de comando, normalmente esse arquivo encontra-se na pasta &#8220;home&#8221; do usuário e chama-se &#8220;.bash_profile&#8221; (em alguns casos &#8220;.bashrc&#8221; ou &#8220;.zshrc&#8221;).</p>
<p>Caso nenhum dos arquivos citados exista, crie-o, caso exista, adicione as seguintes linhas ao final dele:</p>
<pre class="brush: plain; title: ; notranslate">
if [ -f /etc/bash_completion.d/git ]; then
	. /etc/bash_completion.d/git
fi
GIT_PS1_SHOWDIRTYSTATE=true

PS1='\u@\h:\w $(__git_ps1 &quot;(%s)&quot;)\$ '
</pre>
<p>Salve o arquivo, a partir de agora, caso estivermos em uma pasta rastreada pelo Git no prompt de comando, seremos informados. Para ativar as alterações imediatamente, execute o comando <code>source</code> informando o arquivo de perfil que alteramos:</p>
<pre class="brush: plain; title: ; notranslate">
source ~/.bash_profile
</pre>
<h2>Clonando um repositório</h2>
<p>Para testar, faça agora um clone do repositório do vraptor:</p>
<pre class="brush: plain; title: ; notranslate">
git clone git@github.com:caelum/vraptor.git
</pre>
<p>Repare que, diferente de muitos outros sistemas de controle de versão, você possui agora <b>todo</b> o repositório do VRaptor, inclusive todo o histórico de modificações, possibilitando trabalhar de maneira offline e concorrente a outros desenvolvedores. Mais detalhes <a href="http://www.caelum.com.br/curso/online/git/">no novo curso de Git online</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/passo-a-passo-para-comecar-com-git-e-novo-curso-online/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>O recurso de implicits no Scala</title>
		<link>http://blog.caelum.com.br/o-recurso-de-implicits-no-scala/</link>
		<comments>http://blog.caelum.com.br/o-recurso-de-implicits-no-scala/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 14:29:40 +0000</pubDate>
		<dc:creator>Alberto Souza</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[dsl]]></category>
		<category><![CDATA[implicits]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[linguagens]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4614</guid>
		<description><![CDATA[Quem nunca reclamou de uma API não tão bem amigável? Um bom caso é o uso do Calendar enquanto estamos programando em Java. Para fazer uma simples soma de dia num Calendar acabamos com o seguinte código: O que seria mais interessante, pelo menos nesse caso, seria ter algum método mais propício que fizesse a <a href="http://blog.caelum.com.br/o-recurso-de-implicits-no-scala/#more-4614'" 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/scala-logo.png" width="240" />
		</p><p>Quem nunca reclamou de uma API não tão bem amigável? Um bom caso é o uso do <code>Calendar</code> enquanto estamos programando em Java. Para fazer uma simples soma de dia num <code>Calendar</code> acabamos com o seguinte código:</p>
<pre class="brush: java; title: ; notranslate">
   Calendar data = Calendar.getInstance();
   data.add(Calendar.DAY_OF_MONTH,1);
</pre>
<p>O que seria mais interessante, pelo menos nesse caso, seria ter algum método mais propício que fizesse a lógica de adição. Lá dentro poderia até ser implementada de uma maneira complicada, mas é para isso que serve encapsulamento. Já que trabalhar com <code>Calendar</code> é muito comum, muitos programadores acabam criando classes utilitárias justamente para encapsular este tipo de código. Abaixo segue um exemplo:</p>
<pre class="brush: java; title: ; notranslate">
  CalendarUtil calendarWrapper = new CalendarUtil(Calendar.getInstance());
  calendarWrapper.plusDays(1);
</pre>
<p>Existe inclusive o bem conhecido <a title="joda-time" href="http://joda-time.sourceforge.net/">Joda Time</a>, exatamente com esse propósito. O problema aqui é que nem sempre temos uma lib como essa para tentar minimizar problema de APIs verborrágicas e, além disso, temos que trabalhar com objetos de classes diferentes, talvez modificar assinaturas de métodos que já existem, algumas vezes impossível. Pensando nisso, a Scala tem umas de suas mais conhecidas features, para simular novos métodos em classes que não temos controle. Imagine que queremos ter um novo método no <code>Calendar</code> chamado <code>plusDays</code>. O código seria como o abaixo:</p>
<pre class="brush: java; title: ; notranslate">
   Calendar data = Calendar.getInstance();
   data.plusDays(1);
</pre>
<p>Só que esse método não existe. É justamente aqui que criaríamosnosso próprio Wrapper, adicionando esses novos métodos e delegando os antigos, podendo implementar um decorator. No Scala, podemos indicar ao compilador para que procure métodos não existentes em determinadas classes em outro lugar. Preste atenção no código a seguir, que define um método <code>convertCalendarToImprovedCalendar</code> que recebe um <code>Calendar</code> e devolve uma instância de classe anônima (filha de <code>Calendar</code>) com o método adicional <code>plusDays</code>:</p>
<pre class="brush: scala; title: ; notranslate">
  object Converters {
   implicit def convertCalendarToImprovedCalendar(calendar:Calendar) = new {
      def plusDays(number:Int) = calendar.add(Calendar.DAY_OF_MONTH,number)
   }
  }
</pre>
<p>O nosso <code>plusDays</code> poderia ser implementado inclusive com o <em>Joda Time</em> por debaixo dos panos, e os outros desenvolvedores continuariam a trabalhar com o velho conhecido <code>Calendar</code>. </p>
<p>A mágica aqui acontece com o uso da palavra <code>implicit</code>. Podemos agora pedir para que esse conversor seja utilizado sempre quando um método não existente em <code>Calendar</code> for invocado. Basta importarmos o <code>Converters</code>, como no exemplo abaixo:</p>
<pre class="brush: scala; title: ; notranslate">
  import Converters._
  class TesteCalendarComMetodosNovos {
    def main(args:Array[String]) {
      val data = Calendar.getInstance();
      data.plusDays(1);
    }
   }
</pre>
<p>Repare que os métodos da classe <code>Converters</code> são importados estaticamente para o escopo de execução, a linha <code>import Converters._</code> funciona muito parecido ao import estático do Java.</p>
<p>Essa técnica para adicionar novos comportamentos em classes que não estão disponíveis para serem alteradas foi chamado de <em><a title="pimp my library" href="http://www.artima.com/weblogs/viewpost.jsp?thread=179766" target="_blank">Pimp my Library</a> </em>por Martin Odersky, num post que ele escreveu há bastante tempo. Outras linguagens possuem features similares, como as <em>Open Classes</em> do Ruby. Uma diferença bastante grande entre os <em>implicits</em> e as <em>Open Classes</em> é que como o Scala é uma linguagem estaticamente tipada, a resolução das chamadas a esses métodos são todas resolvidas em tempos de compilação. Nada é adicionado em tempo de execução.</p>
<p><em>Implicit method</em> é uma das features que mais utilizamos  da linguagem (e precisamos tomar cuidado para não abusar). Adicionar esses novos comportamentos, criação de DSLs e outros usos que discutiremos em novos posts são alguns dos exemplos de uso. </p>
<p>Para quem quiser ver um pouco mais, existe um projeto chamado <strong><a href="https://github.com/caelum/hibernate-query-dsl">hibernate-dsl</a> </strong>que utilizamos aqui na Caelum para conseguirmos trabalhar com a session do Hibernate de maneira mais interessante.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/o-recurso-de-implicits-no-scala/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Retrospectiva Caelum 2011</title>
		<link>http://blog.caelum.com.br/retrospectiva-caelum-2011/</link>
		<comments>http://blog.caelum.com.br/retrospectiva-caelum-2011/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 17:21:41 +0000</pubDate>
		<dc:creator>Paulo Silveira</dc:creator>
				<category><![CDATA[Inovação]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[evento]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[livro]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[online]]></category>
		<category><![CDATA[qcon]]></category>
		<category><![CDATA[unidades]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4719</guid>
		<description><![CDATA[Assim como nos anos anteriores, o de 2011 foi mais um de conquistas. Gostaríamos de compartilhar algumas delas com vocês, sucintamente. - O Caelum Online foi lançado há apenas 3 meses e já se prova eficiente no ensino de tecnologia, oferecendo aprendizado colaborativo, além de comunicação pessoal com os instrutores para a correção dos exercícios. <a href="http://blog.caelum.com.br/retrospectiva-caelum-2011/#more-4719'" 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/caelum2.jpg" width="240" />
		</p><p>Assim como nos <a href="http://blog.caelum.com.br/retrospectiva-caelum-2009/">anos</a> <a href="http://blog.caelum.com.br/retrospectiva-caelum-2010-mais-de-2-milhoes-de-visitas/">anteriores</a>, o de 2011 foi mais um de conquistas. Gostaríamos de compartilhar algumas delas com vocês, sucintamente.</p>
<p>- <a href="http://blog.caelum.com.br/ha-bom-aprendizado-em-cursos-online/">O Caelum Online foi lançado</a> há apenas 3 meses e já se prova eficiente no ensino de tecnologia, oferecendo aprendizado colaborativo, além de comunicação pessoal com os instrutores para a correção dos exercícios. Em breve, teremos novos cursos, além de funcionalidades, que são adicionadas a cada semana.</p>
<p>- <a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/capa_Arquitetura-e-Design-de-Software.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/capa_Arquitetura-e-Design-de-Software-150x150.jpg" alt="" title="capa_Arquitetura e Design de Software" width="150" height="150" class="alignleft size-thumbnail wp-image-4678" /></a> <a href="http://www.arquiteturajava.com.br">Livro de introdução à arquitetura e design lançado</a>. Depois de uma longa espera, o livro foi publicado e o primeiro carregamento da Saraiva se esgotou em menos de 1 semana! O estoque está sendo reposto e agradecemos a todos os alunos do <a href="www.caelum.com.br/curso/fj-91-arquitetura-design-projetos-java">curso de design e arquitetura da Caelum</a> pelo apoio e ajuda.</p>
<p>- Muitos grupos de usuário fizeram suas reuniões por aqui. O Grupo de Usuários de Tecnologia Google, o .NET Architects, o GUJ através do Café com Java, o Grupo de Usuários Ruby e muito mais, com novidades para esse ano, como o grupo de usuários iOS. Além disso, o <a href="http://blog.caelum.com.br/qcon-2011-como-foi-a-segunda-edicao-do-principal-evento-de-arquitetos-e-desenvolvedores-no-brasil/">QCon deixou sua marca novamente</a>, em sua segunda edição no Brasil.</p>
<p>- E certamente comemoramos em grande estilo, com as festas de fim de ano nas 3 unidades:</p>
<p><center><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/rio-1.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/rio-1-150x150.jpg" alt="" title="rio-1" width="150" height="150" class="alignnone size-thumbnail wp-image-4730" /></a> <a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/rio2.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/rio2-150x150.jpg" alt="" title="rio2" width="150" height="150" class="alignnone size-thumbnail wp-image-4731" /></a> <a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/bsb2.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/bsb2-150x150.png" alt="" title="bsb2" width="150" height="150" class="alignnone size-thumbnail wp-image-4729" /></a></p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/caelum2.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/caelum2-300x45.jpg" alt="" title="caelum2" width="300" height="45" class="alignnone size-medium wp-image-4745" /></a></p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/bsb1.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/bsb1-150x150.png" alt="" title="bsb1" width="150" height="150" class="alignnone size-thumbnail wp-image-4728" /></a> <a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/caelum1.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/caelum1-150x150.jpg" alt="" title="caelum1" width="150" height="150" class="alignnone size-thumbnail wp-image-4744" /></a> <a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/caelum3.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/caelum3-150x150.jpg" alt="" title="caelum3" width="150" height="150" class="alignnone size-thumbnail wp-image-4746" /></a><br />
</center></p>
<p>- Qual o resultado final? Esse ano nós viajamos para <strong>20 cidades diferentes</strong> por todo o Brasil. Agradecemos as empresas dessas cidades, que confiaram a nós o trabalho de atualização e aprendizado: </p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/cidades1.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/cidades1-300x245.png" alt="" title="cidades1" width="300" height="245" class="aligncenter size-medium wp-image-4741" /></a></p>
<p>Mas nosso trabalho atingiu muito mais. Apenas em 2011, tivemos alunos vindos de <strong>285 diferentes cidades</strong>. Fica um grande agradecimento a todos os que se deslocaram, viajando para as nossas unidades de São Paulo, Rio de Janeiro e Brasília, dormindo por aqui e que não investiram só dinheiro, mas em especial muito do seu tempo e estudo.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/cidades2.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/cidades2-300x199.png" alt="" title="cidades2" width="300" height="199" class="aligncenter size-medium wp-image-4742" /></a></p>
<p>E nesses quase 8 anos de treinamentos estamos prestes a atingir 600 cidades diferentes. Com um crescimento ordenado, unidades próprias e a confiança do mercado, conseguimos não só manter como também melhorar nossa qualidade de ensino. Outra prova disso são as mensagens que recebemos de vocês:</p>
<p><a href="https://twitter.com/#!/bronx_/status/146431028934881280"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/Screen-shot-2012-01-03-at-1.28.13-AM.png" alt="" title="Screen shot 2012-01-03 at 1.28.13 AM" width="529" height="187" class="aligncenter size-full wp-image-4748" /></a><br />
<a href="http://twitter.com/#!/RCFuhr/status/58929169228234752"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/Screen-shot-2012-01-03-at-11.17.00-AM.png" alt="" title="Screen shot 2012-01-03 at 11.17.00 AM" width="498" height="220" class="aligncenter size-full wp-image-4749" /></a><br />
<a href="http://twitter.com/#!/vivina/status/86870864473243648"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/Screen-shot-2012-01-03-at-11.19.01-AM.png" alt="" title="Screen shot 2012-01-03 at 11.19.01 AM" width="505" height="218" class="aligncenter size-full wp-image-4750" /></a><br />
<a href="http://twitter.com/#!/rayssak/status/94168294868783104"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/Screen-shot-2012-01-03-at-11.20.04-AM.png" alt="" title="Screen shot 2012-01-03 at 11.20.04 AM" width="505" height="219" class="aligncenter size-full wp-image-4751" /></a><br />
<a href="http://twitter.com/#!/gjmveloso/status/113032621642100737"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/Screen-shot-2012-01-03-at-11.22.58-AM.png" alt="" title="Screen shot 2012-01-03 at 11.22.58 AM" width="523" height="208" class="aligncenter size-full wp-image-4752" /></a><br />
<a href="http://twitter.com/#!/stephanie_blum/status/86895143688482816"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2012/01/Screen-shot-2012-01-03-at-11.23.53-AM.png" alt="" title="Screen shot 2012-01-03 at 11.23.53 AM" width="528" height="140" class="aligncenter size-full wp-image-4753" /></a></p>
<p>Quer ler mais do que estão falando da Caelum? Veja aqui <a href="http://twitter.com/#!/caelum/favorites">uma lista com mais tweets</a>. E que em 2012 trabalhemos para conseguir mais dessas mensagens!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/retrospectiva-caelum-2011/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Rodando sua aplicação na Amazon do Brasil</title>
		<link>http://blog.caelum.com.br/rodando-sua-aplicacao-na-amazon-do-brasil/</link>
		<comments>http://blog.caelum.com.br/rodando-sua-aplicacao-na-amazon-do-brasil/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 13:20:17 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Inovação]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[fj-91]]></category>
		<category><![CDATA[gae]]></category>
		<category><![CDATA[infraestrutura]]></category>
		<category><![CDATA[openshift]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4670</guid>
		<description><![CDATA[Desde o início de nosso trabalho com o cloud em 2009 temos investido tempo e pesquisa na utilização do cloud como plataforma para diminuir custos (e trabalho!) e potencializar produtos, através de diversos vendors. Com a Amazon não é diferente: nosso sistema de ensino online está deployado lá. Com o lançamento de grande parte da <a href="http://blog.caelum.com.br/rodando-sua-aplicacao-na-amazon-do-brasil/#more-4670'" 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/12/maquina_amazon_rodando_2.png" width="240" />
		</p><p>Desde o <a href="http://blog.caelum.com.br/o-cloud-computing-e-inevitavel/">início de nosso trabalho com o cloud em 2009</a> temos <a href="http://blog.caelum.com.br/vivendo-no-cloud-a-infraestrutura-externa-da-caelum-em-11-solucoes/">investido tempo e pesquisa</a> na utilização do cloud como plataforma para diminuir custos (e trabalho!) e potencializar produtos, através de <a href="http://blog.caelum.com.br/screencast-sua-app-no-cloud-com-openshift/">diversos vendors</a>.</p>
<p>Com a Amazon não é diferente: <a href="http://blog.caelum.com.br/ha-bom-aprendizado-em-cursos-online/">nosso sistema de ensino online </a>está deployado lá. <a href="http://aws.amazon.com/about-aws/whats-new/2011/12/14/announcing-the-south-america-sao-paulo-region/">Com o lançamento de grande parte da sua plataforma no Brasil</a>, a Amazon se torna uma opção ainda mais interessante de onde ter sua aplicação. Vamos ver passo a passo como fazer um deploy e aproveitar das novas vantagens da Amazon por aqui.</p>
<p>Primeiro nos <a href="http://aws.amazon.com/console/">logamos no painel AWS Manager</a>, e escolhemos a região da América do Sul:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen7.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen7.png" alt="" title="screen7" width="550" height="216" class="aligncenter size-full wp-image-4686" /></a></p>
<p>Depois escolhemos a imagem que usaremos para a máquina, no nosso caso <a href="http://aws.amazon.com/amis/4157">uma instalação linux limpa</a>, mantida pela própria Amazon. <a href="http://aws.amazon.com/amis">Existem centenas de instalações possíveis</a> (de linux e windows) que podem ser buscadas no market da amazon.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen8.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen8.png" alt="" title="screen8" width="550" height="188" class="aligncenter size-full wp-image-4687" /></a></p>
<p>Escolhemos então a potência da máquina e em qual <em>availability zone</em> ela ficará. Comecemos com &#8220;<code>sa-east-1a</code>&#8220;, que indica América do Sul:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen9.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen9.png" alt="" title="screen9" width="550" height="377" class="aligncenter size-full wp-image-4688" /></a></p>
<p>Vale lembrar que uma aplicação realmente com alta disponibilidade precisaria ser deploiada em duas ou mais avaliability zones, <a href="http://www.infoq.com/news/2011/04/Amazon-EC2-Outage-Explained">mesmo sendo pequena a  chance de uma zona cair</a>.</p>
<p>Nas duas próximas telas escolhemos detalhes do Kernel e do RAM, além de possíveis tags que queremos dar para a máquina (em geral para trabalhar através dos web services). No nosso caso deixaremos os defaults.</p>
<p>Quando uma nova máquina é criada, precisamos nos logar nela e, para isso, precisamos de uma chave privada de acesso. A amazon pergunta qual o nome que devemos dar a chave, criando e permitindo que baixemos o arquivo. Note que a chave contida nesse arquivo é importantíssima e qualquer um de sua posse poderá ter acesso a máquina.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen13.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen13.png" alt="" title="screen13" width="550" height="237" class="aligncenter size-full wp-image-4692" /></a></p>
<p>Por fim, escolhemos quais portas desejamos deixar abertas. No caso de uma aplicação Java com Jetty ou Tomcat, adicionamos a porta padrão 8080:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen21.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen21.png" alt="" title="screen21" width="550" height="147" class="aligncenter size-full wp-image-4700" /></a></p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen22.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen22.png" alt="" title="screen22" width="550" height="147" class="aligncenter size-full wp-image-4700" /></a></p>
<p>Isso mesmo, nada de complicados usuários e senhas. Nada de gerenciá-los através de ferramentas de webadmin desatualizadas. Nada de complicadas regras e configuração de firewalls. A Amazon então permite confirmar todas as opções, e o resultado é a máquina rodando: </p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/maquina_amazon_rodando_2.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/maquina_amazon_rodando_2.png" alt="" title="maquina_amazon_rodando_2" width="556" height="87" class="aligncenter size-full wp-image-4721" /></a></p>
<p>A máquina possui um IP interno (para ser acessado de dentro da Amazon) e um DNS público, através do qual acessaremos a mesma de fora da Amazon. O DNS público pode ser visto ao clicar no nome da máquina:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen20.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen20.png" alt="" title="screen20" width="551" height="310" class="aligncenter size-full wp-image-4699" /></a></p>
<p>Vamos acessar a máquina via ssh:</p>
<pre class="brush: plain; title: ; notranslate">
chmod 700 caelum-exemplo.pem
ssh -i caelum-exemplo.pem ec2-user@ec2-177-71-153-49.sa-east-1.compute.amazonaws.com
</pre>
<p>Resultando em:</p>
<pre class="brush: plain; title: ; notranslate">
The authenticity of host 'ec2-177-71-153-49.sa-east-1.compute.amazonaws.com (177.71.153.49)' can't be established.
RSA key fingerprint is 34:a6:de:34:88:fd:a1:73:ae:c5:03:f1:ed:8e:2f:96.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'ec2-177-71-153-49.sa-east-1.compute.amazonaws.com,177.71.153.49' (RSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

See /usr/share/doc/system-release/ for latest release notes.
There are 16 security update(s) out of 24 total update(s) available
</pre>
<p>Agora fazemos download do jetty, descompactamos e rodamos o servidor (se preferir, utilize o Tomcat):</p>
<pre class="brush: plain; title: ; notranslate">
wget http://download.eclipse.org/jetty/8.1.0.RC1/dist/jetty-distribution-8.1.0.RC1.tar.gz
tar zxf jetty-distribution-8.1.0.RC1.tar.gz
jetty-distribution-8.1.0.RC1/bin/jetty.sh start
</pre>
<p>O servidor irá inicializar e você logo receberá a mensagem de que ele está ouvindo a porta 8080.</p>
<pre class="brush: plain; title: ; notranslate">
2011-12-15 17:54:27.682:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8080 STARTING
</pre>
<p>Pronto, acesse seu jetty:</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen23.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/12/screen23.png" alt="" title="screen23" width="550" height="142" class="aligncenter size-full wp-image-4702" /></a></p>
<p>E se desejarmos atualizar a imagem da máquina, com atualizações de seguranca? Se sua máquina não armazena o banco, mas sim somente arquivos voláteis (de fácil reinstalação), basta terminá-la e criar uma nova. Sistema operacional atualizado! Para manter dados voláteis, você pode usar o <a href="http://aws.amazon.com/rds/">RDS da Amazon</a> para seu banco Mysql ou Oracle (ou outras máquinas para bancos não relacionais) e manter um script de configuração (usar técnicas de configuration management).</p>
<p>Mais: com apenas alguns cliques é muito fácil de <a href="http://aws.amazon.com/pt/elasticloadbalancing/">adicionar um load balancer através de sticky sessions</a>, configurar ips fixos, etc.</p>
<p>O que você está esperando para fazer seu primeiro deploy por lá?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/rodando-sua-aplicacao-na-amazon-do-brasil/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>

