sexta-feira, 1 de agosto de 2008

JEE, o que é Java EE

Acho que uma das coisas mais chatas quando estamos desenvolvendo um sistema comercial de grande porte é termos que nos preocupar em escrever lógica de serviço de infra estrutura (Leia-se LOG, Conexão com Banco de dados, Cache, etc) e de nos preocupar com aspectos do desenvolvimento que são repetitivos e genéricos.

Esse tipo de preocupação, além de provavelmente não fazer parte do negócio para o qual estamos desenvolvendo o sistema, na maioria das vezes não agrega valor ao nosso sistema e é uma tarefa repetitiva ao longo do desenvolvimento, o que pode ser um esforço mal direcionado.
Pensando em resolver esses problemas, diversas empresas desenvolveram o que chamamos de Frameworks, que seriam “plataformas” de desenvolvimento que já implementam toda essa lógica repetitiva que não gostamos de implementar! Cada fabricante e cada Framework é focada em um determinado conjunto de regras de infra estrutura que resolve uma quantidade de detalhes de implementação.

Meu objetivo aqui é falar sobre a Plataforma Java Enterprise da Sun, que é um conjunto de especificação de frameworks que podem ser utilizadas juntas (ou não) para facilitar o desenvolvimento de nossos softwares coorporativos.

Especificação? Sim!

A Sun, em conjunto com o JCP (Java Community Process) desenvolve as especificações para a plataforma JEE (Java Enterprise Edition), e essa especificação é “aberta”, portanto qualquer empresa que se interesse pode desenvovler seus produtos (OpenSource ou não) seguindo essa especificação criada pelo JCP. Isso garante a portabilidade das aplicações desenvolvidas para a plataforma Java Enterprise. Então, você pode criar seu software de “locadora de videos” baseado em uma plataforma JEE e escolher de quem você vai comprar o servidor de aplicação, tendo a “certeza” de que sua aplicação vai ser portável entre os servidores.

Poxa, quer dizer então que a Sun não desenvolve a plataforma JEE?

Na verdade a Sun inventa a plataforma (em conjunto com o JCP) e atualmente ela tem liberado uma “implementação de referência” para cada especificação criada. Antigamente, quando a Sun lançou a JPE (Java Plataform for Enterprise, a predecessora da J2EE que é predecessora da JEE) em Abril de 1997, ela apenas produzia a especificação. No entanto, não existia uma maneira sólida de testar se os produtos criados por outros vendedores (ex. Oracle, BEA, etc) seguiam a especificação “à risca”.

Atualmente, quando sai uma especificação nova de alguma tecnologia que faz parte da JEE (discutirei essas tecnologias mais a fundo nos próximos posts) a Sun lança uma “implementação de referência”, que é um software implementando todas as funcionalidades que a especificação tras. Resumindo, se você desenvolver um software usando uma das tecnologias JEE e ele funcionar na implementação de referência, ele deve funcionar em um servidor comercial, se não funcionar é porque o vendedor daquele produto não está seguindo a especificação.
Outro problema que a JPE enfrentou foi a não sincronia das tecnologias especificadas.
Como assim?

Bom, a JPE inicialmente trazia a especificação para as seguintes tecnologias:
- EJB – Enterprise Java beans
- Servlet – Geradores de páginas HTML
- JNDI – Java Namming Directory
- (outras mais)

Imagine que, a equipe que desenvolveu a especificação do JNDI comece aprimorar essa especificação e criam um serviço de nomes muito mais estável e robusto, enquanto o pessoal que é responsável pelo EJB vai tirar ferias e esquece de pensar em melhorar a especificação. Qual seria o resultado? Teriamos uma especificação JNDI que poderia se tornar imcompatível com EJB. Uma outra plataforma que sofreu com problemas semelhantes foi a plataforma Eclipse. Antes do lançamento do projeto Europa, os plugins do eclipse evoluiam separadamente, e como existe muita dependência entre os plugins, eles acabavam se tornando imcompatíveis.

