<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4832956066770863941</id><updated>2024-12-19T00:31:26.953-03:00</updated><category term="java"/><category term="maven"/><category term="agile"/><category term="comics"/><category term="weblogic"/><category term="11.10"/><category term="64"/><category term="8.1"/><category term="eclipse"/><category term="fix"/><category term="ia64"/><category term="jpa"/><category term="linux"/><category term="mongodb"/><category term="netbeans"/><category term="netbeans osx java bug workaround"/><category term="oracle"/><category term="rant"/><category term="sacanagem"/><category term="scrum"/><category term="spring"/><category term="struts"/><category term="submarino"/><category term="sun"/><category term="twitter"/><category term="twitter4j"/><category term="ubuntu"/><category term="workaround"/><title type='text'>Victor Hogemann</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>50</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-4446756959937249293</id><published>2014-05-18T21:45:00.001-03:00</published><updated>2014-05-18T21:45:15.575-03:00</updated><title type='text'>2004: Código, direto da máquina do tempo...</title><content type='html'>10 anos atrás eu ainda trabalhava na Prefeitura do Rio de Janeiro pelo iPlanRio como Técnico de Redes, mais precisamente eu trabalhava na Secretaria Municipal de Saúde. Então, imagine minha surpresa ao arrumar algumas caixas velhas e encontrar o email abaixo, impresso (impresso!!) em uma folha já amarelada, contendo a listagem completa de um script muito bacalha que eu fiz a exatos 10 anos!&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7uSPQRgMk5bCBMPWchPSd8BtbUJ7mQeaQzBcn_DVB7CQlsM8vabN1wQ6rtVLBHvnHhRcPh02G1lTbLVXUMaYEA5bzewLyHpyXcr2TMK-7DRpfwc-w4hJLejKcT9PKXZKXRh1UqCen_fkD/s1600/IMG_20140518_185332.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7uSPQRgMk5bCBMPWchPSd8BtbUJ7mQeaQzBcn_DVB7CQlsM8vabN1wQ6rtVLBHvnHhRcPh02G1lTbLVXUMaYEA5bzewLyHpyXcr2TMK-7DRpfwc-w4hJLejKcT9PKXZKXRh1UqCen_fkD/s1600/IMG_20140518_185332.jpg&quot; height=&quot;320&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
É uma monstruosidade, um &lt;i&gt;shellscript&lt;/i&gt;&amp;nbsp;feito pra rodar no &lt;i&gt;Windows&lt;/i&gt;&amp;nbsp;usando&amp;nbsp;&lt;i&gt;Cygwin&lt;/i&gt;. E pra quê? Hora bolas, naquela época ainda haviam trocentas máquinas rodando &lt;i&gt;Win 9x&lt;/i&gt;&amp;nbsp;e nós queríamos que todas falassem com o nosso servidor de Windows Update local. Minha solução foi o script abaixo, que funcionava aplicando um patch de registro em todas as máquinas listadas em um arquivo txt.&lt;br /&gt;
&lt;br /&gt;
Porquê usar &lt;i&gt;Cygwin&lt;/i&gt;&amp;nbsp;e &lt;i&gt;shellscript&lt;/i&gt;? Com certeza mesmo naquela época o Windows deveria ter ferramentas administrativas pra fazer isso por mim de forma mais fácil, infelizmente tudo que eu conhecia era Linux, e minha cabeça dura e teimosia não me deixariam usar outra coisa que não fosse &lt;i&gt;bash&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Eu lembro vagamente de ter conseguido a lista de IPs das máquinas a serem utilizadas usando o NMap pra achar todas as máquinas Windows 9x da rede, rodei algumas vezes pra ter certeza que tinha todas.&lt;br /&gt;
&lt;br /&gt;
Uma coisa legal do script é o trabalho que eu tive pra conseguir tirar do PING.EXE do Windows o status de um host. Os executáveis do Windows não tem valor de retorno, então não dá pra saber se executaram com sucesso ( 0 ) ou se ouve alguma falha... Pior, no &lt;i&gt;Cygwin&lt;/i&gt;&amp;nbsp;não havia um port do &lt;i&gt;ping&lt;/i&gt;&amp;nbsp;do &lt;i&gt;GNU&lt;/i&gt;, então eu tive que me virar com o que eu tinha.&lt;br /&gt;
&lt;br /&gt;
Agora, porquê imprimir um email? Sinceramente eu não faço ideia, mas provavelmente deve ter a ver com querer olhar o código fora da minha mesa, e não ter um notebook, tablet ou smartphone a mão naquela época!&lt;br /&gt;
&lt;br /&gt;
Em nome da nostalgia, eu me dei ao trabalho de digitar o código a partir do email impresso:&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/vhogemann/b655f75ce4c67e7f16c2.js&quot;&gt;&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/4446756959937249293/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2014/05/2004-codigo-direto-da-maquina-do-tempo.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/4446756959937249293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/4446756959937249293'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2014/05/2004-codigo-direto-da-maquina-do-tempo.html' title='2004: Código, direto da máquina do tempo...'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7uSPQRgMk5bCBMPWchPSd8BtbUJ7mQeaQzBcn_DVB7CQlsM8vabN1wQ6rtVLBHvnHhRcPh02G1lTbLVXUMaYEA5bzewLyHpyXcr2TMK-7DRpfwc-w4hJLejKcT9PKXZKXRh1UqCen_fkD/s72-c/IMG_20140518_185332.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-3779015534537150391</id><published>2014-03-09T14:59:00.001-03:00</published><updated>2014-03-09T14:59:03.675-03:00</updated><title type='text'>Do Java para o C#</title><content type='html'>&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMapNWgfkOERL0B3Iv3O0F9gYctVSh3owTGSwVFQZ7tNsG-Bdfh5K0_LoylOMOgfTqW7xdWSymLoQnY-U6dIWVdK5XNCj4_JEY7oF6k5MQOpVtOXZjFSz8Wb6SALovAvWOSd_w7k-MZmQ4/s1600-h/image%25255B11%25255D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;float: right; display: inline&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeGmOv9o3jdTNbVcOyYysbh6VXaM-VBAu583-t2doBogMBkqMWQ3SiOYvNMkDFyC57B6W0Hf2jjwziDgPxjOqlxDI52kS1mTq3h1FJjF-IqxEJwPN-5hr7B33d70Rg0YfWY5X8HmFa0onQ/?imgmax=800&quot; width=&quot;240&quot; align=&quot;right&quot; height=&quot;144&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Depois de 8 anos como desenvolvedor Java estou começando meu primeiro projeto em C#. É uma mudança e tanto pra mim, esse tempo todo meu OS principal sempre foi alguma versão de Linux, ou MacOSX.&lt;/p&gt; &lt;h3&gt;Molhando os pés&lt;/h3&gt; &lt;p&gt;Depois de 4 semanas eu ainda estou começando a ter o mesmo tipo de produtividade que tinha com meu bom e velho ambiente Java/Linux. Algumas coisas são melhores, outras são piores… mas no geral o resultado tem sido positivo. Minhas primeiras impressões são:&lt;/p&gt; &lt;h4&gt;Pontos positivos&lt;/h4&gt; &lt;h3&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;O Visual Studio é uma IDE fantástica. Realmente a Microsoft sabe o que está fazendo, tudo é rápido. Existem várias IDEs pra Java, a minha preferida atualmente é o Intellij, mas de longe o VS é mais esperto e agradável.&lt;/li&gt; &lt;li&gt;C# é uma espécie de Java++. As linguagens são muito semelhantes, mas o C# tem aqueles features que só vão estar disponíveis daqui uma versão ou duas do Java pra frente. LINQ é um caso a parte, eu ainda estou engatinhando mas dá pra ver que dá pra fazer miséria com listas, dicionários e outras coleções.&lt;/li&gt; &lt;li&gt;O gerenciador de dependências NuGet é o Maven/Ivy/Gradle do C#, é uma mão na roda e bem integrado com o VS. Nele é que eu percebi o quanto a Microsoft está investindo na comunidade, o NuGet é OpenSource e a maioria dos pacotes disponíveis também é.&lt;/li&gt; &lt;li&gt;Aliás, muitos dos pacotes da Microsoft são OpenSource, e dependem de outros projetos independentes ao invés de tentar reinventar a roda.&lt;/li&gt; &lt;li&gt;O Visual Studio tem um tema com fundo preto, o que é uma grande vantagem pra quem se acostumou com editores como o Sublime Text 2. A única IDE Java que tem algo que chegue perto é o IntelliJ.&lt;/li&gt; &lt;li&gt;Integração com o Git.&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Pontos negativos&lt;/h4&gt; &lt;p&gt;Se você, como eu, prefere uma abordagem poliglota nos seus projetos, isto é, usando mais de uma linguagem ou ferramentas pra resolver os problemas, o Windows vai impor algumas dificuldades. O principal é que muito do ferramental que eu uso é linha de comando, e nasceu no Linux/OSX.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;As ferramentas de linha de comando, e o console da Microsoft, são ainda são muito ruins.&lt;/li&gt; &lt;li&gt;o APT do Ubuntu, e o Brew do OSX não tem equivalentes reais no Windows.&lt;/li&gt; &lt;li&gt;Se você depende de ferramentas que precisam ser compiladas durante a instalação, bem vindo a um mundo de dor. Instalar pacotes do Node.js por exemplo é uma montanha russa de emoções, principalmente quando alguns ainda dependem de instalações funcionais de Ruby, Gems, Python e outras coisas que vem “de graça” no Linux e OSX.&lt;/li&gt; &lt;li&gt;O Windows é muito diferente do ambiente de produção. Sim, seu código vai rodar no ISS, mas todo resto da infra não necessáriamente… Pelo menos não se você estiver pensando em usar coisas como MongoDB, Redis, MySQL. Então é essencial ter o Linux rodando em uma máquina virtual.&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Nem tudo está perdido&lt;/h4&gt; &lt;p&gt;Eu achei algumas soluções pra alguns dos problemas acima:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&quot;http://www.cygwin.com/&quot;&gt;Cygwin&lt;/a&gt; é um ambiente linha de comando Posix pra Windows. Ele vem com emuladores de terminal muito melhores que o CMD.exe ou o Powershell, ter bons e velhos amigos como Bash e Grep a disposição não tem preço.&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;https://chocolatey.org/&quot;&gt;Chocolatey&lt;/a&gt; pretende ser o Apt para Windows, ele aproveita o repositório do NuGet e tem repositórios próprios pra instalar vários softwares de forma mais organizada. Instalar Ruby, Python e Node.js por ele é muito mais tranquilo que fazer o mesmo manualmente.&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://windows.github.com/&quot;&gt;Github Windows&lt;/a&gt; é o cliente oficial do Github para Windows. E quebra um tremendo galho.&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://www.vmware.com/products/player&quot;&gt;VMWare Player Plus&lt;/a&gt; é a opçao gratuíta da VMWare pra quem precisa rodar máquinas virtuais. Eu sei que o Windows tem uma solução embutida nele, e que existe o VirtualBox… mas em termos de desempenho e compatibilidade com Linux ninguém bate o Player Plus.&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;O que poderia melhorar&lt;/h4&gt; &lt;p&gt;Eu sinceramente acho que a Microsoft entendeu o que é comunidade, e como participar dela, inclusive apoiando e encorajando projetos OpenSource. Mas pra o Windows poder ser a opção número 1 dos desenvolvedores muitas coisas precisam melhorar, as principais sendo:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Um ambiente linha de comando Posix. o Cygwin quebra o galho, mas ainda é um hack feito por terceiros. Se a Microsoft realmente quer que o Windows seja atraente para todo tipo de desenvolvedor, e não apenas para aqueles presos aos produtos dela, é necessário que ele se dê bem com Ruby, Python, Node, e que tenha um toolset compatível com o utilizado no Linux e OSX.&lt;/li&gt; &lt;li&gt;Um sistema de pacotes para ferramentas de desenvolvimento e serviços de sistema. Praticamente cada software tem um método de instalação completamente diferente do outro, e não existe forma de estabelecer dependências entre eles… e assim não tem como automatizar a instalação de nada. Ferramentas como Vagrant e Docker mostram como esse tipo de coisa pode ser utiizada pra dar mais poder ao desenvolvedor.&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Daqui pra frente&lt;/h4&gt; &lt;p&gt;A experiência tem sido positivia até agora, vi mais coisas boas que ruins. E a maioria das coisas ruins tem solução, mesmo que a solução seja instar Linux numa VM. Enquanto durar o projeto em que estou Windows vai continuar sendo meu OS principal. Depois, quem sabe?&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/3779015534537150391/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2014/03/do-java-para-o-c.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/3779015534537150391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/3779015534537150391'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2014/03/do-java-para-o-c.html' title='Do Java para o C#'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeGmOv9o3jdTNbVcOyYysbh6VXaM-VBAu583-t2doBogMBkqMWQ3SiOYvNMkDFyC57B6W0Hf2jjwziDgPxjOqlxDI52kS1mTq3h1FJjF-IqxEJwPN-5hr7B33d70Rg0YfWY5X8HmFa0onQ/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-1370410971814095748</id><published>2013-02-04T17:02:00.000-02:00</published><updated>2013-02-04T17:02:05.918-02:00</updated><title type='text'>Bug idiota no KDE e Kopete</title><content type='html'>Voltei pro KDE, e já achei um bug muito imbecil... normalmente eu uso o atalho de teclado &lt;b&gt;Ctrl&amp;nbsp;+ Shift&amp;nbsp;+ W&lt;/b&gt;&amp;nbsp;pra fechar todos os arquivos abertos em um determinado programa, por exemplo um editor de textos ou o Eclipse, mas se você instalar o &lt;b&gt;Kopete&lt;/b&gt;&amp;nbsp;isso para de funcionar!&lt;br /&gt;
&lt;br /&gt;
O que acontece é que o Kopete registra esse mesmo atalho pra mudança de status! Um comportamento padrão imbecil na minha opinião... Então se vocês estiverem com o mesmo problema já sabem de quem é a culpa, e basta desabilitar o tal atalho no Kopete pra resolver.</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/1370410971814095748/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2013/02/bug-idiota-no-kde-e-kopete.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/1370410971814095748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/1370410971814095748'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2013/02/bug-idiota-no-kde-e-kopete.html' title='Bug idiota no KDE e Kopete'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-8547804826036733605</id><published>2012-11-10T12:01:00.000-02:00</published><updated>2012-11-10T12:01:35.307-02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mongodb"/><title type='text'>MongoDB 1.8 :  assertion db/geo/2d.cpp:355</title><content type='html'>This is one of those things that you learn only by doing it... I was hacking with Grails and MongoDB, and suddenly found the error bellow while doing a geospatial query:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;db.location.find({&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;location: { $within: { $box: [ [ 22.873, -43.2 ], [ 20.0, -44.0 ] ] } } })&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;&lt;b&gt;error: { &quot;$err&quot; : &quot;assertion db/geo/2d.cpp:355&quot; }&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
You wont find any reference to this specific error, or file, other than the file itself on the MongoDB git repository. But while it took a couple of hours to figure out what was wrong, it&#39;s quite simple actually: &lt;b&gt;the points are reversed!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
MongoDB expects two points when searching within a box, &amp;nbsp;right-top and bottom-left, in this exact order... at least for version 1.8. So it was just a matter of reversing the points, and everything was working again.&lt;br /&gt;
&lt;br /&gt;
So the correct query would be that bellow:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;db.location.find({&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;location: { $within: { $box: [ [ 20.0, -44.0 ],&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace; font-size: x-small;&quot;&gt;[ 22.873, -43.2 ]&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace; font-size: x-small;&quot;&gt;&amp;nbsp;] } } })&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/8547804826036733605/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2012/11/mongodb-18-assertion-dbgeo2dcpp355.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/8547804826036733605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/8547804826036733605'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2012/11/mongodb-18-assertion-dbgeo2dcpp355.html' title='MongoDB 1.8 :  assertion db/geo/2d.cpp:355'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-7109255507279602517</id><published>2012-07-16T19:06:00.000-03:00</published><updated>2012-07-16T19:06:32.065-03:00</updated><title type='text'>Weblogic: DOMAIN_ROOT e System CLASSPATH</title><content type='html'>Conhecimentos adquiridos através do sofrimento... esbarrei em um projeto que carrega os arquivos &lt;i&gt;.properties&lt;/i&gt; da pasta DOMAIN_ROOT, isto é, a pasta raiz do seu domínio Weblogic.&lt;br /&gt;
&lt;br /&gt;
Acontece que, por algum motivo que eu desconheço, no Linux o DOMAIN_ROOT não é adicionado ao System Classpath... então qualquer chamada a &lt;i&gt;&lt;b&gt;getClassLoader().getResource(&quot;arquivo.properties&quot;)&lt;/b&gt;&lt;/i&gt; vai retornar &lt;i&gt;&lt;b&gt;Null&lt;/b&gt;&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Pra resolver isso, basta adicionar ao script &lt;b&gt;&lt;i&gt;setDomainenv.sh&lt;/i&gt;&lt;/b&gt;, que fica em &lt;i&gt;&lt;b&gt;${DOMAIN_ROOT}/bin&lt;/b&gt;&lt;/i&gt;, a seguinte linha:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name=&quot;code&quot;&gt;CLASSPATH=/opt/oracle/middleware/user_projects/domains/my_domain&lt;/pre&gt;&lt;br /&gt;
Substituindo o caminho pelo do seu domínio.</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/7109255507279602517/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2012/07/weblogic-domainroot-e-system-classpath.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/7109255507279602517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/7109255507279602517'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2012/07/weblogic-domainroot-e-system-classpath.html' title='Weblogic: DOMAIN_ROOT e System CLASSPATH'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-4340360061556709115</id><published>2012-07-12T01:09:00.000-03:00</published><updated>2012-07-12T22:55:40.772-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="oracle"/><title type='text'>Apanhando do Oracle XE 11g</title><content type='html'>Depois de passar os últimos 2 dias tentando instalar a versão &quot;completa&quot; do Oracle 11g em uma máquina virtual, e falhando miseravelmente, voltei meus esforços pra versão XE. E finalmente fui bem sucedido, usando o &lt;i&gt;openSuSE 12.1&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Uma dica em relação a instalação... se tudo for bem, mas na hora de criar o banco de dados começar a dar erro, pode ser que o &lt;i&gt;listener&lt;/i&gt; do Oracle não esteja subindo. Isso pode acontecer se o &lt;i&gt;hostname&lt;/i&gt; da máquina não estiver listado no arquivo &lt;i&gt;/etc/hosts&lt;/i&gt; associado a um IP, como 127.0.0.1 mesmo, ou não resolver via DNS. &lt;br /&gt;
&lt;br /&gt;
Só que meus problemas não acabaram por aí, eu precisava desse Oracle pra restaurar um &lt;i&gt;dump&lt;/i&gt; feito usando o utilitário &lt;i&gt;expdp&lt;/i&gt;. O que eu não sabia é que o Oracle mantém várias versões de arquivos de configuração de &lt;i&gt;Time zones&lt;/i&gt;, mas que a versão XE só vem com a mais recente, 14.&lt;br /&gt;
&lt;br /&gt;
O resultado é esse:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;UDI-31626: operation generated ORACLE error 31626
ORA-31626: job does not exist
ORA-39086: cannot retrieve job information
ORA-06512: at &quot;SYS.DBMS_DATAPUMP&quot;, line 3326
ORA-06512: at &quot;SYS.DBMS_DATAPUMP&quot;, line 4551
ORA-06512: at line 1&lt;/pre&gt;
&lt;br /&gt;
Fuçando mais um pouco, e olhando os arquivos de log da importação gerada pelo&lt;i&gt; impdp&lt;/i&gt;, eu descobri isso:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;ORA-39097: Data Pump job encountered unexpected error -30094
ORA-39065: unexpected master process exception in DISPATCH
ORA-30094: failed to find the time zone data file for version 11 in $ORACLE_HOME/oracore/zoneinfo&lt;/pre&gt;
&lt;br /&gt;
O problema é que todo o campo que contiver um valor &lt;b&gt;TIMESTAMP&lt;i&gt; &lt;/i&gt;&lt;/b&gt;vai estar vinculado a uma versão desses aquivos de &lt;i&gt;Time zone&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Como resolver esse impasse então? Bom, ainda não testei todas as possibilidades mas tem uma coisa que funciona... restaurar apenas os SCHEMAS sem o conteúdo das tabelas, a sintaxe do &lt;i&gt;impdb&lt;/i&gt; ficaria assim:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;impdp dumpfile=arquivo.dump content=metadata_only&lt;/pre&gt;
&lt;br /&gt;
A opção &lt;b&gt;content=metadata_only&lt;/b&gt; é o que faz ele ignorar o conteúdo das tabelas. Achei essa num blog muito apropriadamente denominado &lt;a href=&quot;http://oraclequirks.blogspot.com.br/2011/11/ora-30094-failed-to-find-time-zone-data.html&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;&lt;i&gt;Annals of Oracle&#39;s Improbable Errors.&lt;/i&gt;&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
A outra alternativa é pegar os arquivos de timezone que vem com o Oracle XE e copiar utilizando os nomes das versões anteriores, ou seja, substituindo o 14 por 13, 12, 11, 10... Tem um cara nessa &lt;a href=&quot;https://forums.oracle.com/forums/thread.jspa?threadID=2326206&quot; target=&quot;_blank&quot;&gt;thread dos fóruns da Oracle&lt;/a&gt; que jura que funciona, mas ainda não testei.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;UPDATE:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Fazer os links simbólicos funciona pra resolver o problema do &lt;b&gt;&lt;i&gt;impdp&lt;/i&gt;&lt;/b&gt;, fica assim:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;linux-1pk6:/home/admin # ls -l /u01/app/oracle/product/11.2.0/xe/oracore/zoneinfo/
total 1156
-rwxr-xr-x 1 oracle dba    6068 Ago 29  2011 readme.txt
-rwxr-xr-x 1 oracle dba   31525 Ago 29  2011 timezdif.csv
lrwxrwxrwx 1 root   root     15 Jul 12 22:50 timezlrg_10.dat -&amp;gt; timezlrg_14.dat
lrwxrwxrwx 1 root   root     15 Jul 12 22:50 timezlrg_11.dat -&amp;gt; timezlrg_14.dat
lrwxrwxrwx 1 root   root     15 Jul 12 22:50 timezlrg_12.dat -&amp;gt; timezlrg_14.dat
lrwxrwxrwx 1 root   root     15 Jul 12 22:50 timezlrg_13.dat -&amp;gt; timezlrg_14.dat
-rwxr-xr-x 1 oracle dba  791430 Ago 29  2011 timezlrg_14.dat
lrwxrwxrwx 1 root   root     15 Jul 12 22:50 timezone_10.dat -&amp;gt; timezone_14.dat
lrwxrwxrwx 1 root   root     15 Jul 12 22:50 timezone_11.dat -&amp;gt; timezone_14.dat
lrwxrwxrwx 1 root   root     15 Jul 12 22:50 timezone_12.dat -&amp;gt; timezone_14.dat
lrwxrwxrwx 1 root   root     15 Jul 12 22:50 timezone_13.dat -&amp;gt; timezone_14.dat
-rwxr-xr-x 1 oracle dba  344448 Ago 29  2011 timezone_14.dat&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/4340360061556709115/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2012/07/apanhando-do-oracle-xe-11g.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/4340360061556709115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/4340360061556709115'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2012/07/apanhando-do-oracle-xe-11g.html' title='Apanhando do Oracle XE 11g'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-416364321189622744</id><published>2012-05-25T17:20:00.000-03:00</published><updated>2012-05-25T17:20:18.112-03:00</updated><title type='text'>Rumor: Facebook vai comprar o Navegador Opera</title><content type='html'>Alguns sites, desde ontem, estão noticiando a possibilidade do Facebook comprar o browser noroeguês mais querido de todos nós, o Opera!&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
Forbes: &lt;a href=&quot;http://www.forbes.com/sites/reuvencohen/2012/05/25/facebook-rumored-to-be-in-talks-to-acquire-opera-to-create-a-facebook-browser/&quot; target=&quot;_blank&quot;&gt;Facebook rumored to be in talks to buy Opera...&lt;/a&gt;Engadget:&lt;a href=&quot;http://www.engadget.com/2012/05/25/facebook-could-be-looking-to-buy-opera/?a_dgi=aolshare_twitter&quot; target=&quot;_blank&quot;&gt; Facebook could be looking into buy Opera&lt;/a&gt;&amp;nbsp;&lt;/blockquote&gt;
Faz muito sentido, hoje os principais adversários do Facebook são o Google e a Microsoft, ambos no espaço de publicidade online... que é o ganha-pão tanto do Google quanto do Facebook, e um mercado onde a Microsoft quer entrar de qualquer jeito. Ambos tem um Browser, respectivamente o Internet Explorer e o Chrome... e por causa disso ambos conseguem exercer uma pressão enorme na hora de emplacar novas tecnologias pra web, que na realidade vão servir aos seus próprios interesses.&lt;br /&gt;
&lt;br /&gt;
Provavelmente o Facebook também tem sua agenda de quais novas features do HTML5 merecem um tratamento especial, e que maneira mais eficaz de garantir que essas features vão ser adotadas do que implementa-las você mesmo, no seu próprio browser?&lt;br /&gt;
&lt;br /&gt;
Na boa? Do jeito que as coisas estão, os caras poderiam transformar o Opera num cliente dedicado pro Facebook, que por acaso abre outras páginas, e muita gente nem iria notar a diferença...</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/416364321189622744/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2012/05/rumor-facebook-vai-comprar-o-navegador.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/416364321189622744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/416364321189622744'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2012/05/rumor-facebook-vai-comprar-o-navegador.html' title='Rumor: Facebook vai comprar o Navegador Opera'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-8074756691010453614</id><published>2012-03-13T17:19:00.002-03:00</published><updated>2012-03-14T18:41:36.775-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="agile"/><category scheme="http://www.blogger.com/atom/ns#" term="comics"/><title type='text'>TDD - O Coelho e a Tartaruga</title><content type='html'>Segue uma pequena fábula pra tentar explicar os benefícios de duas técnicas opostas de desenvolvimento: o &lt;a href=&quot;http://desciclopedia.org/wiki/Gambi_Design_Patterns&quot; target=&quot;_blank&quot;&gt;Go Horse&lt;/a&gt;&amp;nbsp;e o &lt;a href=&quot;http://pt.wikipedia.org/wiki/Test_Driven_Development&quot; target=&quot;_blank&quot;&gt;TDD&lt;/a&gt;, ou Test Driven Development. Clique na imagem para aumentar...&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJfZDn4oUmz8LZtQc333vuS1Lzs_gCduNyNy8y-3eIelHwHaoyaVwF08Dldsr4YdwkwbMdvfHH2l7-AmNxshvrerBfhxuytD9zap7P0ISlgFHcLPHck0loNQqpLquGEOMWn03-9Wkqk9mI/s1600/tdd.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;282&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJfZDn4oUmz8LZtQc333vuS1Lzs_gCduNyNy8y-3eIelHwHaoyaVwF08Dldsr4YdwkwbMdvfHH2l7-AmNxshvrerBfhxuytD9zap7P0ISlgFHcLPHck0loNQqpLquGEOMWn03-9Wkqk9mI/s400/tdd.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/8074756691010453614/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2012/03/tdd-o-coelho-e-tartaruga.html#comment-form' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/8074756691010453614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/8074756691010453614'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2012/03/tdd-o-coelho-e-tartaruga.html' title='TDD - O Coelho e a Tartaruga'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJfZDn4oUmz8LZtQc333vuS1Lzs_gCduNyNy8y-3eIelHwHaoyaVwF08Dldsr4YdwkwbMdvfHH2l7-AmNxshvrerBfhxuytD9zap7P0ISlgFHcLPHck0loNQqpLquGEOMWn03-9Wkqk9mI/s72-c/tdd.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-3411235192965031142</id><published>2012-02-14T17:42:00.001-02:00</published><updated>2012-02-14T17:42:28.537-02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="agile"/><category scheme="http://www.blogger.com/atom/ns#" term="comics"/><category scheme="http://www.blogger.com/atom/ns#" term="scrum"/><title type='text'>Reunião de Retrospectiva</title><content type='html'>&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4Y3j0vwf2spGdzCw5l35i1waZQ71qeVTBGurSbBWrJRpsghaRX9bn-S3HM3A-YCiBDb82jFVHrjpy_RgR24XPkuri2NcbALbkaMHgbfDp2iDHVBPbO8OfSRVJd8PQrQHh6zmj0Dhcrwg0/s1600/review_meeting.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4Y3j0vwf2spGdzCw5l35i1waZQ71qeVTBGurSbBWrJRpsghaRX9bn-S3HM3A-YCiBDb82jFVHrjpy_RgR24XPkuri2NcbALbkaMHgbfDp2iDHVBPbO8OfSRVJd8PQrQHh6zmj0Dhcrwg0/s640/review_meeting.png&quot; width=&quot;451&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Feito pra ilustrar o que é uma reunião de retrospectiva pros novatos lá da Ideais, onde eu trabalho. Clique pra ampliar.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/3411235192965031142/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2012/02/reuniao-de-retrospectiva.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/3411235192965031142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/3411235192965031142'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2012/02/reuniao-de-retrospectiva.html' title='Reunião de Retrospectiva'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4Y3j0vwf2spGdzCw5l35i1waZQ71qeVTBGurSbBWrJRpsghaRX9bn-S3HM3A-YCiBDb82jFVHrjpy_RgR24XPkuri2NcbALbkaMHgbfDp2iDHVBPbO8OfSRVJd8PQrQHh6zmj0Dhcrwg0/s72-c/review_meeting.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-145690692285047030</id><published>2011-12-09T09:57:00.001-02:00</published><updated>2011-12-09T11:51:06.898-02:00</updated><title type='text'>Scaling MySQL : Facebook &amp; Twitter</title><content type='html'>Agora que estamos no meio dessa onda de substituir bancos relacionais por outros modelos, o tal NoSQL, esses dois tech talks trazem uma perspectiva diferente ao debate.&lt;br /&gt;
&lt;br /&gt;
A apresentação do Twitter é mais focada em como organizar os dados no banco de forma que seja possível segmentar a informação, e planejar as queries para que a área de impacto seja a menor possível. É um passeio superficial em como foi adaptar a infra-estrutura para acomodar o crescimento. E a pesar de estarem &lt;a href=&quot;http://engineering.twitter.com/2010/07/cassandra-at-twitter-today.html&quot; target=&quot;_blank&quot;&gt;lentamente migrando para o Cassandra&lt;/a&gt;, a base de dados para os Tweets continua sendo o MySQL.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.infoq.com/presentations/Big-Data-in-Real-Time-at-Twitter&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;297&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdamLldZpK7bcPun_8QcL5JICiw6rUjA7qSQhjRtjfpdgBR0dV64sq-Pot7E7EKzH-XBRywYslej0AhKfol6TdDPZfgtGCkOFo9g72wUnQqnPrR9pniNVvXnoVYTPowC9q_-CIZl-MzjX/s400/Screenshot+at+2011-12-09+11%253A11%253A54.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;clique na imagem pra ver a apresentação no site da infoq&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
O vídeo do pessoal do Facebook é muito mais focado nas soluções para os problemas do dia-a-dia, operacionais, que eles tem administrando uma base de dados que cresceu 7x nos últimos dois anos. E que tem um volume insano, na casa de dezenas de milhões de transações por segundo. Nesse tech-talk podemos ver o quanto os caras investiram no MySQL, a performance que eles conseguem não veio sem custos, e muita coisa eles mesmos tiveram que desenvolver pra resolver os problemas conforme foram aparecendo... Não é dizer que eles não investigam soluções NoSQL, &lt;a href=&quot;https://www.facebook.com/note.php?note_id=24413138919&quot; target=&quot;_blank&quot;&gt;os caras criaram o Cassandra&lt;/a&gt;, e &lt;a href=&quot;https://www.facebook.com/note.php?note_id=454991608919&quot; target=&quot;_blank&quot;&gt;usam o Haddop e HBase no engine de mensagens&lt;/a&gt;, mas o core do Facebook ainda depende do MySQL.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;iframe frameborder=&quot;0&quot; height=&quot;340&quot; scrolling=&quot;no&quot; src=&quot;http://cdn.livestream.com/embed/fbtechtalks?layout=4&amp;amp;clip=pla_a3d62538-1238-4202-a3be-e257cd866bb9&amp;amp;color=0xe7e7e7&amp;amp;autoPlay=false&amp;amp;mute=false&amp;amp;iconColorOver=0x888888&amp;amp;iconColor=0x777777&amp;amp;allowchat=true&amp;amp;height=340&amp;amp;width=560&quot; style=&quot;border: 0; outline: 0;&quot; width=&quot;560&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div style=&quot;font-size: 11px; padding-top: 10px; text-align: center; width: 560px;&quot;&gt;
Watch &lt;a href=&quot;http://www.livestream.com/?utm_source=lsplayer&amp;amp;utm_medium=embed&amp;amp;utm_campaign=footerlinks&quot; streaming=&quot;&quot; title=&quot;live&quot; video=&quot;&quot;&gt;live streaming video&lt;/a&gt; from &lt;a at=&quot;&quot; fbtechtalks=&quot;&quot; href=&quot;http://www.livestream.com/fbtechtalks?utm_source=lsplayer&amp;amp;utm_medium=embed&amp;amp;utm_campaign=footerlinks&quot; livestream.com=&quot;&quot; title=&quot;Watch&quot;&gt;fbtechtalks&lt;/a&gt; at livestream.com&lt;/div&gt;
&lt;br /&gt;
Em ambos os casos, Twitter e Facebook, existe um uso extensivo de cache. No caso ambos usam o &lt;a href=&quot;http://memcached.org/&quot; target=&quot;_blank&quot;&gt;Memcached&lt;/a&gt;, que é um cache em memória e distribuído via rede num esquema cliente-servidor.&lt;br /&gt;
&lt;br /&gt;
Vou falar pra vocês que eu acho todas essas soluções NoSQL bem promissoras, em particular o &lt;a href=&quot;http://www.mongodb.org/&quot; target=&quot;_blank&quot;&gt;MongoDB&lt;/a&gt; é bem legal, mas se pintasse um projeto onde fosse cabível usar MySQL com Memcached... putz, eu não iria reclamar não, seria diversão de primeira.</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/145690692285047030/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/12/scaling-mysql-facebook-twitter.html#comment-form' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/145690692285047030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/145690692285047030'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/12/scaling-mysql-facebook-twitter.html' title='Scaling MySQL : Facebook &amp; Twitter'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEdamLldZpK7bcPun_8QcL5JICiw6rUjA7qSQhjRtjfpdgBR0dV64sq-Pot7E7EKzH-XBRywYslej0AhKfol6TdDPZfgtGCkOFo9g72wUnQqnPrR9pniNVvXnoVYTPowC9q_-CIZl-MzjX/s72-c/Screenshot+at+2011-12-09+11%253A11%253A54.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-8959857528418169039</id><published>2011-12-06T12:05:00.001-02:00</published><updated>2011-12-08T12:49:44.412-02:00</updated><title type='text'>JDeveloper display issues on Ubuntu 10.11</title><content type='html'>I don&#39;t really know what&#39;s triggering this bug, but it&#39;s really annoying and it makes JDeveloper unusable... take a look on what happens:&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0C303MnOtPaXUJ0S8r4mmoRZZek31t_NJslmthHCnNCU9IFrrffuZ6ScrYrsWwpOoz3m7_DriJiCqPvjC341LxDDt5I0ZqCbFcwf1pDHFLfe1MNuKMvbbjYyDXR7B30wV5x3-rBrPrjrp/s1600/Screenshot+at+2011-12-06+11%253A48%253A55.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;311&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0C303MnOtPaXUJ0S8r4mmoRZZek31t_NJslmthHCnNCU9IFrrffuZ6ScrYrsWwpOoz3m7_DriJiCqPvjC341LxDDt5I0ZqCbFcwf1pDHFLfe1MNuKMvbbjYyDXR7B30wV5x3-rBrPrjrp/s400/Screenshot+at+2011-12-06+11%253A48%253A55.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;What a mess...&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Right now I think it&#39;s a combination of:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;XOrg 1.9&lt;/li&gt;
&lt;li&gt;Compiz&lt;/li&gt;
&lt;li&gt;ATI Drivers&lt;/li&gt;
&lt;li&gt;Radeon 43XX cards&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
How do I fix it? It&#39;s kind of a hack, but it sort of works... I had to figure a way to bypass the 2D acceleration provided by the ATI native driver, so it was a matter of switching to the VESA driver, or running anoter XServer on top of the current one, and that&#39;s what I did.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
At first I went with XNest or Xephyr, but then JDeveloper would appear on a Window inside the XNest window, and it was annoying and not very usable. So instead I used &lt;b&gt;xpra&lt;/b&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;xpra&lt;/b&gt;&amp;nbsp;is a solution build around xvfb, it renders the application to a virtual framebuffer device so it doesn&#39;t need a real video hardware, and you can attach and detach your local xserver to it. Think of it as a X11 version of the &lt;b&gt;screen&lt;/b&gt;&amp;nbsp;command.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So, on Ubuntu do:&lt;/div&gt;
&lt;div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;$ sudo apt-get install xpra&lt;br /&gt;$ xpra start :100&lt;br /&gt;$ DISPLAY=:100 /&lt;path_to_mid_home&gt;/jdeveloper/jdev/bin/jdev &amp;amp;&lt;/path_to_mid_home&gt;$ xpra attach :100&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
This will take care of the rendering issues, and you&#39;ll get a window that you can resize at will.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/8959857528418169039/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/12/jdeveloper-display-issues-on-ubuntu.html#comment-form' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/8959857528418169039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/8959857528418169039'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/12/jdeveloper-display-issues-on-ubuntu.html' title='JDeveloper display issues on Ubuntu 10.11'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0C303MnOtPaXUJ0S8r4mmoRZZek31t_NJslmthHCnNCU9IFrrffuZ6ScrYrsWwpOoz3m7_DriJiCqPvjC341LxDDt5I0ZqCbFcwf1pDHFLfe1MNuKMvbbjYyDXR7B30wV5x3-rBrPrjrp/s72-c/Screenshot+at+2011-12-06+11%253A48%253A55.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-3806625111970521944</id><published>2011-12-01T18:10:00.001-02:00</published><updated>2011-12-01T18:18:39.145-02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="11.10"/><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="sun"/><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu"/><title type='text'>Usar Java da SUN no Ubuntu 11.10</title><content type='html'>&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;$ sudo add-apt-repository &quot;deb http://archive.canonical.com/ lucid partner&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;$ sudo apt-get update&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;$ sudo apt-get install sun-java6-jdk&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;$ sudo update-alternatives --config java&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; Selection &amp;nbsp; &amp;nbsp;Path &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Priority &amp;nbsp; Status&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; 0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/usr/lib/jvm/java-6-openjdk/jre/bin/java &amp;nbsp; 1061 &amp;nbsp; &amp;nbsp; &amp;nbsp;auto mode&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; 1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/usr/lib/jvm/java-6-openjdk/jre/bin/java &amp;nbsp; 1061 &amp;nbsp; &amp;nbsp; &amp;nbsp;manual mode&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #660000;&quot;&gt;* &lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #cc0000;&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #660000;&quot;&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;/usr/lib/jvm/java-6-sun/jre/bin/java &amp;nbsp; &amp;nbsp; &amp;nbsp; 63 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;manual mode&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Press enter to keep the current choice[*], or type selection number: &lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #cc0000;&quot;&gt;2&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #cc0000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;$java -version&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;java version &quot;1.6.0_26&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Java(TM) SE Runtime Environment (build 1.6.0_26-b03)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/3806625111970521944/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/12/usar-java-da-sun-no-ubuntu-1110.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/3806625111970521944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/3806625111970521944'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/12/usar-java-da-sun-no-ubuntu-1110.html' title='Usar Java da SUN no Ubuntu 11.10'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-1639077761923160609</id><published>2011-09-26T21:25:00.000-03:00</published><updated>2011-09-26T21:27:00.189-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><category scheme="http://www.blogger.com/atom/ns#" term="jpa"/><category scheme="http://www.blogger.com/atom/ns#" term="maven"/><category scheme="http://www.blogger.com/atom/ns#" term="spring"/><category scheme="http://www.blogger.com/atom/ns#" term="struts"/><category scheme="http://www.blogger.com/atom/ns#" term="twitter"/><category scheme="http://www.blogger.com/atom/ns#" term="twitter4j"/><title type='text'>Tutorial: Twitter com Java, Struts2 e Spring</title><content type='html'>Vou mostrar aqui a solução que eu encontrei pra integrar o Twitter com uma aplicação baseada em Struts 2 e Spring. Hoje já existe um projeto do Spring chamado &lt;a href=&quot;http://www.springsource.org/spring-social&quot;&gt;Spring-Social&lt;/a&gt; que resolve boa parte do que eu estou explico aqui, mas ainda não parei para entender direito como tudo funciona nele, outro problema é que a pesar dele já se integrar com o Spring-Security e com o Spring-Web-MVC não tem nenhuma integração pronta pro Struts2, que é a minha escolha preferida.&lt;br /&gt;
&lt;br /&gt;
Pegue &lt;a href=&quot;https://github.com/vhogemann/Struts2-Twitter-Integration&quot;&gt;no GitHub o código fonte completo desse tutorial&lt;/a&gt;, mas lembre-se que pra fazer funcionar você ainda vai precisar se registrar como desenvolvedor no Twitter, e registrar uma aplicação para obter as chaves de acesso à API.&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;O problema&lt;/h1&gt;Criar uma solução reutilizável de autenticação no Twitter para aplicações Java, nesse caso baseadas em Spring e Struts2. Eu não consegui encontrar nada 100% pronto, então parti pra integrar as bibliotecas que eu já conhecia. Estou assumindo aqui que você vai guardar as informações de usuário de alguma forma, e por isso tem no seu modelo uma entidade pra isso. Como falei lá em cima, vou usar duas entidades aqui User e TwitterAccount.&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;A solução&lt;/h1&gt;Antes de mais nada, abaixo segue um breve descritivo das principais bibliotecas que eu estou utilizando, não vou me aprofundar muito em como configurar cada uma... o foco aqui é mostrar como utilizar cada uma, com o Twitter4J, pra se autenticar e utilizar o Twitter como uma aplicação cliente.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Struts 2&lt;/h3&gt;É um framework para construir aplicações Web em Java, é bem maduro e excepcionalmente versátil. Não é exatamente o mais fácil de aprender, e pode ser até mesmo frustrante tentar se entender com sua configuração, mas depois que se pega o jeito da coisa dá pra ver que ele é muito poderoso sem ser absurdamente complicado.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Spring&lt;/h3&gt;É um framework, com muitas, muitas funcionalidades, suporte e integração a trocentas tecnologias. Mas quando falamos de Spring, normalmente nos referimos ao container de IoC. Nele a responsabilidade de instanciar, e associar seus objetos uns com os outros é tirada das suas mãos, o Spring oferece um jeito absurdamente mais fácil de organizar o ciclo de vida da sua aplicação, e de gerenciar o gráfico de inter-dependências entre seus objetos. Se você programa profissionalmente em Java já usa, usou ou vai usar.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Twitter4j&lt;/h3&gt;É a biblioteca que eu escolhi para fazer a comunicação com o Twitter. Tem uma API muito fácil, e funciona diretinho, inclusive com a nova autenticação baseada em OAuth. O único problema é que o jeito de usar meio que bate de frente com algumas coisas que o Spring assume, então eu precisei criar uma Factory pra encapsular o Twitter4j.Factory e instanciar os objetos Twitter pelo Spring.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Modelo&lt;/h2&gt;Vamos então conhecer nosso modelo de User. Ele é bem básico, nesse caso eu só vou deixar nessa classe base o essencial. A idéia é que essas sejam informações comuns, que eu possa preencher a partir do Twitter. O User está associado a uma ou mais Accounts, que é onde estão todos os detalhes de identificação e acesso ao Twitter.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmup6Or3AE2bfF2HO3w_kxSsR9AsJixB7l0Shs3pyhveSip8YXNlnzcy0WBACWTdb0ly7b5FRj5iD3hQ-UeehAnFvWc63uAnOa8bF5Kc9fQAI6lD1UpDMiJcHmzhMhb1yOyiQatJUxVshh/s1600/Modelo_ER.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;168&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmup6Or3AE2bfF2HO3w_kxSsR9AsJixB7l0Shs3pyhveSip8YXNlnzcy0WBACWTdb0ly7b5FRj5iD3hQ-UeehAnFvWc63uAnOa8bF5Kc9fQAI6lD1UpDMiJcHmzhMhb1yOyiQatJUxVshh/s320/Modelo_ER.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;em&gt;Olha só, um diagrama ER!&lt;/em&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;Classe User&lt;/h3&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class User extends AbstractEntity {

	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name=&quot;id&quot;)
	private long id;
	
	@Column
	private String nick;
	
	@Column
	private String name;
	
	@Column 
	private String image;
	
	@OneToMany(fetch=FetchType.EAGER)
	private List&lt;account&gt; accounts;
	
	...

}
&lt;/pre&gt;&lt;br /&gt;
Pelas anotações alguns vão perceber que eu estou usando JPA, mas na realidade o jeito que você vai persistir essas informações não é tão importante pra integração com o Twitter.&lt;br /&gt;
Account é uma classe base, utilizada pra criar tantos tipos quanto forem necessários. Nesse exemplo iremos utilizar o Twitter, mas é possível criar implementações para Facebook, Google, Foursquare e o que mais for do seu agrado.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Classe Account&lt;/h3&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class Account extends AbstractEntity {

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private long id;
	
	@ManyToOne
	private User user;
	
    ...

}
&lt;/pre&gt;&lt;br /&gt;
TwitterAccount herda de Account, e adiciona os atributos necessários para processarmos a autenticação.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Classe TwitterAccount&lt;/h3&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;

