Ontem Eu, hoje Certified ScrumMaster

Scrum

Essa foi a sensação que tive quando terminei o tão esperado treinamento de CSM (Certified Scrum Master) aqui em Belém, nos dias 14 e 15 de novembro, seguindo a turnê promovido pela Caelum com certificado da ScrumAliance e palestrado pelo Alexandre Magno que diga-se de passagem possui uma visão muito clara e objetiva não somente sobre o assunto mas também as possíveis dificuldades que a maiorias das empresas encontram quando adotam processos ágeis, o treinamento foi muito produtivo e inspirador pelas quantidades de duvidas tiradas devido receio que tinhamos no inicio de tudo. Fiquei muito surpreso e contente pela numero de empresas que participaram do treinamento, isso significa que a região esta atenta a tendências de mercado e disposta a mudanças para melhoria contínua de nossos processos de desenvolvimento de software.

O CSM traz com sigo uma quebra de paradigma e uma nova visão até então difícil no entendimento das muitas, pelos anos de canelada experiência do modelo waterfall, porém, a vontade de mudança é visível, como bem foi colocado pelo Alexandre “precisamos resgatar a nossa imagem diante das empresas, como um setor que entrega os projetos nos prazos” e Scrum parece ser uma das chaves para o sucesso, mas reparem o eu disse “uma das”, sempre temos que levar em consideração varios outros fatores que não impede que afete diretamente no fracasso de um projeto, tudo depende de quão estamos comprometidos com essa nova forma de agir(ágil). Pode levar algum tempo, ser exaustivo e nebuloso, mas niguem disse que era fácil. :)

O que se esperar do desenvolvimento móvel JavaME e o Flash Lite.

Estive envolvido em um projeto esses meses, que se tratava de um modulo que tinha como objetivo final clientes moveis(PDA’s) e integração com ERP. Uma das primeiras coisas que me fez refletir foi qual a implementação utilitazar para o desenvolvimento, pois fazia tempo que não desenvolvia como esse tipo de tecnologia –acho que uns 2 anos atrás. Então busquei saber o que havia de novo, o que tinha facilitado na vida de quem trabalha com esse ramo de desenvolvimento. Nesse período pude ver (não se aprofundar)as novas opções de plataformas estendendo-se no mercado de tecnologia móvel e cada vez mais próximo do desenvolvimento business. Essa tendência de se ter a mobilidade com informações em tempo real, traz com sigo valores significativos na tomada de decisão, e de extrema relevância competitiva.  Só Deus e os desenvolvedores sabe o quanto dá trabalho em implementações desse tipo e quão a recompensa é avassaladora.

Como também não podia deixar de pesquisar o que estava acontecendo entre Java e Flash dentro do foco móvel (desta vez nao estou falando de Flex). Tomei conhecimento projeto de Capuchin, desenvolvido pela Sony Ericsson o mesmo busca a integração entre as duas tecnologias. Não é de hoje que temos aplicações JaveME em diversas dispositivos como celulares e PDA’s, isso ja não acontece com o Flash Lite. Por que não junta-las?

Seus exemplos estão disponíveis no site e mostram como animações flash podem ser usadas como UI para representar dados de uma camada de serviço Java, como empacotar o Flash Lite no MIDlet e mecanismo de transferência de dados. Não tive tempo de testar as APIs do Capuchin, para desenvolver o projeto completamente com esse novo recurso. Mas assim que tiver alguma coisa pronta posto aqui no blog :)

PS: Qual foi minha saída? Utilizar bom o velho JavaME de guerra, dessa vez com CDC/Personal Profile, sobre Windows Móbile 2003, tive a oportunidade de utilizar o SWT/wce J2SE pelo menos foi o único que me deu uma interface rica e produtiva, e com suporte da JVM J9 PPRO11. Pelo tempo e necessidade no decorrer do projeto essa foi uma das poucas saídas que tive.

Campanha: Abrace um desenvolvedor

Abrace um desenvolvedor todos os dias. :)

PS: Onde quer que esteja, nos entendemos sua dor.

Obrigado pelo link Handerson

Criando uma aplicação Flex+Java com BlazeDS (em três minutos)