Atualmente, para cada distribuição do eclipse, é feito um controle dos plugins disponíveis para garantir essa compatibilidade e evitar muita dor de cabeça ao usuário. A Sun tomou essa mesma postura, e a partir da especificação J2EE já implementou um controle de versão e sincronia das tecnologias que fazem parte da plataforma Java Enterprise.

A plataforma JEE é uma plataforma que já tem 11 anos de história, e 11 anos de evolução contínua. Cabe lembrar que ela também não é proprietária, ou seja, não é a Sun que inventa as especificações ao seu “bel prazer”, existe um “consórcio” de empresas (o JCP) que decidem juntos as especificações, e disponibilizam essas especificações para quem quizer desenvolver.

Isso traz uma garantia para o desenvolvedor de que ele não vai ficar na “mão” de um único fabricante, nem amarrado a um software específico (ou seja, se o servidor de aplicação da oracle for muito caro, voce pode comprar o da RedHat, ou usar a “implementação de referência” da Sun, que é gratis e open source), o que pode ser uma grande vantagem para os “executivos” das empresas que escolhem adotar o Java como tecnologia de desenvolvimento. Para o Desenvolvedor a vantagem é enorme, já que ele tem uma plataforma padronizada e não precisa ficar se preocupando de quem a empresa vai comprar os servidores, além de ja poder usar um kit de ferramentas que implementam a maior parte da lógica de infra estrutura, ou seja, podem se focar apenas nos pontos importantes do software que estão desenvolvendo!

Nos próximos posts iniciarei uma discussão sobre a plataforma JEE atual, falando de uma maneira mais técnica sobre cada uma de suas tecnologias.

Abraços e até lá!
Giuliano Bortolassi

quinta-feira, 24 de julho de 2008

Configurando projeto Flex num Tomcat para acessar EJBs do JBoss