@Entity
public class TwitterAccount extends Account {

	private static final long serialVersionUID = 1L;
	
	@Column
	private Long twitterId;

	@Column
	private String token;
	
	@Column 
	private String secret;
	
	@Transient
	private Twitter twitter;
	
	@Transient
	private AccessToken accessToken;

	@Transient
	private RequestToken requestToken;

    ...

}
&lt;/pre&gt;&lt;br /&gt;
Esses são só os atributos, depois vamos ver alguns métodos que vão auxilar no processo de autenticar o usuário no Twitter, e depois resgatar as informações do usuário para não precisarmos autenticar novamente.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Autenticando o Usuário&lt;/h2&gt;&lt;br /&gt;
Vamos dar uma olhada em tudo que acontece entre o usuário clicar em &lt;em&gt;Entrar&lt;/em&gt; até o momento em que ele já autorizou a aplicação a acessar sua conta do Twitter. &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzRsVNZlRwA82xK6QtYUbrnmnP_1Zr8wuF7Hl_oGo1UNSPXN8gfmXmlaCCyKQsBukD2IPbYHX7mRvKzFfV1ubHsLhZewSO-OjB2SslONHsMbnERH7UQ6kbKsrpZXtatS7Qe4BiRKlYg6iO/s1600/Authentication.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;260&quot; width=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzRsVNZlRwA82xK6QtYUbrnmnP_1Zr8wuF7Hl_oGo1UNSPXN8gfmXmlaCCyKQsBukD2IPbYHX7mRvKzFfV1ubHsLhZewSO-OjB2SslONHsMbnERH7UQ6kbKsrpZXtatS7Qe4BiRKlYg6iO/s400/Authentication.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;em&gt;Continue lendo e esse diagrama vai fazer sentido, eu prometo&lt;/em&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;TwitterAuthInterceptor&lt;/h3&gt;&lt;br /&gt;
Se você nunca viu Struts2 na sua vida aqui as coisas vão ficar meio nebulosas, mas vamos lá... No Struts2 existe o conceito de &lt;em&gt;Interceptors&lt;/em&gt;, que são bem parecidos com os os &lt;em&gt;Servlet Filters&lt;/em&gt;, só que eles atuam apenas nas Actions que você definir. Bom, nosso amigo &lt;em&gt;TwitterAuthInterceptor&lt;/em&gt; é responsável por verificar se existe uma &lt;em&gt;Account&lt;/em&gt; na sessão, e se não houver ver se consegue criar uma verificando um cookie.&lt;br /&gt;
&lt;br /&gt;
É ele o responsável por &quot;lembrar&quot; do usuário entre cada visita ao aplicativo.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;TwitterOAuthRequestAction&lt;/h3&gt;&lt;br /&gt;
Aqui que as coisas ficam interessantes, essa &lt;em&gt;Action&lt;/em&gt; que é responsável por enviar pro usuário um redirecionamento que vai leva-lo à página de autorização do Twitter, vamos dar uma olhada melhor nele.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;@Controller(&quot;twitterAuth&quot;)
public class TwitterOauthRequestAction implements SessionAware {

