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

<channel>
	<title>CØdeZØne! &#187; exceções</title>
	<atom:link href="http://leandrosilva.com.br/category/excecoes/feed/" rel="self" type="application/rss+xml" />
	<link>http://leandrosilva.com.br</link>
	<description>Coisas sobre desenvolvimento de software</description>
	<lastBuildDate>Sat, 21 Apr 2012 17:14:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Message-Driven Beans e Transações</title>
		<link>http://leandrosilva.com.br/2009/02/22/message-driven-beans-e-transacoes/</link>
		<comments>http://leandrosilva.com.br/2009/02/22/message-driven-beans-e-transacoes/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 05:50:45 +0000</pubDate>
		<dc:creator>Leandro Silva</dc:creator>
				<category><![CDATA[arquitetura]]></category>
		<category><![CDATA[ejb3]]></category>
		<category><![CDATA[exceções]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jms]]></category>
		<category><![CDATA[mom]]></category>
		<category><![CDATA[transação]]></category>

		<guid isPermaLink="false">http://leandrosilva.com.br/?p=184</guid>
		<description><![CDATA[Sexta-feira passada, postei  em meu twitter que estou tocando um projeto que envolve MOM. Hammm&#8230; JMS, para ser mais específico&#8230; rsrsrs&#8230;. Bem, o fato é que este projeto acabou me motivando a escrever este post sobre o assunto transação e EJB3 Message-Driven Beans (MDB),  apenas para fazer alguns lembretes e dar algumas dicas, já que [...]]]></description>
			<content:encoded><![CDATA[<p>Sexta-feira passada, <a href="http://twitter.com/codezone/status/1231363269" target="_blank">postei  em meu twitter</a> que estou tocando um projeto que envolve <a href="http://pt.wikipedia.org/wiki/MOM" target="_blank">MOM</a>. Hammm&#8230; <a href="http://pt.wikipedia.org/wiki/JMS" target="_blank">JMS</a>, para ser mais específico&#8230; rsrsrs&#8230;. Bem, o fato é que este projeto acabou me motivando a escrever este post sobre o assunto <a href="http://pt.wikipedia.org/wiki/Transação_atômica" target="_blank">transação</a> e <a href="http://java.sun.com/products/ejb/" target="_blank">EJB3</a> <a href="http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/EJBConcepts5.html" target="_blank">Message-Driven Beans</a> (MDB),  apenas para fazer alguns lembretes e dar algumas dicas, já que este é um assunto fundamentalmente importante. Vamu que vamu então&#8230;</p>
<p>A <strong>primeira coisa</strong> importante a saber é que <strong>transações não são propagadas do produtor de mensagens JMS para o MDB que as consome</strong>, independentemente destes trabalharem com <a href="http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Transaction3.html" target="_blank">CMT</a> ou <a href="http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Transaction4.html" target="_blank">BMT</a>. Isso se dá pela própria natureza assíncrona de um sistema baseado em MOM, uma vez que uma mensagem pode levar horas para ser consumida, se assim fizer sentido ao sistema. Assim sendo, uma transação de um MDB está limitada ao escopo do método <a href="http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/MDB4.html#70210" target="_blank"><strong>onMessage</strong></a>, que recebe e trata as mensagens.</p>
<p>A <strong>segunda coisa</strong> importante a saber é que <strong>quando o MDB faz o seu próprio gerenciamento de sua transação, a mensagem consumida não é parte transação.</strong> Ao passo que, se a transação do MDB for gerenciada pelo contêiner EJB, sim, a mensagem é parte da transação.</p>
<p>Sabendo essas duas coisas, somos levados a uma questão: <strong>O que acontece entãos se a transação falhar?</strong> Bem, está é a <strong>terceira coisa</strong> importante que precisamos saber. Sempre que o método <strong>onMessage</strong> completa sua execução sem erros, o contêiner EJB notifica ao provedor JMS <em>reconhecendo o recebimento da mensagem.</em> No entanto, se o correr uma <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/RuntimeException.html" target="_blank">RuntimeException</a> durante a sua execução, o provedor JMS não receberá esta notificação de reconhecimento e, muito provavelmente, disponibilizará a mensagem para ser novamente consumida pelo MDB. Isso poderia causar um problema sério de <em>loop</em> infinito, em caso de <em>poison messages</em>, mas felizmente há antidoto para isso: Configurar o número máximo de tentativas de entrega de mensagens. Uff!!!</p>
<p><strong>Como lidar então com exceções, rollback e reentrega de mensagens?</strong></p>
<p>Há momentos em que a reentrega de mensagens é fundamental; e há momentos que não. Se ocorrer uma exceção de negócio, por exemplo, você não vai querer que a mensagem seja entregue novamente. Mas, se ocorrer um exceção por indisponibilidade de uma recurso (banco de dados, web service, etc), seria fundamental que a mensagem fosse entregue novamente, depois de algum tempo. Com isso em mente, vamos discutir um pouquinho o assunto.</p>
<p><strong>Primeiro de tudo</strong>, não se esqueça que <strong>MDB&#8217;s não retornam exceções ao cliente que produziu a mensagem.</strong> Se a sua lógica de negócio em cima da mensagem produzida pelo cliente prevê uma exceção, pare e pense um pouco a respeito. Se você puder responder a ele com uma outra mensagem que ele (ou outro MDB responsável por notificar clientes) poderá consumir no provedor JMS, ótimo; caso contrario, esqueça, mensagens assíncronas não é uma opção para você.</p>
<p>Seguindo adiante com a solução, você precisa saber como MDB&#8217;s CMT ou BMT se comportam quando o assunto é transação. As diferenças básicas entre esses dois modelos de gerenciamento de transações são as seguintes:</p>
<p>Se seu <strong>MDB está baseado em CMT,</strong> significa que as mensagens que ele consume são parte da transação. Portanto, se a transação sofrer <em>rollback</em>, automaticamente, o consumo da mensagem também será revertido e o provedor JMS deverá tentar entregar a mensagem novamente.</p>
<p>Já, se seu <strong>MDB está baseado em BMT,</strong> significa que se a transação sofrer <em>rollback</em> o consumo da mensagem não será revertido, como acontece automaticamente no caso de CMT, e você poderá manter isso em segredo do provedor JMS, evitando que ele entregue a mensagem novamente. Ou, se fizer sentido ao seu requisito, você poderá notificá-lo do <em>rollback</em> de maneira bem simple e segura, basta lançar uma <a href="http://java.sun.com/javaee/5/docs/api/javax/ejb/EJBException.html" target="_blank">EJBException</a> que é <em>pá/pum.</em></p>
<blockquote><p><strong><em>Um pouco mais sobre Reconhecimento de Mensagem</em></strong></p>
<p>A <a href="http://java.sun.com/javaee/5/docs/api/javax/ejb/ActivationConfigProperty.html" target="_blank">propriedade</a> <strong>acknowlodgeMode</strong>, que determina o modo de reconhecimento da mensagem, pode ser definida como <em>Auto-acknowledge</em> ou <em>Dups-ok-acknowledge</em>. A primeria opção, instrui o contêiner EJB a notificar o reconhecimento da mensagem dentro do contexto da transação, seguindo as regras já citadas; e a segunda, o instrui a fazer isso num outro momento qualquer.</p>
<p>Essa propriedade pode ser ignorada, a menos que você esteja implementando um BMT ou um CMT com <a href="http://java.sun.com/javaee/5/docs/api/javax/ejb/TransactionAttribute.html" target="_blank">atributo de transação</a> definido como <a href="http://java.sun.com/javaee/5/docs/api/javax/ejb/TransactionAttributeType.html#NOT_SUPPORTED" target="_blank"><em>NotSupported</em></a>. Do contrario, o reconhecimento sempre ocontecerá no contexto da transação.</p>
<p>Se quiser saber mais, indico que você <a href="http://www.onjava.com/pub/a/onjava/excerpt/ejb3_ch13/index.html?page=6#28" target="_blank">leia esse material</a>.</p></blockquote>
<p><strong>Resumindo:</strong> Tome cuidado com suas exceções e não deixe que elas explodam sem mais nem menos, sem um tratamento adequado, nem nada, porque elas podem detonar suas transações e ainda causar problemas de negócio, com a reentrega de mensagens. Um bom <em>log</em> também vai muito bem, meu caro! <img src='http://leandrosilva.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Bom, é isso ai&#8230; Espero que te ajude!</p>
<p>E se você ainda não leu esses dois posts: <a href="http://leandrosilva.com.br/2008/08/12/cuidado-com-suas-excecoes/" target="_self">Cuidado com suas exceções</a> e <a href="http://leandrosilva.com.br/2008/08/12/transacionando-ejb3-session-beans/" target="_self">Transacionando EJB3 Session Beans</a>, quando tiver um tempinho, leia. Talvez lhe sejam úteis também.</p>
<p>Até a próxima!</p>
]]></content:encoded>
			<wfw:commentRss>http://leandrosilva.com.br/2009/02/22/message-driven-beans-e-transacoes/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Cuidado com suas exceções!</title>
		<link>http://leandrosilva.com.br/2008/08/12/cuidado-com-suas-excecoes/</link>
		<comments>http://leandrosilva.com.br/2008/08/12/cuidado-com-suas-excecoes/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 14:10:56 +0000</pubDate>
		<dc:creator>Leandro Silva</dc:creator>
				<category><![CDATA[arquitetura]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[ejb3]]></category>
		<category><![CDATA[exceções]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://codezone.wordpress.com/?p=28</guid>
		<description><![CDATA[Um tema bastante trivial, mas não pouco importante, são as sempre presentes Exceções. Outro dia desses me deparei novamente com elas – em um dos projetos que presto consultoria [em arquitetura] – e resolvi escrever este post, como uma pequena &#8220;dica&#8221;, digamos assim, para quem ainda não está totalmente seguro com o tema. Por fim, [...]]]></description>
			<content:encoded><![CDATA[<p>Um tema bastante trivial, mas não pouco importante, são as sempre presentes Exceções. Outro dia desses me deparei novamente com elas – em um dos projetos que presto consultoria [em arquitetura] – e resolvi escrever este post, como uma pequena &#8220;dica&#8221;, digamos assim, para quem ainda não está totalmente seguro com o tema. Por fim, ele também servirá como complemento ao meu post anterior que aborda o tema transações em EJB3 Session Beans.</p>
<p><strong>Conceituando as coisas</strong></p>
<p>Em Java há dois tipos de exceções:</p>
<p>- Checadas (checked),<br />
- E não checadas (unchecked).</p>
<p>As exceções <em>checadas</em> são identificáveis em tempo de desenvolvimento e, obrigatoriamente, devem ser capturadas (try&#8230;catch) e tratadas – seja com uma mensagem &#8220;amigável&#8221; ao usuário, ou com um algoritmo alternativo,  ou seja lá como for. Estas exceções são identificáveis em tempo de desenvolvimento, por isso, são muito uteis na hora de sinalizar que uma &#8220;regra de negócio&#8221; foi violada – também conhecidas como exceção de aplicação – e, portanto, algo deve ser feito.</p>
<p>Alguns exemplos deste tipo de exceção seriam:</p>
<p>- MaioridadeNaoIdentificavelException<br />
- ValorPagamentoMenorTaxaEmbarqueException<br />
- DataReservaInvalidaException</p>
<p>Já as exceções <em>não checadas</em> normalmente não são identificáveis em tempo de desenvolvimento, por isso são conhecidas como exceções de runtime – e não coincidentemente, são filhas de <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/RuntimeException.html" target="_blank">RuntimeException</a>. Estas exceções geralmente (mas não invariavelmente) denotam erros de sistema que não são recuperáveis.</p>
<p>Exemplos destas exceções na própria API do Java são:</p>
<p>- <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/SecurityException.html" target="_blank">SecurityException</a><br />
- <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/NullPointerException.html" target="_blank">NullPointerException</a><br />
- <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/MissingResourceException.html" target="_blank">MissingResourceException</a></p>
<p>E, como uma prática comum, também é bom notar que exceções <em>não checadas</em> não são declaradas na clausura <em>throws</em> dos métodos os quais podem lançá-las.</p>
<p><strong>Tomando decisões</strong></p>
<p>Quando você entende este conceito fica simples saber quando usar uma ou outra, não? Sim. Quer dizer, sim, mas também, não! Mas por que não? Hammm&#8230; Veja só&#8230;</p>
<p><a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/IllegalArgumentException.html" target="_blank">IllegalArgumentException</a> denota que um parâmetro inválido foi passado a um método, correto? Sim, é isto que diz a documentação. Bem, neste caso, imagine que você estivesse escrevendo um método de negócio, e neste método você tivesse que consistir os seus parâmetros. Imaginou? Tá. Agora, o que você faria se um dos parâmetros fosse invalido?</p>
<p>a) Lançaria uma IllegalArgumentException<br />
b) Criaria uma exceção própria [<em>checada</em>] para denotar parâmetros inválidos</p>
<p>Sem pensar muito, você ficaria tentado a optar por <strong>(a)</strong>, certo? Creio que sim. Mas esta não seria uma boa opção, se estes parâmetros forem realmente essenciais para o dado método; e se for possível para o código que executa este método tomar uma “decisão de negócio”, se souber que um ou mais parâmetros são inválidos. Neste caso, o melhor é a opção <strong>(b)</strong>. É preciso ficar atento para escolher a melhor opção em cada situação.</p>
<p><strong>Um pouco sobre exceções em EJB3</strong></p>
<p>Todos os métodos de um <a href="http://java.sun.com/products/ejb/" target="_blank">EJB3</a> <a href="http://en.wikipedia.org/wiki/Session_Beans" target="_blank">Session Bean</a> lançam uma exceção do tipo <a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/ejb/EJBException.html" target="_blank">EJBException</a>, que é <em>não checada</em>, caso algo de errado aconteça. Isto automaticamente desencadeia um processo de <em>rollback</em> na transação atual, e grava um registro de <em>log</em> no <a href="en.wikipedia.org/wiki/Application_server" target="_blank">application server</a> para conhecimento do administrador do sistema.</p>
<p>Como fica então se quisermos lançar nossas próprias exceções? É muito simples, mas é também preciso se ater a um detalhe:</p>
<p>“Se a exceção que você lançar for <em>não checada</em>, ela será automaticamente encapsulada por uma EJBException, o que torna o tratamento desta exceção nada fluente na aplicação cliente, uma vez que não será pego de maneira &#8216;especifica&#8217; pela seu bloco catch. Isto quer dizer que você somente conseguirá capturar uma EJBException, e não uma NaoConseguiEnviarEmailException, por exemplo.”</p>
<p>No caso deste meu cliente, que usa <a href="http://www.oracle.com/technology/products/ias/index.html" target="_blank">Oracle Application Server</a>, a EJBException encapsula uma OracleRemoteException, que por sua vez encapsulada a exceção que de fato foi lançada. Que beleza, né? Beleza nada, uma praga! <em>rsrsrs</em></p>
<p>Então, cuidado! Se você estiver trabalhando com EJB3 e quiser lançar uma exceção <em>não checada</em>, não se esqueça que o cliente de seu EJB não saberá (de forma natural, com um simples try&#8230;catch) que exceção realmente foi lançada.</p>
<p>Aqui permanece então o que foi dito acima:</p>
<p>- Exceção de negócio, prefira que seja <em>checada</em>,<br />
- E de sistema, prefira que seja <em>não checada</em>, caso realmente não possa trata-la.</p>
<p>Talvez agora você esteja se perguntando: Mas e a transação, como fica? Ela será abortada quando uma exceção <em>checada</em> for lançada?</p>
<p>A resposta é&#8230; Não, ela não será abortada. Porque nem sempre uma exceção de negócio requer um <em>rollback </em>de transação. Aliás, também não será registrado qualquer <em>log</em> no application server – porque erros de negócio são irrelevantes a administradores de sistema.</p>
<p>Mas nem tudo esta perdido. EJB3 provê uma anotação para possibilitar que você aborte uma transação caso uma dada exceção <em>checada</em> ocorra.</p>
<p><a href="http://java.sun.com/javaee/5/docs/api/javax/ejb/ApplicationException.html" target="_blank">@javax.ejb.ApplicationException</a> tem um atributo <em>rollback</em> que pode ser definido como <em>true</em> ou <em>false</em>, indicando que a transação deve ser abortada ou não. Assim, basta fazer esta anotação em sua exceção e pronto!</p>
<p>Essa é uma maneira fácil de garantir a <strong>atomicidade</strong> de sua transação, porque caso ocorra alguma exceção de negócio que de fato viole o acordo da transação, automaticamente, a transação será abortada.</p>
<p>Bom, é isso&#8230; Chega de exceções por hoje!</p>
]]></content:encoded>
			<wfw:commentRss>http://leandrosilva.com.br/2008/08/12/cuidado-com-suas-excecoes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