Faz um tempo que não escrevo por aqui, mas olhando o meu rank de post, percebi que uns dos assuntos mais vistos é do BlazeDS, então decidir escrever um artigo bem focado. Este tutorial tem como objetivo criar um exemplo simples para “conectar” um cliente Flex com um serviço Java utilizando o BlazeDS. No exemplo não vou me prolongar em detalhes, pois temos que seguir o cronograma de três minutos ;)

Para desenvolver o exemplo vamos utilizar as seguintes ferramentas:

Eclipse 3.3.2

Flex Builder 3

Flex 3 SDK

BlazeDS 3.0.0

JBoss4.2.2GA

1-Criação do Serviço Java.

Primeiro vamos criar um projeto que vai rodar no nosso servidor, o back-end Java, crie-o com o nome “ServerBlazeDS” com a seguinte estrutura:

WebContent

|____swf

|____WEB-INF

|______classes

|______flex

|______lib

Desenpacote o zip de download do BlazeDS e extraia o arquivo blazeds.war, va ate o diretório WEB-INF/lib e copie todas os jars e cole no mesmo diretório do seu projeto, faça a mesma coisa com a pasta “flex”, feito isso vamos contruir nossa classe de serviço Java:

public class Service {

private List<Map<String,String>> collection;

public List<Map<String,String>> getCollection(){

System.out.println(“Begin-getCollection()”);

collection = new ArrayList<Map<String,String>>();

Map<String, String> joao = new HashMap<String, String>();

joao.put(“Nome”,“Joao”);

Map<String, String> Zezinho = new HashMap<String, String>();

Zezinho.put(“Nome”,“Zezinho”);

Map<String, String> Mariazinha =new HashMap<String,String>();

Mariazinha.put(“Nome”,“Mariazinha”);

collection.add(joao);

collection.add(Zezinho);

collection.add(Mariazinha);

System.out.println(“end-getCollection()”);

return collection;

}

}

Essa classe implementa um método simples que retorna uma List de Maps, fiz isso, pois é uma maneira simples de implementar um objeto não tipado na hora da deserialização em ActionScript, onde vamos ter a mesma estrutura em um Object. E claro que podemos implementar perfeitamente um VO para a mesma operação.

Seguindo a seqüência, precisamos mapear os nossos serviços como destination, ou seja, fazer com que nossa aplicação possa invocar métodos da nossa classe de serviço distribuída dentro de nosso servidor Java. Dentro da pasta flex abra o arquivo remoting-config.xml e adicione nossa classe Service como destination.

<destination id=“myService”>

<properties>

<source>exmplo.amf.ds.Service</source>

<scope>application</scope>

</properties>

</destination>

Lembre-se do id (no caso ‘myService‘), pois será o nome que sua aplicação flex ira usar para referenciar sua classe remota. Pronto, tudo que precisamos em nosso servidor já foi configurado, agora precisamos criar nosso cliente Flex para acessar nosso serviço.

2-Criação do Flex Client

Agora utilizando o Plug-in do Flex Builder podemos seguir os passos New> Flex Project> digite o nome do projeto como “ClientBlazeDS” e “finish”, por padrão o plug-in já cria uma Application para você com o mesmo nome do projeto, mais ou menos assim.

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute>

</mx:Application>

Tudo que escrevermos tem que esta dentro desta tag ‘Application’ é onde o compilador flex vai considerar como base para gerar nosso swf. Antes de começar a codificar precisamos indicar ao nosso compilador onde ele deve ler nosso arquivo servide-config.xml tambem dentro da pasta ‘flex’, então clique com o botão direito em cima do projeto va em Properties>Flex Compiler>Aditional compiler argumes e adicione:

-context-root ServerBlazeDS -services <DIR_PROJETO>\ ServerBlazeDS \WebContent\WEB-INF\flex\services-config.xml

Recapitulando:

1) Nossa aplicação terá que fazer uma requisição para nosso serviço Java, para isso vamos utilizar um componente chamado RemoteObject que ira fazer nossa chamada assíncrona de nosso método.

2) Mostrar de alguma forma esses dados, vamos utilizar o DataGrid para exibição de listas de objetos.

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute

creationComplete=”init()”>

<mx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.collections.ArrayCollection;

import mx.rpc.events.ResultEvent;

[Bindable]

private var collection:ArrayCollection;

private function init():void{

ROService.getCollection();

}

private function onResult(event:ResultEvent):void{

collection = event.result ? event.result as ArrayCollection : new ArrayCollection();

}

]]>

</mx:Script>