	private static final long serialVersionUID = 1L;

	@Autowired
	private TwitterService service;

	private Map&lt;String, Object&gt; session;

	private String redirect;

	public String execute() {

		TwitterAccount account = service.startAuthentication();
		redirect = account.getAuthenticationURL();
		session.put(TwitterService.TWITTER_USER, account);

		return &quot;success&quot;;
	}

	public void setSession(Map&lt;String, Object&gt; session) {
		this.session = session;
	}

	public String getRedirect() {
		return redirect;
	}

}
&lt;/pre&gt;&lt;br /&gt;
Como você deve ter adivinhado, a mágica mesmo ocorre em &lt;em&gt;TwitterService&lt;/em&gt; e &lt;em&gt;TwitterAccount&lt;/em&gt;. Vamos dar uma olhada nelas:&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;TwitterServiceImpl&lt;/h3&gt;&lt;br /&gt;
Esse aqui é o responsável por concentrar a maior parte das ações de criar, autenticar e salvar as contas. Por exemplo, o método &lt;em&gt;public TwitterAccount startAuthentication()&lt;/em&gt; que vimos acima retorna uma &lt;em&gt;TwitterAccount&lt;/em&gt; pronta para ser autenticada.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;public class TwitterServiceImpl implements TwitterService {

	private static final Log log = LogFactory.getLog(TwitterService.class);
	
	@Autowired
	private TwitterAccountRepository repository;
	
	@Autowired
	private TwitterFactory factory;
	
	@Autowired
	private String twitterCallbackUrl = &quot;http://localhost:8080/stamp/twittercallback&quot;;
	
	public TwitterAccount startAuthentication() {
		
		try {
			Twitter twitter = factory.getTwitter();
			RequestToken requestToken = twitter.getOAuthRequestToken(twitterCallbackUrl);
			TwitterAccount account = new TwitterAccount(twitter, requestToken);
			return account;
		} catch (TwitterException e) {
			log.error(e);
		}
		
		return null;
	}

        ...

}
&lt;/pre&gt;&lt;br /&gt;
Está na hora de darmos mais uma olhada em &lt;em&gt;TwitterAccount&lt;/em&gt;, dessa vez no construtor &lt;em&gt;TwitterAccount(Twitter twitter, RequestToken requestToken)&lt;/em&gt; e no método &lt;em&gt;TwitterAccount(Twitter twitter, RequestToken requestToken)&lt;/em&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Classe TwitterAccount&lt;/h3&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;public TwitterAccount(Twitter twitter, RequestToken requestToken){
		this.twitter = twitter;
		this.requestToken = requestToken;
	}

       ...

	public String getAuthenticationURL(){
		if(this.requestToken == null)
			return null;
		return requestToken.getAuthenticationURL();
	}