Pretendo explicar nesse post como configurar a biblioteca do Ryannorris (http://www.ryannorris.com/) para acessar um servidor de aplicação em uma máquina virtual diferente daquela onde roda seu aplicativo Flex.

O cenário onde apliquei os passos descritos nesse post foi o seguinte:

Sistema Operacional: Mac Os X 10.4
Versão do Java: 1.5
Servidor de aplicação: Jboss 2.0GA (http://www.jboss.org/)
Servidor Web: Esse servidor roda o projeto em Flex + Lcds: Tomcat 6.0 (http://tomcat.apache.org/)

Considere que o projeto em Flex já está funcionando juntamente com o LCDs, e os objetos remotos já estão sendo consumidos pelas aplicações em MXML.

A partir do momento em que o meu projeto já estava configurado e integrado com o LCDs, o que precisei fazer foi o seguinte:

(Ah! Tambem estou supondo que já exista um Application Server com os EJBs configurados e rodando perfeitamente)


Passo 1 - Adicionei as bibliotecas de cliente do JBoss na pasta lib do WEB-INF do meu projeto flex. ( No Flex Builder 3 o path seria algo mais ou menos assim
<projetoflex_home>/WebContent/WEB-INF/lib )

Passo 2 - Adicionei a biblioteca do Ryannorris na mesma pasta lib (<projetoflex_home>/WebContent/WEB-INF/lib). No entanto, precisei modificar a biblioteca do Ryannorris para acessar meu sevidor. Veja mais a frente como fiz.

Passo 3 - Registrar o Factory no services-config.xml do Lcds. O diretorio desse arquivo é o seguinte: /WebContent/WEB-INF/flex/.
Para registrar o Factory precisamos colocar o seguinte trecho de codigo no final do documento:

<factories>
<factory id="ejbFactory" class="com.adobe.ac.ejb.EJB3Factory">
</factories>
Essa classe EJB3Factory faz parte do jar da biblioteca do Ryannorris(flex-ejb-factory.jar).

Passo 4 - Registrar seu EJB no remoting-config.xml ( o arquivo fica no mesmo diretório do services-config.xml)


<destination id="carrinhoCompraBean">
<properties>
<factory>ejbFactory</factory>
<source>nomeRemotoDoSeuEJB</source>
<scope>application</scope>
</properties>
</destination>

O "nomeRemotoDoSeuEJB" é o nome usado para dar Lookup no objeto. Esse nome varia de servidor para servidor. No meu caso, usando o JBoss é algo mais ou menos assim: nomeProjeto/nomeClasseImplementacao/remote.
Ex:
myFlexEjbSample/CarrinhoBean/remote
Pronto. Isso é tudo que precisei configurar do lado do servidor. Iniciei o tomcat, e vi que ele startou corretamente, inclusive carregando o Factory especificado.

Agora vamos ao lado da aplicação MXML.

Na aplicação MXML precisamos apenas mapear mais um objeto remoto, como qualquer outro que já estejamos usando.

O código que usei foi o seguinte:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

/* Listener para o sucesso do metodo */
private function meuMetodoRemotoHandler(result:ResultEvent):void{
Alert.show("Result: "+result," Executou Metodo remoto ");
}
/* Listener para o erro do metodo */
private function meuMetodoRemotoErrorHandler(fault:FaultEvent):void{
Alert.show("Fault: "+fault," Erro ao executar metodo remoto ");
}
]]>
</mx:Script>

<mx:RemoteObject id="meuEjb" destination="carrinhoCompraBean">
<mx:method name="meuMetodoRemoto" result="meuMetodoRemotoHandler(event)" fault="meuMetodoRemotoErrorHandler(event)"/>
</mx:RemoteObject>
<mx:Button click="meuEjb.meuMetodoremoto()" label="Executar" x="250" y="218"/>

</mx:Application>


Na teoria é somente isso que precisamos. Se o seu serivor de aplicação e o servidor onde roda o LCDS forem o mesmo, provavelmente isso funciona. Como expliquei no inicio do post, o ambiente em que desenvolvo é diferente. O servidor de aplicação é em uma maquina, o meu servidor onde roda o LCDs é em outra... simplesmente o Factory não vai encontrar o meu EJB.

Por padrão, quando vamos desenvolver um cliente para um EJB, em outra máquina virtual, e em uma máquina com outro IP, precisamos adicionar um arquivo jndi.properties na pasta "src" do nosso projeto com as informacões para que nosso "initial context" encontre nosso servidor de aplicação. Eu tentei fazer isso. Adicionei esse arquivo na pasta source (que quando exportado vai para a pasta "/WEB-INF/classes" do projeto. Não funcionou. A Factory ainda não encontrava o servidor de aplicação.
Testei colocar o arquivo jndi.properties em outros diretórios, mas também não tive sucesso. Parti para o plano B, alterar os fontes do nosso amigo Ryannorris. ( a biblioteca ja vem com os fonts configurados para trabalhar no eclipse!! Uma mão na roda!)

Joguei a pasta dos fontes em um projeto novo no eclipse e dei uma bisbilhotada! Poxa.. como é simples fazer essa tal de Factory! Achei fantástico o trabalho do Ryannorris!

A idéia da Factory é a seguinte: Extender uma interface do LCDS (flex.messaging.FlexFactory) e implementar os métodos para criar seus objetos. No nosso caso, fazer o lookup dos EJBs. Como não poderia deixar de ser, em algum lugar vamos ter que criar nosso InitialContext e fazer o "lookup" do ejb. Fui na veia procurando já essa instanciação do Initial context. Isso acontece na classe "com.adobe.ac.ejb.LocalJNDIResourceLocator" da biblioteca do Ryannorris. Bom, como não consegui externalizar os parametros, criei um HashMap com eles e passei no construtor do InitialContext. Sei que isso é "feio" de se fazer, porque torna a implementação totalmente acoplada, não fica nada genérico. Toda vez que eu mudar meu servidor de aplicação de IP terei que alterar essa biblioteca. Uma alternativa imbutir o codigo do Ryannorris no meu projeto, mas não pretendo fazer isso. Por enquanto deixarei o código fixo, simplemente para fazer funcionar o lookup. Futuramente me preocuparei em externalizar essas configurações.

Vamos ao código. O que adicionei foram as seguintes linhas no método "locate" da classe do Ryannorris:


Hashtable hashParametros = new Hashtable();
hashParametros.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
hashParametros.put("java.naming.provider.url", "jnp://10.0.0.22:1099");
final Context ctx = new InitialContext(hashParametros);



O código completo do método ficou da seguinte maneira:


public Object locate(final String name ) throws ResourceException {
try {
Hashtable hashParametros = new Hashtable();
hashParametros.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
hashParametros.put("java.naming.provider.url", "jnp://localhost:1099");
final Context ctx = new InitialContext(hashParametros);
final Object res = ctx.lookup( name );
return res;
} catch ( NamingException e ) {
// tratamento da exception
}
}


Percebam que a única coisa que mudei foram realmente os parametros. Esses são os parametros que ficariam dentro do jndi.properties

E.. Voila! Funcionou!

Executei a aplicação flex e meu método remoto funcionou perfeitamente, invocando oEJB no outro servidor corretamente!

Se alguém tem uma solução simples e mais inteligente que a minha (heheh coisa que não é dificil) ou sabe onde colocar o arquivo jndi.porpeties para trabalhar com a biblioteca do Ryannorris, por favor me diga!

Bom, é isso ai, acho que fazer funcionar o EJB não foi tão dificil. Agora quero ver é usar o EJB de uma forma eficiente no projeto! é meu próximo desafio!



Flex3 + Lcds + EJB3

Recentemente terminei um curso de EJB3 (FJ-31) na Caelum. Curso muito bom, diga-se de passagem e tirei um peso de minhas costas: Aprender a usar efetivamente o tal do EJB.

A um tempo atraz eu tinha iniciado um blog somente para falar sobre tecnologia JEE e para me motivar a estudar o ejb (http://jeenoob.blogspot.com) mas acabei desistindo quando não consegui fazer o lookup e regigir corretamente os arquivos de deploy para o servidor Glassfish. No entanto agora, que aprendi como fazer o tal do EJB funcionar comecei a correr atraz de como usar ele nos meus projetos.

Hoje trabalho como arquiteto/gerente de produção em um projeto que usa as tecnologias Flex, Java e Microsoft SqlServer. Tirando o SQLServer a plataforma é bem produtiva e o Flex3 vem superando minhas expectativas no que diz respeito a produtividade.

Devido a alguns objetivos do lider do projeto, estou prevendo que vamos precisar se esforçar mais em relação a "robustes" da aplicação. Procurei então como mesclar o Flex, o Java e o EJB que poderia ser uma solução para um problema futuro.

Encontrei referências para o blog do Raynnorris ( http://www.ryannorris.com/ ) que desenvolveu uma Factory para o Lcds que consegue instanciar e fornecer EJBs de forma transparente para os aplicativos Flex. Achei a idéia fabulosa e fui testar.

O post do Raynnorris que explica como usar a biblioteca que ele criou é o seguinte: http://www.ryannorris.com/2007/05/18/using-flex-data-services-with-ejb3/

O post é bastante claro em relação a como configurar o LCDs para usar a Factory que ele criou, e explica muito bem como editar os XMLs do flex.

Simples, pratico e rápido.

No meu caso especifico tive que fazer algumas alterações nos fontes do Ray para que a Factory encontrasse meu servidor de aplicação.

Explico o que fiz para usar a biblioteca dele no post:
Configurando projeto Flex num Tomcat para acessar EJB3 no JBoss


Agora resta a dúvida... como será que o LCDs se comporta com uma grande quantidade de requisições??

O próximo passo vai ser fazer um "stress test" no meu aplicativo... simular as requisições e ver se o LCDs não vai gerar gargalo.

De nada adianta ter uma servidor robusto e uma arquitetura extremamente boa no servidor de aplicação se o servidor web não der conta do recado.

Um outro teste que estou agendando é fazer o LCDs rodar no próprio JBoss (hoje ele roda em um Tomcat 6.0).

Vamos ver no que dá!

quinta-feira, 5 de junho de 2008