<mx:RemoteObject id=”ROService” destination=”myService” requestTimeout=”1>

<mx:method name=”getCollection” result=”onResult(event)” fault=”{Alert.show(‘error de conexão’)}” />

</mx:RemoteObject>

<mx:Panel width=”384” height=”314” layout=”absolute” verticalCenter=”0” horizontalCenter=”0>

<mx:Form width=”100%” height=”100%>

<mx:DataGrid id=”grd” width=”100%” height=”100%” dataProvider=”{collection}>

</mx:DataGrid>

</mx:Form>

</mx:Panel>

</mx:Application>

3-Empacotando e distribuindo a aplicação:

Vamos criar dentro da pasta swf uma pagina para carregar nosso arquivo *.swf gerado pelo nosso cliente:

<html>

<head>

<meta http-equiv=“Content-Type” content=“text/html; charset=utf-8″ />

<title></title>

<style>

body { margin: 0px; overflow:hidden }

</style>

<script language=“JavaScript” type=“text/javascript”>

</script>

</head>

<body scroll=“no”>

<object classid=“clsid:D27CDB6E-AE6D-11cf-96B8-444553540000″

id=“callcenter” width=“100%” height=“100%”

codebase=“http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab”>

<param name=“movie” value=“http://localhost:8080/ServerBlazeDS/swf/ClientBlazeDS.swf” />

<param name=“quality” value=“high” />

<param name=“bgcolor” value=“#869ca7″ />

<param name=“allowScriptAccess” value=“sameDomain” />

<embed src=ClientBlazeDS.swfquality=“high” bgcolor=“#869ca7″

width=“100%” height=“100%” name=“callcenter” align=“middle”

play=“true”

loop=“false”

quality=“high”

allowScriptAccess=“sameDomain”

type=“application/x-shockwave-flash”

pluginspage=“http://www.adobe.com/go/getflashplayer”>

</embed>

</object>

</body>

</html>

Agora copie o swf gerado no seu projeto flex dentro da pasta ‘bin-debug’ para pasta ‘swf’ do seu projeto servidor, execute o ant de deploy.

<project name=“BlazeDS-ANT” default=“pack-blaze”>

<property name=“deploy.dir” value=“../deploy”/>

<property name=“output.dir” value=“../output”/>

<target name=“create-directories” >

<echo>Creating output Directories …</echo>

<mkdir dir=“${deploy.dir}” />

<mkdir dir=“${output.dir}” />

<mkdir dir=“${output.dir}/blaze” />

<mkdir dir=“${output.dir}/blaze/WEB-INF/classes” />

<mkdir dir=“${output.dir}/blaze/swf” />

<echo>Done.</echo>

</target>

<property name=“sourceBlaze.dir” value=“../../ServerBlazeDS/src/”/>

<target name=“clean” >

<echo>Deleting build temp DIR …</echo>

<delete dir=“${output.dir}/blaze”/>

<mkdir dir=“${output.dir}/blaze”/>

<mkdir dir=“${output.dir}/blaze/WEB-INF/classes”/>

<mkdir dir=“${output.dir}/blaze/WEB-INF/lib”/>

<echo>done.</echo>

</target>

<target name=“build-blaze” depends=“create-directories”>

<echo>Compiling classes …</echo>

<javac destdir=“${output.dir}/blaze/WEB-INF/classes”

encoding=“iso-8859-1″

debug=“on”>

<src path=“${sourceBlaze.dir}”/>

<classpath>

<pathelement path=“${classpath}”/>

<fileset dir=“${sourceBlaze.dir}/../WebContent/WEB-INF/lib”>

<include name=“**/*.jar”/>

</fileset>

</classpath>

</javac>

<echo>Done Compiling.</echo>

<echo>Copying .swf.</echo>

<copy todir=“${output.dir}/blaze”>

<fileset dir=“${sourceBlaze.dir}/../WebContent”>

<include name=“**/*.*”/>