&lt;/pre&gt;&lt;br /&gt;
Nada demais, certo? Como você já deve ter percebido &lt;em&gt;TwitterAccount&lt;/em&gt; encapsula o objeto &lt;em&gt;Twitter&lt;/em&gt; do &lt;em&gt;Twitter4J&lt;/em&gt;, esse é objeto que vai representar a conexão do usuário com o Twitter, e a maioria das chamadas a API vai ser intermediada através dele.&lt;br /&gt;
&lt;br /&gt;
O método &lt;em&gt;public String getAuthenticationURL()&lt;/em&gt; encapsula a chamada ao método de mesmo nome do &lt;em&gt;requestToken&lt;/em&gt; que é responsável por mediar a autenticação OAuth. Ele retorna uma URL que direciona para a página do Twitter que pede ao usuário que permita a aplicação acesso a sua conta, uma vez concedida o Twitter redireciona o usuário para a URL definida pela URL &lt;em&gt;twitterCallbackUrl&lt;/em&gt;, que no nosso caso aponta para a action &lt;em&gt;TwitterOAuthCallbackAction&lt;/em&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;TwitterOAuthCallbackAction&lt;/h3&gt;&lt;br /&gt;
Após o usuário dar permissão para a aplicação no Twitter ele é redirecionado para essa action. O que acontece agora é o seguinte, a aplicação vai tentar verificar se existe um &lt;em&gt;TwitterAccount&lt;/em&gt; salvo na sessão, e utiliza-lo para completar a autenticação via OAuth. Procuramos ver também se já existe uma conta prévia para esse usuário, e tentamos recupera-la da persistência, do contrário a cada tentativa de autenticação o usuário acabaria com uma conta nova!&lt;br /&gt;
&lt;br /&gt;
Após a validação da conta com as credenciais enviadas pelo Twitter, salvamos a conta na persistência, e criamos o Cookie para que da próxima vez que o usuário volte não precise autorizar a aplicação novamente com o Twitter, suas credenciais serão salvas juntamente com a conta. No caso eu apenas estou codificando o ID da conta como Base32 e gravando no Cookie, em uma aplicação real provavelmente você vai querer esconder melhor a identificação do seu usuário para evitar que alguém roube a identidade dele no aplicativo.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;public class TwitterOauthCallbackAction implements ServletResponseAware {

	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(TwitterOauthCallbackAction.class);
	private String oauth_verifier;
	
	@Autowired
	private TwitterService service;
	
	@Autowired
	private TwitterAccountRepository accountRepository;

	private HttpServletResponse response;
	
	public String execute(){
		
		Map&lt;String,Object&gt; session = ActionContext.getContext().getSession();
		
		TwitterAccount user = service.getFromSession(session);
		
		if(user != null &amp;&amp; !user.isAuthenticated()) try {
			user.authenticate(oauth_verifier);
			
			TwitterAccount recycled = recycle(user);
			long id = 0;
			if(recycled != null){
				user = recycled;
				id = user.getId();
			} else {
				id = service.save(user);
			}
			String base32 = Base32.encode(String.valueOf(id).getBytes());
			Cookie cookie = new Cookie(TwitterService.TWITTER_COOKIE,base32);
			cookie.setMaxAge(60*60*24*15);
			response.addCookie(cookie);
		
		} catch (TwitterException e) {
			log.warn(&quot;Erro ao processar callback do Twitter&quot;,e);
			return &quot;error&quot;;
		}
		
		return &quot;success&quot;;
	}
	
	/**
	 * Tenta encontrar uma conta de usuário na persistencia
	 * que já tenha sido utilizada, e associa o ID dela
	 * ao usuário com as informações de autenticação
	 * 
	 * @param account
	 */
	private TwitterAccount recycle(TwitterAccount account){
		TwitterAccount recycled = accountRepository.findFirst(account);
		if(recycled != null){
			recycled.recycle(account);
		}
		return recycled;
	}
	
	public void setOauth_verifier(String oauth_verifier) {
		this.oauth_verifier = oauth_verifier;
	}

	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}
}
&lt;/pre&gt;&lt;br /&gt;
E basicamente é isso, a partir daí você tem um Objeto &lt;em&gt;TwitterAccount&lt;/em&gt; na sessão, que encapsula o &lt;em&gt;twitter4j.Twitter&lt;/em&gt;, é só explorar um pouco mais o código e ir adicionando as funcionalidades que você precisar, listar os posts do usuário, criar novos, consultar seguidores e etc...&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Referências&lt;/h2&gt;&lt;blockquote&gt;Twitter4J - http://twitter4j.org/&lt;br /&gt;
&lt;br /&gt;
Struts2 - http://struts.apache.org/2.2.1/&lt;br /&gt;
&lt;br /&gt;
Spring - http://www.springsource.org/&lt;br /&gt;
&lt;br /&gt;
Maven - http://maven.apache.org/&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/1639077761923160609/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/09/tutorial-twitter-com-java-struts2-e.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/1639077761923160609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/1639077761923160609'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/09/tutorial-twitter-com-java-struts2-e.html' title='Tutorial: Twitter com Java, Struts2 e Spring'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmup6Or3AE2bfF2HO3w_kxSsR9AsJixB7l0Shs3pyhveSip8YXNlnzcy0WBACWTdb0ly7b5FRj5iD3hQ-UeehAnFvWc63uAnOa8bF5Kc9fQAI6lD1UpDMiJcHmzhMhb1yOyiQatJUxVshh/s72-c/Modelo_ER.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-5010070950324779533</id><published>2011-09-22T16:27:00.002-03:00</published><updated>2011-09-22T16:27:52.328-03:00</updated><title type='text'>Preparando um novo tutorial...</title><content type='html'>Estou estreiando minha conta no github com um projeto pessoal que vou transformar em tutorial, é uma aplicação java usando Maven, Struts2, Spring e JPA que usa o Twitter para autenticar seus usuários. O repositório é o seguinte:&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href=&quot;https://github.com/vhogemann/Struts2-Twitter-Integration&quot;&gt;https://github.com/vhogemann/Struts2-Twitter-Integration&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
O código ainda está bagunçado e com pedaços do que iria ser outro projeto, e eu estou ajeitando tudo pra ficar mais organizado. A ideia é ir adicionando suporte a outras redes sociais conforme a coisa for evoluindo, então primeiro vem o Twitter, depois vou integrar o Facebook, Google, Orkut, e o que mais for aparecendo pela frente.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/5010070950324779533/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/09/preparando-um-novo-tutorial.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/5010070950324779533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/5010070950324779533'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/09/preparando-um-novo-tutorial.html' title='Preparando um novo tutorial...'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-5842774896232833755</id><published>2011-09-12T19:06:00.001-03:00</published><updated>2011-09-12T19:06:01.490-03:00</updated><title type='text'>EHCache com anotações no Spring</title><content type='html'>&lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Esse é um artigo que eu estava escrevendo para uma revista, mas por um motivo ou outro nunca encontrei tempo pra deixa-lo no ponto de ser publicado… Pra não ficar pegando poeira no meu HD resolvi publica-lo aqui no blog. Espero que seja útil!&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Caches são uma técnica comum para resolver problemas de performance. A ideia por trás é guardar informações para que possam ser reutilizadas, ao invés de arcar com os custos de gerar os dados novamente.  &lt;p&gt;Eles são tão difundidos que podemos os encontrar em praticamente todos os níveis de um sistema, desde o processador, passando pelo sistema operacional, aplicações e entre diversas máquinas interconectadas em uma rede.  &lt;p&gt;É natural então que encontremos implementações de cache para o Java, desde as mais simples até soluções que distribuem gigabytes de dados entre várias máquinas diferentes. Nesse artigo vamos tratar de uma solução em especial, que se integra ao SpringFramework e é bem fácil de ser aplicada na grande maioria dos projetos que o utilizam.  &lt;p&gt;&amp;nbsp; &lt;h2&gt;EHCache Spring Annotations&lt;/h2&gt; &lt;p&gt;Essa é a solução que é apresentada aqui, um projeto open-source que visa simplificar a aplicação e o uso do cache através do uso de anotações. É o sucessor de outro projeto, o Spring-Cache Module, que foi descontinuado, e não tem mais desenvolvimento ativo.  &lt;p&gt;&amp;nbsp; &lt;h2&gt;Spring Framework&lt;/h2&gt; &lt;p&gt;Mais que um conjunto de bibliotecas, oferece um conjunto integrado completo de soluções para o desenvolvimento Java. O Spring oferece diversos módulos que facilitam a integração de praticamente todas as tecnologias utilizadas no desenvolvimento J2EE. Também é um projeto open-source, e tem uma grande comunidade de desenvolvedores e usuários ao seu redor.  &lt;p&gt;O EHCache Spring Annotations é uma extensão do Spring, e depende dele para ser utilizado.&amp;nbsp;&amp;nbsp; &lt;p&gt;&amp;nbsp; &lt;h2&gt;EHCache&lt;/h2&gt; &lt;p&gt;É uma implementação open-source de cache em Java, popular e amplamente utilizada é a base para a JSR-107 que visa definir uma API comum de cache para a linguagem. A simplicidade e facilidade de utilização contribuíram para sua popularidade.  &lt;p&gt;O EHCache pode ser utilizado de diversas maneiras, por exemplo ele pode fazer caching das requisições enviadas a uma aplicação Web, já enviando a resposta utilizando compressão gzip. Praticamente como implementar um proxy reverso direto na sua aplicação. Para essa e outras utilizações, visite a página do projeto, veja o link ao final do artigo.  &lt;p&gt;&amp;nbsp; &lt;h2&gt;Configuração&lt;/h2&gt; &lt;p&gt;O primeiro passo é fazer o download da última versão do EHCache Spring Annotations a partir do site, e incluir o jar e suas dependências no classpath. Faça o download no link abaixo:  &lt;blockquote&gt; &lt;p&gt;http://code.google.com/p/ehcache-spring-annotations/downloads/list&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Após isso precisamos do EHCache, portanto faça o download da distribuição a partir do site oficial. Vamos utilizar a versão 1.2.4 do ehcache.jar.  &lt;blockquote&gt; &lt;p&gt;http://www.terracotta.org/dl/ehcache-oss-download-catalog&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Nos meus projetos prefiro deixar a cargo do Maven a tarefa de baixar e resolver as dependências das bibliotecas que utilizo. O Maven é uma ferramenta completa, que pode gerenciar todo ciclo de vida do seu projeto, do desenvolvimento ao deploy, passando por execução de testes e build do projeto. A &lt;em&gt;listagem 1&lt;/em&gt; mostra o trecho que deve ser incluído ao arquivo de configuração do projeto, pom.xml.  &lt;p&gt;Listagem 1. Configuração do ehcache e ehcache-spring-annotations para o maven  &lt;hr&gt;  &lt;blockquote&gt; &lt;p&gt;&amp;lt;pom&amp;gt;&lt;br&gt;...&lt;br&gt;&amp;lt;dependências&amp;gt;&lt;br&gt;... &lt;br&gt;&amp;lt;dependency&amp;gt;&lt;br&gt;&amp;lt;groupId&amp;gt;com.googlecode.ehcache-spring-annotations&amp;lt;/groupId&amp;gt;&lt;br&gt;&amp;lt;artifactId&amp;gt;ehcache-spring-annotations&amp;lt;/artifactId&amp;gt;&lt;br&gt;&amp;lt;version&amp;gt;1.1.3&amp;lt;/version&amp;gt;&lt;br&gt;&amp;lt;/dependency&amp;gt;&lt;br&gt;&amp;lt;dependency&amp;gt;&lt;br&gt;&amp;lt;groupId&amp;gt;net.sf.ehcache&amp;lt;/groupId&amp;gt;&lt;br&gt;&amp;lt;artifactId&amp;gt;ehcache&amp;lt;/artifactId&amp;gt;&lt;br&gt;&amp;lt;version&amp;gt;1.2.4&amp;lt;/version&amp;gt;&lt;br&gt;&amp;lt;type&amp;gt;jar&amp;lt;/type&amp;gt;&lt;br&gt;&amp;lt;scope&amp;gt;compile&amp;lt;/scope&amp;gt;&lt;br&gt;&amp;lt;/dependency&amp;gt;&lt;br&gt;...&lt;br&gt;&amp;lt;/dependências&amp;gt;&lt;br&gt;...&lt;br&gt;&amp;lt;/pom&amp;gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Após isso é necessário criar um arquivo para configurar os caches do EHCache, qué chamado ehcache.xml e deve ser colocado no classpath da aplicação. A&lt;em&gt; listagem 2&lt;/em&gt; mostra um arquivo com uma configuração mínima, note que podemos configurar vários caches cada um com características diferentes. Cada caso de utilização requer uma configuração específica, para efeito de exemplo configuraremos um cache apenas em memória:  &lt;p&gt;Listagem 2. O arquivo ehcache.xml  &lt;hr&gt;  &lt;blockquote&gt; &lt;p&gt;&amp;lt;ehcache&amp;gt;&lt;br&gt;&amp;lt;cache name=&quot;books&quot;&lt;br&gt;maxBytesOnHeap=&quot;50m&quot;&lt;br&gt;maxBytesOffHeap=&quot;200m&quot;&lt;br&gt;timeToLiveSeconds=&quot;100&quot;&lt;br&gt;overflowToDisk=&quot;false&quot; &amp;gt;&lt;br&gt;&amp;lt;/cache&amp;gt;&lt;br&gt;&amp;lt;/ehcache&amp;gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Com o EHCache configurado, precisamos agora declarar no contexto Spring da sua aplicação as configurações do ehcache-spring-annotations. Veja na &lt;em&gt;listagem 3&lt;/em&gt; como é simples.  &lt;p&gt;listagem 3. Configuração do contexto do Spring, normalmente o applicationContext.xml  &lt;hr&gt;  &lt;blockquote&gt; &lt;p&gt;&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xmlns:ehcache=&quot;http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring&quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; xsi:schemaLocation=&quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; http://www.springframework.org/schema/beans &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd&quot;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;lt;ehcache:annotation-driven /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;lt;bean id=&quot;cacheManager&quot; class=&quot;org.springframework.cache.ehcache.EhCacheManagerFactoryBean&quot;/&amp;gt;&lt;br&gt;...&lt;br&gt;&amp;lt;/beans&amp;gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Existem várias maneiras de configurar os caches no EHCache, existe por exemplo a possibilidade de persistir os objetos do cache em disco, ou então podemos configurar um cache distribuído utilizando o Terracota.  &lt;p&gt;&amp;nbsp; &lt;h2&gt;Utilizando o Cache&lt;/h2&gt; &lt;p&gt;O funcionamento básico do Ehcache Annotations é interceptar a chamada aos métodos anotados, fazer cache do objeto retornado e utilizar os parâmetros, o tipo do retorno e o nome do método para gerar a chave. Os métodos são interceptados utilizando a implementação de AOP do Spring, podemos anotar os métodos diretamente na Interface, ou então nas Classes que as implementam.  &lt;p&gt;Para marcar métodos para terem seu retorno adicionado ao cache, utilizamos a anotação @Cacheable, que recebe um parâmetro cacheName correspondente ao cache declarado no arquivo ehcache.xml da &lt;em&gt;listagem 2&lt;/em&gt;.  &lt;p&gt;Na &lt;em&gt;listagem 4&lt;/em&gt; temos dois métodos anotados com @TriggersRemove, essa anotação indica que&amp;nbsp; quando o método for invocado devemos remover uma, ou todas, das entradas do cache. De outra forma a única maneira dos objetos serem atualizados seria o tempo de expiração configurado no EHCache, o que quase sempre não é o comportamento esperado. Por exemplo, método updateAll na listagem faz com que todo o cache seja invalidado quando atualizamos uma lista de objetos.  &lt;p&gt;Listagem 4. Uma interface anotada com @Cacheable  &lt;hr&gt;  &lt;blockquote&gt; &lt;p&gt;import com.googlecode.ehcache.annotations.Cacheable;&lt;br&gt;import com.googlecode.ehcache.annotations.TriggersRemove;&lt;br&gt;import com.googlecode.ehcache.annotations.PartialCacheKey;&lt;br&gt;public interface BookManager {&lt;br&gt;&amp;nbsp;&amp;nbsp; @Cacheable(cacheName=&quot;books&quot;,&lt;br&gt;keyGenerator = @KeyGenerator (&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name = &quot;HashCodeCacheKeyGenerator&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; properties = @Property( name=&quot;includeMethod&quot;, value=&quot;false&quot; )&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;&amp;nbsp;&amp;nbsp; public Book load(long bookId);&lt;br&gt;@TriggersRemove(cacheName=&quot;books&quot;,&lt;br&gt;keyGenerator = @KeyGenerator (&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name = &quot;HashCodeCacheKeyGenerator&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; properties = @Property( name=&quot;includeMethod&quot;, value=&quot;false&quot; )&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;public void delete(long bookId);&lt;br&gt;&amp;nbsp;&amp;nbsp; @TriggersRemove(cacheName=&quot;books&quot;,&lt;br&gt;keyGenerator = @KeyGenerator (&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name = &quot;HashCodeCacheKeyGenerator&quot;,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; properties = @Property( name=&quot;includeMethod&quot;, value=&quot;false&quot; )&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;&amp;nbsp;&amp;nbsp; public void update( @PartialCacheKey long bookId, Book book);&lt;br&gt;&amp;nbsp;&amp;nbsp; @TriggersRemove(cacheName=&quot;books&quot;, removeAll=true)&lt;br&gt;&amp;nbsp;&amp;nbsp; public void updateAll(List&amp;lt;Book&amp;gt; book);&lt;br&gt;}&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Ambas anotações, @Cacheable e @TriggersRemove, podem receber como parâmetro uma terceira anotação @KeyGenerator. Isso configura a estratégia de geração das chaves do cache, e é importante por um motivo: fazer @Cacheable e @TriggersRemove trabalharem em conjunto.  &lt;p&gt;Como por padrão a geração das chaves do cache leva em conta o nome e o tipo de retorno do método. Os métodos load e delete da listagem 4 acabam gerando chaves diferentes, mesmo possuindo a mesma assinatura. O comportamento desejado nesse caso é que quando o método delete for chamado ele utilize o parâmetro bookId para gerar a chave do cache, dessa forma referenciando o mesmo objeto. Assim os objetos inseridos no cache por load serão invalidados toda vez que houver uma chamada a delete.  &lt;p&gt;Notem a anotação @Properties que define includeMethod como false. É isso que faz as chaves geradas considerarem apenas os parâmetros passados. Dessa forma as chaves geradas pela invocação de load e delete serão iguais para os mesmos valores passados.  &lt;p&gt;Finalmente temos @PartialCacheKey, que permite que apenas alguns parâmetros da assinatura de um método sejam utilizados na criação da chave do cache. No caso do método update no exemplo anotamos o parâmetro bookId para que as chaves geradas sejam as mesmas de load e delete. Assim quando chamado, ele irá invalidar a entrada correspondente no cache, e da próxima vez que recuperarmos um objeto utilizando o método load ele irá pular o cache, e buscar o objeto atualizado.  &lt;p&gt;&amp;nbsp; &lt;h2&gt;Alguns cuidados&lt;/h2&gt; &lt;blockquote&gt; &lt;p&gt;“A otimização prematura é a raiz de todos os males”  &lt;p&gt;&lt;em&gt;- Donald Knuth, Computer Programming as an Art&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;A pesar de ser um recurso muito valioso para resolver problemas de performance, a utilização do cache deve ser estudada de maneira cuidadosa. No mundo ideal sua aplicação deveria funcionar a contento sem precisar recorrer a nenhum tipo de cache, portanto comece o projeto com esse objetivo. Não espere que utilização de caches seja uma bala-de-prata que irá resolver todos os seus problemas. Muitas vezes o cache só vai mascarar o problema, como uma consulta mal escrita no banco de dados, ou um problema de rede que torna a chamada a um WebService muito lenta.  &lt;p&gt;Portanto, na maioria dos casos, o cache deve ser a última coisa a ser implementada no projeto,&amp;nbsp; quando tudo mais já funciona, e outras soluções de otimização foram aplicadas.  &lt;p&gt;Caso planeje utilizar cache em disco, ou cache distribuído, certifique-se de que os objetos colocados em cache implementem a interface Serializable. Caso contrário eles serão descartados, e uma mensagem de alerta será enviada para o log. Outra recomendação é implementar métodos equals e hashCode para suas classes.  &lt;p&gt;Se você opera num ambiente distribuido tenha em mente que por padrão o cache é local, e que isso vai fazer que as informações a respeito de um mesmo recurso possa variar nos diversos caches de cada uma das instâncias da sua aplicação.  &lt;p&gt;&amp;nbsp; &lt;h2&gt;Nada vem de graça: o custo do cache&lt;/h2&gt; &lt;p&gt;Os caches aceleram a execução e o acesso aos recursos utilizados por sua aplicação, mas o custo disso é memória. Quanto mais informações no cache, mas memória será utilizada.  &lt;p&gt;A memória disponível para sua aplicação é limitada pelo parâmetro -Xmx da JVM, que configura o máximo de HEAP que poderá ser alocado. Quando utilizamos uma JVM 64bit esse limite é alto o suficiente para que em termos práticos você possa alocar toda memória disponível, ou quase toda, para sua aplicação. Mas no caso de uma JVM 32bit o limite máximo é de 2GB.  &lt;p&gt;Então ao configurar seus caches, tenha em mente esses limites.  &lt;p&gt;Mesmo que memória não seja um problema, definir um cache gigantesco pode não ser uma boa ideia. O importante aqui não é saber quantos objetos colocar em cache, mas sim saber quais. Informações que são alteradas muito pouco, ou nunca, e são lidas várias vezes são os candidatos ideais para irem para o cache, ao contrário de informações que são alteradas constantemente.  &lt;p&gt;Além disso tudo, a má utilização do cache pode ter um impacto negativo na performance da sua aplicação. Conforme o uso de memória aumenta, também aumenta o tempo gasto pelo Garbage Collector da JVM, e quando a quantidade de memória alocada chega aos Gigabytes as interrupções feitas para GC começam a ser perceptíveis.  &lt;p&gt;Por isso, como toda otimização o uso de cache requer planejamento e um bom entendimento do problema a ser resolvido.  &lt;p&gt;&amp;nbsp; &lt;h2&gt;Conclusão&lt;/h2&gt; &lt;p&gt;O EHCache Spring Annotations é uma solução que se encaixa bem tanto para novos projetos, quanto para projetos já existentes que utilizem o SpringFramework. A necessidade de se adaptar o código é mínima, quando necessária.  &lt;p&gt;Isso o torna uma adição valiosa ao conjunto de ferramentas a sua disposição na hora em que for necessário tirar aquele “pouquinho a mais” da sua aplicação, seja para melhorar sua performance ou seja para escalar a aplicação a um número maior de usuários.  &lt;p&gt;&amp;nbsp; &lt;h2&gt;Links&lt;/h2&gt; &lt;p&gt;&lt;a href=&quot;http://code.google.com/p/ehcache-spring-annotation&quot;&gt;http://code.google.com/p/ehcache-spring-annotation&lt;/a&gt; - EHCache Spring Annotations&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://ehcache.org&quot;&gt;http://ehcache.org&lt;/a&gt; - EHCache&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://springsource.org&quot;&gt;http://springsource.org&lt;/a&gt; - SpringFramework&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;http://terracotta.org&quot;&gt;http://terracotta.org&lt;/a&gt; - Terracotta, desenvolvedores do EHCache.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/5842774896232833755/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/09/ehcache-com-anotacoes-no-spring.html#comment-form' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/5842774896232833755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/5842774896232833755'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/09/ehcache-com-anotacoes-no-spring.html' title='EHCache com anotações no Spring'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-4383916569974212234</id><published>2011-05-31T09:09:00.001-03:00</published><updated>2011-05-31T09:09:11.660-03:00</updated><title type='text'>Cada projeto tem seu próprio dialeto</title><content type='html'>&lt;div&gt;&lt;p&gt;Isso &amp;#233; uma coisa que eu percebo em todos os projetos em que participei, e onde uma equipe convive durante algum tempo. Depois de um tempo os conceitos, processos, classes, m&amp;#233;todos e interfaces do sistema se entranham de tal forma na conversa do dia-a-dia que um dialeto particular &amp;#224;quele projeto acaba surgindo.&lt;/p&gt;
&lt;p&gt;&amp;#201; nessa hora que d&amp;#225; realmente pra ver quais s&amp;#227;o as entidades &quot;fortes&quot;, aquelas que dominam a conversa. Eu acho que nessa hora tamb&amp;#233;m conseguimos perceber se a modelagem do sistema consegue refletir a realidade do problema que est&amp;#225; sendo resolvido. Se o &quot;dialeto&quot; consegue ser utilizado entre pessoas de &amp;#225;reas diferentes, do programador, passando pelo designer at&amp;#233; o cliente ou o cara de vendas isso &amp;#233; um bom indicador que a modelagem capturou, mesmo que num n&amp;#237;vel mais alto, a ess&amp;#234;ncia do problema.&lt;/p&gt;
&lt;p&gt;Ser&amp;#225; que existe alguma t&amp;#233;cnica de modelagem que se preocupe com isso? Em criar antes de mais nada uma linguagem pela qual diversas pessoas consigam entender e discutir determinado problema, ou ser&amp;#225; que isso &amp;#233; apenas um produto natural do processo de desenvolvimento?&lt;/p&gt;
&lt;p&gt;N&amp;#227;o sei, mas &amp;#233; o que eu vou tentar fazer daqui por diante. Antes de mais nada ter certeza que todos est&amp;#227;o falando a mesma l&amp;#237;ngua, e a respeito da mesma coisa... E acho que isso vale pra outras coisas al&amp;#233;m do desenvolvimento de software.&lt;/p&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/4383916569974212234/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/05/cada-projeto-tem-seu-proprio-dialeto.html#comment-form' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/4383916569974212234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/4383916569974212234'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/05/cada-projeto-tem-seu-proprio-dialeto.html' title='Cada projeto tem seu próprio dialeto'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-1888791647195044100</id><published>2011-05-04T12:04:00.001-03:00</published><updated>2011-05-04T12:12:09.356-03:00</updated><title type='text'>Por que existe uma classe Void em java?</title><content type='html'>&lt;div&gt;Resumindo o artigo, serve basicamente nos casos onde você está tentando determinar o tipo de retorno de um método por reflexão, e então é preciso representar a keyword void como uma classe de algum jeito.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;a href=&quot;http://java.dzone.com/articles/why-does-void-class-exist-jdk?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+javalobby%2Ffrontpage+%28Javalobby+%2F+Java+Zone%29&quot;&gt;Why does Void class exist in JDK | Javalobby&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/1888791647195044100/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/05/por-que-existe-uma-classe-void-em-java.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/1888791647195044100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/1888791647195044100'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/05/por-que-existe-uma-classe-void-em-java.html' title='Por que existe uma classe Void em java?'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-6386422843393030914</id><published>2011-04-25T14:11:00.001-03:00</published><updated>2011-04-25T14:13:11.704-03:00</updated><title type='text'>Xoom a venda</title><content type='html'>&lt;div&gt;&lt;p&gt;Encontrei esse numa loja da Vivo, 2K tendo que contratar plano de dados! Por isso que o iPad vende tanto...&lt;/p&gt;
&lt;br/&gt;&lt;img src=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwaaje26dN1uNcAyT9hHBPs23dK2GtGINSHTu42UlSZjhcUORQJ40w_VT3TWYfrLLhvEOr8R9oaAQVmtORrZn_ISow4v1pwTenJ3pmh83X08PwJFn-oqCLuIspoT6pGZ81IAP6yKev-Mlg/&#39; /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/6386422843393030914/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/04/xoom-venda.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/6386422843393030914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/6386422843393030914'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/04/xoom-venda.html' title='Xoom a venda'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwaaje26dN1uNcAyT9hHBPs23dK2GtGINSHTu42UlSZjhcUORQJ40w_VT3TWYfrLLhvEOr8R9oaAQVmtORrZn_ISow4v1pwTenJ3pmh83X08PwJFn-oqCLuIspoT6pGZ81IAP6yKev-Mlg/s72-c" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>Botafogo Praia Shopping, Praia de Botafogo, 400 - Rio de Janeiro - RJ, 22250-040, Brazil</georss:featurename><georss:point>-22.947609 -43.183217</georss:point></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-8768986253274091893</id><published>2011-04-20T20:46:00.000-03:00</published><updated>2011-04-20T20:46:39.415-03:00</updated><title type='text'>Chegou a hora novamente...</title><content type='html'>&lt;div&gt;de experimentar o NetBeans! Todo relase eu baixo, instalo, e testo alguns projetos nele pra ver se a grama é realmente mais verde &quot;do outro lado da cerca&quot;. E toda vez eu volto pro Eclipse.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Alguns destaques:&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;- Suporte ao draft do Java 7&lt;/div&gt;&lt;div&gt;- Maven 3&lt;/div&gt;&lt;div&gt;- Maior integração com o Weblogic&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;a href=&quot;http://netbeans.org/community/news/show/1519.html&quot;&gt;NetBeans Community News&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/8768986253274091893/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/04/chegou-hora-novamente.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/8768986253274091893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/8768986253274091893'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/04/chegou-hora-novamente.html' title='Chegou a hora novamente...'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-7130429244329897284</id><published>2011-04-19T18:50:00.000-03:00</published><updated>2011-04-19T18:50:46.987-03:00</updated><title type='text'>Install Adobe AIR on 64-bit Ubuntu 10.10</title><content type='html'>&lt;div&gt;Grabbed this from the official Flash Patform Blog, and it&#39;s working nicely as far as I can tell. Allowed me to install the Yammer client on my Kubuntu 10.10 64bit desktop.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;a href=&quot;http://blogs.adobe.com/flashplatform/2010/10/install-adobe-air-on-64-bit-ubuntu-10-10.html&quot;&gt;Install Adobe AIR on 64-bit Ubuntu 10.10 (Adobe Flash Platform Blog)&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/7130429244329897284/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/04/install-adobe-air-on-64-bit-ubuntu-1010.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/7130429244329897284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/7130429244329897284'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/04/install-adobe-air-on-64-bit-ubuntu-1010.html' title='Install Adobe AIR on 64-bit Ubuntu 10.10'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-1016334673116931926</id><published>2011-04-18T22:37:00.001-03:00</published><updated>2011-04-18T22:37:38.621-03:00</updated><title type='text'>On the go</title><content type='html'>&lt;div&gt;&lt;p&gt;Instalei o app do blogger pra android, vamos ver se agora eu consigo escrever aquelas ideias que acabam se perdendo no caminho pro trabalho, ou no meio da madrugada. N&amp;#227;o sei se rola a mesma coisa com voc&amp;#234;s, mas eu sempre acabo escrevendo bem menos do que gostaria... ou do que acho que vou escrever.&lt;/p&gt;
&lt;p&gt;Ali&amp;#225;s isso &amp;#233; uma das coisas que me deixa meio puto com o twitter... Quando o espa&amp;#231;o que tem l&amp;#225; acaba e voc&amp;#234; ainda tem aquela uma ou duas palavrinhas a acrescentar. Eu gosto de trabalhar um pouco as coisas que vou escrever, e o twitter &amp;#233; meio brochante nisso.&lt;/p&gt;
&lt;p&gt;Tamb&amp;#233;m com a quantidade de coisas e pessoas por l&amp;#225; n&amp;#227;o rola mesmo entupir os posts de texto, por que ficaria impratic&amp;#225;vel separar e ler o que aparece de interessante.&lt;/p&gt;
&lt;p&gt;Viram? Acabei entupindo isso aqui de texto, e era s&amp;#243; pra falar do app do Blogger...&lt;/p&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/1016334673116931926/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/04/on-go.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/1016334673116931926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/1016334673116931926'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/04/on-go.html' title='On the go'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-9143964611593475315</id><published>2011-02-09T08:33:00.001-02:00</published><updated>2011-02-09T08:33:20.940-02:00</updated><title type='text'>O que eu quero de Natal : Nokia + Android</title><content type='html'>&lt;div class=&#39;posterous_autopost&#39;&gt;A Nokia está perdida num mato sem cachorro, por anos dominou o mercado de celulares high-end com um hardware impecável e um SO estável e hiper otimizado... Só que veio o iPhone e mudou as regras do jogo.&lt;p&gt;De repente ter o melhor hardware, com a maior quantidade de features não era mais suficientes. Diabos, o iPhone foi lançado sem ter metade das features do n95, e ainda assim foi o produto da década! Depois vieram os primeiros Android, que eram meio esquizitos mas que num período de 2 anos deixaram a Nokia pra trás e estão se equiparando com o iOS em termos de usabilidade.&lt;/p&gt;&lt;p&gt;E, pasmem, até a Microsoft conseguiu se organizar e tirar da manga um SO moderno das cinzas do WinMobile 6... que arda no inferno por toda eternidade.&lt;/p&gt;&lt;p&gt;Já ouvi dizer que o problema é que na Nokia o software sempre ficou em segundo plano, e que o desenvolvimento era todo feito em função do hardware. Claramente a Apple mostrou que com uma grande tela touchscreen e o software certo o hardware pode ficar em segundo plano.&lt;/p&gt;&lt;p&gt;Se é assim, entāo no meio de tantos fabricantes lançando celulares com Android, um que poderia se destacar apenas pelo hardware é a Nokia. ( e não por estragar o OS com skins e customizaçoes meia boca. Sim Motoblur, estou olhando pra você )&lt;/p&gt;&lt;p&gt;A combinação Nokia + Android Vanilla + Atualizações frequentes seria matadora!&lt;/p&gt;&lt;p&gt;Bom, não custa sonhar...&lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/9143964611593475315/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/02/o-que-eu-quero-de-natal-nokia-android.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/9143964611593475315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/9143964611593475315'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/02/o-que-eu-quero-de-natal-nokia-android.html' title='O que eu quero de Natal : Nokia + Android'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-835232024351004946</id><published>2011-02-08T19:13:00.001-02:00</published><updated>2011-02-08T19:13:18.445-02:00</updated><title type='text'>Uruguaiana</title><content type='html'>&lt;div class=&#39;posterous_autopost&#39;&gt;Parece que estão querendo acabar mesmo com o camelodromo da Uruguaiana. Desconfio que exista toda sorte de interesses por detrás disso, um ou outro até legítmo... como sanear toda aquela área pra revitalizar o Centro.&lt;p&gt;O foda é que se conseguirem isso vai gerar um problema ainda maior, que é pra onde vai aquela massa de comerciantes? Caso substituam com um shopping center, algo que falta no Centro, provavelmente alguns vão conseguir se estabelecer nele... Mas e os outros? Periga aumentar ainda mais a quantidade de ambulantes que entopem ruas e calçadas, e contribuem pra o inferno que é caminhar por lá.&lt;/p&gt;&lt;p&gt;Se removerem o camelodromo a única certeza que eu tenho é que alguns poucos vão se dar muito bem enquanto a maioria sofre com as consequências.&lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/835232024351004946/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/02/uruguaiana.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/835232024351004946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/835232024351004946'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/02/uruguaiana.html' title='Uruguaiana'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-734789565097398293</id><published>2011-02-06T18:43:00.001-02:00</published><updated>2011-02-07T11:02:00.061-02:00</updated><title type='text'>Desenvolvendo pra iOS : Objective-C</title><content type='html'>&lt;div xmlns=&#39;http://www.w3.org/1999/xhtml&#39;&gt;&lt;p&gt;Vou contar a experiência que eu tive desenvolvendo o App de duas lojas Online (  não posso citar nomes ) pra iOS. Quero tirar isso da minha cabeça e colocar escrito, pra depois poder fazer o mesmo com a experiência que eu tive desenvolvendo pra Android.&lt;/p&gt;&lt;h2&gt;Uma história em capítulos&lt;/h2&gt;&lt;p&gt;O primeiro App passou por duas iterações, uma primeira versão que não era muito mais que uma casquinha ao redor de um browser, e uma segunda versão com muito mais telas nativas mesmo. Essa foi a fase do deslumbramento, quando tudo ainda tinha aquele cheirinho de novo e eu ainda estava aprendendo a linguagem e os meandros do SDK.&lt;/p&gt;&lt;p&gt;Depois o projeto ficou meio de lado, voltei pra meus afazeres normais, e tome-lhe Java nas idéias. Apareceu a oportunidade de fazer uma versão Android, que eu também fiz, e depois disso já tinha até passado meu MacBook pra minha esposa, comprado um Dell e esquecido das minhas aventuras no iOS.&lt;/p&gt;&lt;p&gt;Foi quando pintou o segundo App pra fazer, e eu tive que voltar pro Mac e pro iOS. O que o tempo não faz, depois daquela sensação de novo ter passado é que dá pra perceber realmente o que a plataforma tem de bom e ruim, principalmente depois de ter feito uma aplicação pra Android, que é funcionalmente igual a da versão iOS.&lt;/p&gt;&lt;p&gt;Então, como a história é comprida vou contar aos pouquinhos começando pela linguagem utilizada no SDK do iOS, o Objective-C. Vão ser só minhas impressões, não espere encontrar aqui um tutorial completo da linguagem.&lt;/p&gt;&lt;h2&gt;Objective-C&lt;/h2&gt;&lt;p&gt;Antes de falar o que eu acho do Objective-C, acho melhor explicar um pouco da orígem e listar as características dela. Assim fica mais fácil de vocês entenderem o que ela tem, ou não, de legal.&lt;/p&gt;&lt;p&gt;Ele é uma extensão do C, isto é, qualquer programa feito em C vai compilar num compilador ObjC.&lt;/p&gt;&lt;p&gt;O SMALLTALK foi a fonte de inspiração para implementação OO dele. Então imagino que a sintaxe pareça absurdamente alienígena pra quem está acostumado com C++ ou Java.&lt;/p&gt;&lt;p&gt;Uma das heranças do SMALLTALK é o fato de você não chamar métodos, mas sim enviar mensagens. Na prática isso significa que todas as associações entre métodos e classes são feitas em runtime, ao invés de em tempo de compilação como em C++ e Java. Como efeito você pode enviar mensagens a objetos mesmo que eles não saibam como responder a elas.&lt;/p&gt;&lt;p&gt;Outra coisa bem diferente é que você pode enviar mensagens para objetos nulos sem que isso detone um erro, como o NPE do Java por exemplo. É uma coisa que pode te deixar coçando a cabeça imaginando por quê determinada parte da aplicação não funciona como esperado.&lt;/p&gt;&lt;p&gt;É uma linguagem dinamicamente tipada, pelo menos no que diz respeito aos ponteiros pra objetos. Existe o tipo especial &quot;id&quot; pra ser associado a objetos de tipos desconhecidos.&lt;/p&gt;&lt;p&gt;Outra é que como o Java, o ObjC permite reflexão nos seus objetos. Isto é, você consegue a partir de uma referência a um objeto consultar informações a respeito da classe, como o nome de métodos e seus parâmetros por exemplo.&lt;/p&gt;&lt;p&gt;A gerência de memória é via contagem de referência, mas isso não é feito automaticamente, ou seja, ObjC não tem Garbage Collection. Lembrar de incrementar e decrementar manualmente as referências aos seus objetos é algo bem trabalhoso, que pode levar a alguns bugs bem chatos de encontrar durante o desenvolvimento. Isso mesmo, você vai estar jogando ponteiros de um lado para outro como no bom e velho C.&lt;/p&gt;&lt;p&gt;Como C++ a interface das classes é declarada em um arquivo, e a implementação em outro. O que leva a você ter que repetir diversas vezes a mesma declaração pra métodos e variáveis.&lt;/p&gt;&lt;p&gt;E finalmente a sintaxe, que não é parecida com nenhuma linguagem OO criada nos últimos 20 anos... Minha mente ainda leva um tempo até sair do &quot;modo Java&quot; para o &quot;modo ObjC&quot;. Sério, ObjC pode ter o C como ancestral comum da maioria das linguagens utilizadas hoje, mas é como você comparar mamíferos placentarios com os monotremos, tecnicamente são dois grupos de mamíferos, mas as diferenças... Objective-C é o ornitorrinco das linguagens de programação.&lt;/p&gt;&lt;p&gt;Isso é a declaração da interface de uma classe:&lt;/p&gt;&lt;pre&gt;