<exclude name=“**/*.svn”/>

</fileset>

</copy>

<echo>Done.</echo>

</target>

<target name=“pack-blaze” depends=“build-blaze”>

<echo>Packing WebAPP on WAR file …</echo>

<jar destfile=“${deploy.dir}/ServerBlazeDS.war” basedir=“${output.dir}/blaze”>

</jar>

<echo>Done.</echo>

</target>

</project>

Pronto, agora é só botar no servidor e testar a aplicação. Abra o browser e digite http://localhost:8080/ServerBlazeDS/swf/main.html, se ocorrer tudo bem a sua aplicação vai aparecer com essa cara.

Agora sim temos nossa aplicação (lindona :) ) , funcionando e acessando nossos objetos Java. Entao fico por aqui espero ter ajudado.

Codigo Fonte:

ClienteBlazeDS

ServerBlazeDS

Curso on-line de Flex + Vídeos

Só repassando, daqui algumas semanas ocorrerá mais uma boa oportunidade para o desenvolvimento Flex, A e-Genial ta promovendo um curso on-line. O curso terá 18 aulas/horas e irá iniciar em Agosto, vamos fazer a matrícula:

Curso On-Line de Flex e Vídeos (streaming)

Você já pode baixar a grade, e ao termino será feito uma aplicação exemplo.

Introspecção Performance: Java x ActionScript3

Bom, hoje vou falar um pouco de um recurso muito importante no desenvolvimento de aplicações, que é o processo pelo qual se pode obter informações sobre a estrutura e comportamento do programa em tempo de execução, de uma maneira estreitamente dependente das características de abstração do código, ou seja, o programa tem a habilidade para “observar” e possivelmente modificar a estrutura e comportamento. Levando em consideração esse conceito vou mostrar como esse pode ser aplicado tanto na linguagem Java como em ActionScript3(AS3).

Em AS3 ultilizada no desenvolvimento Flex, reflexão é referenciada como object introspection (introspecção de Objeto). Existem duas formas de introspecção em AS3: Usando o laço for…in e a API introspecção. Em Java esta atividade é auxiliada pelo pacote java.lang.reflect. É bom deixar bem claro que a API introspecção em ActionScript não é tão avançada como em Java, porem permite você ler métodos, propriedades e invocar métodos de objetos em tempos de execução, tao bem quanto. Bom, chega de conversa e mãos a obra.

Para nosso exemplo vamos definir nossa classe que ira servir como base para fazer nossos testes, precisamos de duas classes uma em Java .class e outra em ActionScript .as:

Vamos por parte, primeiramente aprender como pegar a definição de classe e logo em seguida criar uma instancia da mesma, primeiro em Java:

...
Class classePessoa = Class.forName("Pessoa");
Object instance = classePessoa.newInstance();
...

Muito fácil não? Em ActionScript é mais fácil ainda, com a utilização do método getDefinitionByName() definido em flash.utils, onde contem diversas funções de manipulação de classes e objetos em tempo de execução, podemos criar uma definição de classe.

...
var classePessoa: Class = getDefinitionByName("Pessoa") as Class;
var instance = new classePessoa ();
...

Agora Vamos tentar recuperar a estrutura do Objeto Pessoa em tempo de execução, primeiro em Java:

Class classePessoa = Class.forName("Pessoa");
String str="";
for (Field field : classePessoa.getDeclaredFields()) {
str+="Variaveis: "+
field.getName()+
"=("+field.getType().getSimpleName()+
")"+
"\n";
}
for (Method method : classePessoa.getDeclaredMethods()) {
str+="Metodo: "+
method.getName()+
"=("+method.getReturnType()+
")"+
"\n";
}
System.out.println(str);

Agora o processo em ActionScript, é feito com a utilização do for..in e a função describeType() que vem também no pacote flash.utils, recebe como parâmetro o objeto a ser introspectivo sobre um retorno descrito em XML do tipo do objeto e toda sua estrutura:

var ClassePessoa:Class = getDefinitionByName("Pessoa") as Class;
var classInfo:XML = describeType(classePessoa);
var str:String='';
for each (var v:XML in classInfo..variable) {
str += "Variavel: " + v.@name + "=" + " (" + v.@type + ")\n"; }
for each (var v:XML in classInfo..method) {
str += "Metodo: " + v.@name + "=" + " (" + v.@returnType + ")\n";
}
trace(str);

Abas imprimem o seguinte trace:

Variavel : nome=(String)

Variavel : nacionalidade=(String)

Variavel : idade=(String)

Metodo: falar=(void)

Metodo: ouvir=(void)

Outra coisa muito utilizada quando se utiliza reflexão e invocação de métodos por definição explicita de assinatura e parâmetro, em Java podemos criar um objeto Method a partir do getMethod() passando o nome do método como parâmetro, e em seguida utilizar seu método invoke() , passando o objeto, e parâmetro, no argumento:

...
Class classePessoa = Class.forName("Pessoa");
Method m = classePessoa.getMethod("falar", null);
m.invoke(classePessoa.newInstance(), null);
...

Em ActionScript é um pouco diferente, pois o tipo Object é uma classe dinâmica então não precisamos fazer o hard-code do método para que o metodo seja invocado, basta fazer instanciar com new e invocar explicitamente.

var classePessoa:Class = getDefinitionByName("Pessoa") as Class;
var instance:Object = new classePessoa()
instance["falar"](); //
ou instance.falar(); os dois sao equivalentes

Um outro método muito utilizado na introspecção AS3 é o getClassInfo(), no qual retorna um objeto com nome e propriedades do mesmo e o toString() que retorna uma espécie de “mapa” do Objeto, todos dois da classe ObjetoUtils.

...
var o:Object = ObjectUtil.getClassInfo(Pessoa);
trace(ObjectUtil.toString(o));
...

Bom, espero ter colaborado para um entendimento do que vem a ser introspecção de objetos e como se comporta em cada uma das linguagens, tanto em Java quando em AS3, podendo ser uma técnica poderosa no desenvolvimento de soluções um tanto quanto genéricas.

RIA com Java: BlazeDS e AMF

Ultimamente com o uso de ferramentas como Adobe Flex, Flash CS3 vem crescendo muito o numero de Rich Internet Applications (RIA), aplicações desktop com o Adobe AIR e aqueles que rodam em browser com Flash Player atuando como client-side, que por sua vez tem que de alguma forma se comunicar com um servidor para leitura e manipulação de dados, dados esses que geralmente são transportados via HTTP, mas a diferença em como esses dados são passados pelo protocolo pode comprometer drasticamente a performance, bem como a produtividade no desenvolvimento dos sistemas.

Muitas dessas aplicações utilizam-se de XML-sobre-HTTP para a comunicação cliente-servidor e acabam se dando conta da carga que sistema sofre com a serialização e deserialização dos XMLs que correm de um lado para outro.

O Action Message Format(AMF) se trata de um protocolo binário que pode ser usado sobre o HTTP ao invés do XML, evitando o tempo de parse entre a comunicação com o servidor. Nesse intuito, a Adobe tratou de lanca o tantas vezes renomeado LiveCycle Data Service, que prove as APIs necessárias para o server-side trabalhar com o AMF. Porém, não muito difundido pelos desenvolvedores por ser uma ferramenta liberada apenas para um único servidor(CPU) como demonstração. Em dezembro de 2007 a Adobe anuncio que a especificação AMF seria liberada e uma poção do LiveCycle Data Service seria open-source denominado BlazeDS que incluiria a implementação Java de AMF em servidores de aplicação como: Tomcat, JBoss, WebLogic, WebSphere, etc.

James Ward e Shashank Tiwari publicaram um artigo que explica em detalhes todo esse processo e a criação de um exemplo com back-end Java com o BlazeDS sobre o desenvolvimento Flex para um cliente RIA.

O artigo pode ser encontrado aqui postado na infoQ.

Comunicação entre componentes distribuídos por mensagens assíncronas com MDB

Após um tempo estudando Enterprise JavaBeans (EJB’s) para um projeto em que estava participando, percebi que estava confuso em relação ao conceito do tipo de ambiente(arquitetura) que o Beans de Sessão(Sessions Beans) são utilizados, pois cheguei a seguinte situação; queria que meu cliente acessasse por JNDI serviços registrados em outro servidor remoto e esses me devolviam informações(objetos) de um sistema heterogêneo , sendo que o mesmo estava em uma outra rede de uma filial da empresa, interligadas por uma WAN, ou seja, queria uma interação direta e síncrona entre meus componentes. Mas essa solução não é adequada por uma serie de condições adversas tais como: Link esta fora, servidor remoto parar no meio de uma transação, pico de luz e etc. A não ser que meu cliente espere longos 30min para receber apenas um timeout como resposta de uma conexão falha, nem mesmo quando pode voltar a estabelecer uma nova conexão com esse servidor. Então, como sair dessa situação? Depois de muito queimar a ‘cuca‘, encontramos a resposta na seguinte solução:

Invocar serviços através mensagens assíncronas, monitoradas por um tipo de especial de EJB denominado Message Driven Bean (MDB). Antes de começar explicar, vou explanar alguns conceitos importantes da solução apresentada:

  • MDB: São beans consumidores de JMS dentro do container JEE.
  • Queue: Filas de mensagens onde só vai ser consumida por um único MDB.
  • Producer: Produtor de mensagens para um Provider JMS.
  • Consumer: Recebe as mensagens de uma Queue que esta ‘escutando’.
  • Provider: Ambiente responsável pela organização e entrega de JMS.

O Conceito do funcionamento de uma JMS Application pode ser muito bem ilustrada na figura abaixo:

Isso nos trouxe mais confiança à comunicação entre nossos componentes distribuídos, pois não temos que nos preocupar em “busca coisas” em serviços de um servidor remoto, pois ele se encarrega de enviá-los através de um Producer construído somente para empilhar mensagens em uma Queue, escutada pelo nosso Consumer em um servidor local. O processando das mensagens é forma ordenada e durável, ou seja, somente sai da fila quando for realmente processada na ordem de chegada. Então a disposição de comunicação de nossos componentes ficou da seguinte forma:

A grande sacada foi como um MDB acessa uma Queue remota e fazer com que minhas mensagens sejam consistentes o bastante para garantirem a entrega no meu Consumer. Para isso foi feito algumas configurações no JBoss(no meu caso v.405), primeiramente foi adicionado mais um mbean(Managed Bean) em <$JBOSS_HOME/server/<your-configuration>/deploy/jms/jms-ds.xml, que defini um Provider remoto (que pode ser gerenciado via jmx-console). Lembrando esta alteração é no container em que o MDB esta rodando. Por padrão todos os MDBs acessam o DefaultJMSProvider também declarado no arquivo como Provider.

<mbean code=“org.jboss.jms.jndi.JMSProviderLoader”

name=“jboss.mq:service=JMSProviderLoader,name=RemoteJMSProvider,server=remotehost”>

<attribute name=“ProviderName”>RemoteJMSProvider</attribute>

<attribute name=“ProviderAdapterClass”>org.jboss.jms.jndi.JNDIProviderAdapter</attribute>

<!– The connection factory –>

<attribute name=“FactoryRef”>UIL2XAConnectionFactory</attribute>

<!– The queue connection factory –>

<attribute name=“QueueFactoryRef”>UIL2XAConnectionFactory</attribute>

<!– The topic factory –>

<attribute name=“TopicFactoryRef”>UIL2XAConnectionFactory</attribute>

<!– Connect to JNDI on the host “the-remote-host-name” port 1099–>

<attribute name=“Properties”>

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory

java.naming.factory.url.pkgs=org.jnp.interfaces

java.naming.provider.url=the-remote-host-name:1099

</attribute>

</mbean>

Troque “the-remote-host-name” para o IP do servidor que a Queue se encontra. E para fazer com que o MDB consuma de um provider remoto é mais fácil ainda:

@MessageDriven(activateConfig =
{
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="queue/testQueue"),
@ActivationConfigProperty(propertyName="providerAdapterJNDI", propertyValue="java:/RemoteJMSProvider")
})
public class MDB implements MessageListener
{
...
}

Agora para garantir com que as mensagens fossem persistentes. Definimos o envio do nosso Producer maneira persistente:


QueueSender sender = session.createSender(myQueue);
Message message = session.createTextMessage("hello");
int priority = 4;
sender.send(message, DeliveryMode.PERSISTENT, priority, 0);

Fazendo isto, garantimos a entrega da mensagem para o MDB pelo menos uma vez após uma exceção, se tornar a persistir, a mensagem é levada para o DLQ (ou mais conhecida como “lixão”), mas para que isso não ocorra você pode indicar que não quer tratamento de DLQ utilizando useDQL, desta forma, sempre ira tentar entregar a mensagem sem retirar da Queue enquanto houver exceção. Outra configuração que pode fazer também é numero de vezes que ele vai tentar entregar antes de mandar para DLQ o DLQMaxResent. A configuração do MDB pode ficar da seguinte forma:


@MessageDriven(activateConfig =
{
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="queue/testQueue"),
@ActivationConfigProperty(propertyName="useDLQ", propertyValue="true"),
@ActivationConfigProperty(propertyName="DLQMaxResent", propertyValue="100"),
@ActivationConfigProperty(propertyName="providerAdapterJNDI", propertyValue="java:/RemoteJMSProvider")
})
public class MDB implements MessageListener
{
...
}

Fiquei muito satisfeito com a facilidade de criação de aplicações desse tipo e ainda existe uma serie de configurações que podem ser feitas customizando a utilização de um MDB aumentando ainda mais a escalabilidade de sistemas, pois de uma solução JMS não se resume apenas apresentação unilateral de comunicação entre componentes, mais de uma interação substancial de processos definidos em uma margem de requisitos do funcionamento do sistema como um todo, tornando-o como uma ferramenta essencial na aplicação de grandes projetos.

Bom, vou ficando por aqui espero ter colaborado da alguma forma para o entendimento de aplicações JMS com MDB boa sorte e ate à próxima.

Relatórios em Flex? Jasper4Flex pode ser uma opção

Recentemente por uma iniciativa de Teodor Danciu, foi desenvolvido mais uma opção de renderização de relatórios feitos em jasper, so que desta vez em swf, ou seja, para desenvolvimento Flex, conhecido como Jasper4Flex, o mesmo possui algumas peculiaridades em relação ao FlexReport, pois constitui base jasper server-side, então toda a geração do relatório ocorre no servidor jasper seguido de um parser Jasper4Flex, feito por um servlet registrado no deploy descriptor:

web.xml

….

<servlet>

<servlet-name>SwfServlet</servlet-name>

<servlet-class>net.sf.jasperreports.j2ee.servlets.SwfServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>SwfServlet</servlet-name>

<url-pattern>/servlets/swf</url-pattern>

</servlet-mapping>

……

Em poucas linhas podemos fazer nossa chamada apartir de um servlet.

JasperPrint impressao = JasperFillManager.
fillReport("Report_exemplo.jasper", parametros,conn);
HttpSession session = request.getSession();
session.
setAttribute(BaseHttpServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, impressao);
response.sendRedirect("servlets/swf");

Neste caso foi criado um servlet para testar o exemplo. O código, não tem muito mistério a única diferença está, em como esse servlet vai responder essa requisição direcionando ’servlets/swf’. O resto o jasper4Flex se encarrega de fazer. Estou ate satisfeito com os testes que tenho feito ate agora. Mais o projeto é muito recente? Sim, eu sei mais a comunidade esta ai pra isso, testar, motivar e colaborar. Vejo isso como mais um incentivo a desenvolvedores que querem usar projetos Java em front-end Flex. Os exemplos podem ser baixados aqui no site do projeto.

Injeção de Dependência e o Google GUICE

Segundo Martin Fowler todo e qualquer conteiner leve deve por si só implementar Inversão de Controle (Inversion of Control, ou IoC), definidos por três possíveis formas de Injeção de Dependência (DI), constructor Injection (Injeção por Construtores), Setter Injection (Injeção por Métodos Set) e Interface Injection (Injeção por Interfaces), a DI está relacionada ao baixo acoplamento de diferentes componentes de seu sistema e como acessar o mesmos não por uma chamada direta e sim por uma “injeção” do conteiner, hoje existem vários conteiner leves que fazem essas implementações como PicoContainer, Spring, Avalon. O Guice criado pelos “GooglersBob Lee e Kevin Bourrillion traz como principal característica um conteiner puramente DI, suportando injeção via constructor e setter e podendo funcionar somente com anotações ou se preferir, construir módulos para definir os bind entre objetos.

DI, Guice Style

Diferentemente do clássico pattern Factory que traz a instância de uma implementação, quando se trata de DI ocorre a inversão desse controle e o Guice simplifica com uma simples anotação @Inject dizendo onde o conteiner vai injetar.

Code 1.

public class Cliente {

private Service service;

@Inject

public Cliente(Service service) {

this.service = service;

}

public void getMyService(){

service.getService();

}

}

No Code 1 acima usa-se uma injeção por construtor. O mais interessante é a configuração de dependência:

Code 2.

@ImplementedBy(ServiceImpl.class)

public interface Service {

void getService();

}

@Singleton

public class ServiceImpl implements Service {

public void getService() {

System.out.println(“Metodo getService foi chamado”);

}

}

Pronto, agora podemos testar o nosso exemplo a partir da classe Cliente do Code 1, as anotações @ImplementedBy define sua implementação de classe eliminando qualquer código, e a @Singleton define o escopo de implementação por padrão o Guice cria uma instância a cada chamada.

Code 3.

public class App {

public static void main(String[] args) {

Injector guiceInj = Guice.createInjector(new Module[0]);

Cliente c = guiceInj.getInstance(Cliente.class);

c.getMyService ();

}

}

Se tivermos sorte nosso Code 3 irá imprimir “Metodo getService foi chamado”, é claro podemos também definir nosso bind explicitamente por construção de módulos:

Code 4.

public class MyModule implements Module {

public void configure(Binder binder) {

binder.bind(Service.class).to(ServiceImpl.class).in(Scopes.SINGLETON);

}

}

…..

Injector guiceInj = Guice.createInjector(new MyModule());

Cliente c = guiceInj.getInstance(Cliente.class);

c.getMyService ();

……

O Code 4 mostra que um único metodo da interface é definido com um objeto Bind, podendo ser usado para definir sua especial sintaxe que pode ser lido da seguinte forma: “Amarra interface Service a implementação ServiceImpl no escopo Singleton”. Ate ai tudo bem, mais como sair da situação onde temos mais de uma implementação para nossa Service.class? Podemos também utilizar o AbstractModule para fazer nossa subclasse. A mesma implementa a interface Module e não define argumento no metodo configure, sigamos o exemplo com essa implementação:

Code 5.

public class MyModule extends AbstractModule {

public void configure() {

bind(Service.class).to(ServiceImpl.class);

bind(Service.class).to(ServiceImplNew.class);

}

}

Provavelmente quando for executar esse Code 5 irá ocorrer um erro de execução, pois o Guice não trabalha desta forma, então como sair dessa situação? Simples, basta fazer um bind com anotação da seguinte forma:

Code 6.

public class MyModule extends AbstractModule {

public void configure() {

bind(Service.class).to(ServiceImpl.class);

bind(Service.class).annotateWith(Marca.class).to(ServiceImplNew.class);

}

}

Isso mesmo, podemos definir um bind com uma marcação anotada em uma determinada requisição, vamos a sintaxe lendo da esquerda para direita: “Amarra todas as requisições para a interface Service anotado com @Marca para a implementação ServiceImpl”, porém a anotação @Marca deve ser criada programaticamente com a seguinte estrutura:

Code

Explanation

@Retention(RetentionPolicy.RUNTIME)

Anotação em tempo de execução

@Target({ElementType.FIELD,ElementType.PARAMETER})

Onde pode ser colocada

@BindingAnnotation

Informa que é uma anotaçao ‘binding’

Public @interface Marca{}

Como é declarada

Feito isso basta definir como marcação:

public class Cliente {

private Service service;

@Inject

public Cliente(@Marca Service service) {

this.service = service;

}

……

Bom, explorando mais a fundo o Guice podemos encontrar inúmeras funcionalidades como bindInterceptor, Aspect-Oriented Programming (AOP), Integrating Web(Struts 2, Wicket) entre outros, onde pode ou não trazer benefícios para sua arquitetura, isso vai depender muito do que você precisa e com que você esta trabalhando. Anteriormente em muitos fóruns já foi discutido isso, e muita gente não se sente muito confortável de como o Guice trabalha, porém, temos que concordar que não há muito que refazer com o que já foi feito só nos resta a escolha. Boa sorte a todos e espero que eu tenha ajudado de alguma forma com esse meu primeiro post.

Referencias:

http://martinfowler.com/bliki/InversionOfControl.html

http://www.javafree.org/content/view.jf?idContent=1

http://www.apress.com/book/view/9781590599976

http://code.google.com/p/google-guice/


Anderson Silveira

Anderson
Graduado em computação pelo CESUPA, com amplos conhecimentos na linguagem Java (EJB3/HIBERNATE/IBATIS) e Delphi com banco de dados PostgreSQL e Oracle, redes WI-FI. Experiência de mais de 4 anos como Analista/Desenvolvedor em ambiente Windows. Certificado Sun Programmer for the Java 2 Platform (SCJP), Sun Certified Web Component Developer(SCWCD) e Certified ScrumMaster(CSM). Atualmente se dedicando a projetos de aplicações ricas para Internet(RIA) e Metodologia Ageis. Perfil Completo

 

Dezembro 2009
S T Q Q S S D
« Nov    
 123456
78910111213
14151617181920
21222324252627
28293031  

Categorias

Arquivos