@interface Application : SomeSuperclass {
    OtherClass* variable;
    BOOL aboolean;
}

@property (nonatomic,retain) OtherClass* variable;

+ classMethod;
+ classMethodWith:( id ) referenceParam and:(BOOL)booleanParam;

- (id) instanceMethod;
- (OtherClass*) instanceMethodReceiving:( int ) anIntparam and:( NSString* )aStringParam;

@end

&lt;/pre&gt;&lt;p&gt;E abaixo segue a parte da implementação:&lt;/p&gt;&lt;pre&gt;

@implementation Application

@synthetize variable; //Isso gera &quot;getters e setters&quot;

-( id ) instanceMethod{
  
  id localvar = [[SomeClass alloc] init];
  
  [localvar somemethod: @&quot;with string param value&quot;];
  
}

@end

&lt;/pre&gt;&lt;p&gt;A Wikipedia tem uma artigo a respeito do ObjC que trata do assunto a exaustão : http://en.wikipedia.org/wiki/Objective-c &lt;/p&gt;&lt;h2&gt;Veredito&lt;/h2&gt;&lt;p&gt;Na minha humilde opinião o Objective-C é o ponto mais fraco de todo o SDK do iOS. A pesar de ser possível aplicar todos os conceitos e padrões de orientação a objetos que você possa conhecer, no final das contas você ainda vai estar lidando com uma sintaxe tenebrosa e gerenciando memória na unha.&lt;/p&gt;&lt;p&gt;Existe uma piada circulando na internet que o Objective-C foi criado para combater o princípio DRY (Don&#39;t Repeat Yourself), contra-atacando com o WET: Write Everything Twice (or trice). Sério mesmo, em pleno século XXI ainda estamos separando a interface da implementação? Fora isso, declarar a mesma variável 3 vezes espalhadas em 2 arquivos diferentes? Isso é sério mesmo?&lt;/p&gt;&lt;p&gt;Existe um papo de que a Apple está investindo no Ruby para substituir o Objective-C. Isso já é realidade pra aplicações do OSX, e quanto mais cedo isso acontecer no iOS melhor.&lt;/p&gt;&lt;p&gt;&lt;img height=&#39;1&#39; width=&#39;1&#39; src=&#39;https://blogger.googleusercontent.com/tracker/4832956066770863941-734789565097398293?l=victorhogemann.blogspot.com&#39;/&gt;&lt;/p&gt;&lt;p&gt;&lt;img height=&#39;1&#39; width=&#39;1&#39; src=&#39;https://blogger.googleusercontent.com/tracker/4832956066770863941-734789565097398293?l=victorhogemann.blogspot.com&#39;/&gt;&lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/734789565097398293/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/02/desenvolvendo-pra-ios-objective-c.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/734789565097398293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/734789565097398293'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/02/desenvolvendo-pra-ios-objective-c.html' title='Desenvolvendo pra iOS : Objective-C'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4832956066770863941.post-7625201687263041137</id><published>2011-01-18T10:03:00.001-02:00</published><updated>2011-01-18T10:03:52.747-02:00</updated><title type='text'>iOS vs Android</title><content type='html'>&lt;div xmlns=&#39;http://www.w3.org/1999/xhtml&#39;&gt;&lt;p&gt;Minha breve opinião a respeito de desenvolver pra iOS/iPhone e pra Android.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;iOS é um Trem Bala, você pode chegar a onde precisa muito fácil, e muito rapidamente. Infelizmente você fica limitado ao que a Apple planejou, qualquer desvio do caminho e você está por conta própria.&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;Android é uma Land-Rover, pode não ser tão confortável ou rápida quanto um trem-bala... mas uma vez que você pegue a manha vai te levar onde você quizer.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://victorhogemann.blogspot.com/feeds/7625201687263041137/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://victorhogemann.blogspot.com/2011/01/ios-vs-android.html#comment-form' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/7625201687263041137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4832956066770863941/posts/default/7625201687263041137'/><link rel='alternate' type='text/html' href='http://victorhogemann.blogspot.com/2011/01/ios-vs-android.html' title='iOS vs Android'/><author><name>Victor Hogemann</name><uri>http://www.blogger.com/profile/10776588527172796582</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>