Mostrando postagens com marcador JAVA EE. Mostrar todas as postagens
Mostrando postagens com marcador JAVA EE. Mostrar todas as postagens

Desenvolvimento Portlets: JSRs 168 e 286

quarta-feira, 12 de outubro de 2011

Duas JSRs, 168 e 286, atendem à criação de portlets. Em outubro de 2003 o JCP lançou a JSR-168, a primeira especificação que padroniza como os componentes devem ser desenvolvidos para os servidores de portal. Como as outras grandes JSRs, a JSR-168 possui o aval dos maiores fornecedores de portais. Esta especificação atende aos seguintes quesitos:

  • O contrato de contêiner de portlet e o gerenciamento do ciclo de vida do portlet; 
  • A definição dos estados das janelas e os modos do portlet; 
  • Gerenciamento das preferências do Portlet; 
  • Informações do Usuário como nome, endereço, e-mail, que podem ser informadas no arquivo de deployment descriptor e que podem ser recuperadas por um objeto Map através da constante USER_INFO definida na interface PortletRequest
  • Empacotamento e Deployment; 
  • Segurança; 
  • Tags para JSF. 
Mas, quando grandes fornecedores como a Apache, BEA, Borland, Oracle, IBM, SAP entre outros que fazem parte do expert group da JSR-168 começaram a criar as suas soluções de Portal, começaram a surgir também alguns problemas relacionados à limitação da especificação que antes não haviam sido detectados.
Conforme a adoção por soluções de portal baseadas na JSR 168 começou a aumentar, naturalmente o público consumidor destas soluções e o próprio negócio passou a demandar cada vez mais funcionalidades, que não haviam sido contempladas, fazendo com que soluções proprietárias fossem criadas pelos fornecedores. Entre as limitações da primeira versão da especificação de Portlets (JSR-168), podemos citar:
  • Falta de filtros para portlets (similar aos Filtros nos Servlets); 
  • Ausência de funcionalidades para a intercomunicação entre os portlets; 
  • Limitação do Escopo de Sessão do Portlet, onde a sessão do Portlet na JSR 168 se restringe apenas ao ID individual da aplicação e não da sessão do usuário do Portal. 
Essas limitações culminaram no lançamento da JSR 286, que define a segunda versão da API de Portlets. A JSR 286 incluiu novas funcionalidades como tratamento de eventos, envio e recebimento de parâmetros (permitindo a passagem de parâmetros entre os portlets), inclusão de filtros, suporte a Ajax e a disponibilidade de recursos do servidor, com o uso da interface ResourceServingPortlet.

Contrato do Contêiner e Gerenciamento do ciclo de vida do Portlet

A especificação da JSR-286 define um contrato para o contêiner de portlets. O contrato define quais métodos o contêiner deve chamar durante o ciclo de vida do portlet mediante o uso da interface javax.portlet.Portlet. O desenvolvedor pode implementar estes métodos para fornecer a funcionalidade desejada. Dessa forma, todo portlet tem que implementar esta interface, seja implementando-o diretamente ou estendendo uma classe existente que a implemente.
Os métodos do ciclo de vida executados pelo contêiner definidos pela interface javax.portlet.Portlet são apresentados na Tabela 1.

Método
Descrição
init()
Método executado quando o portlet for instanciado no contêiner.
processAction()
Chamado após o usuário submeter requisições ao portlet. É onde processamos os inputs disparados por uma ação do usuário do portlet.
render()
Chamado sempre que o portlet é reconstruído na tela.
destroy()
Executado no momento em que o contêiner destrói o portlet. Útil para liberarmos recursos que não estejam sendo utilizados, por exemplo, conexões com banco de dados.
Tabela 1. Métodos do ciclo de vida de um portlet

A especificação da JSR-286 ainda fornece interfaces opcionais para controle do ciclo de vida que o Portlet pode implementar como EventPortlet, que permite ao Portlet reagir às ações ou mudanças de estado oriundas da interação do usuário com o portlet ou ações originadas por outros portlets e a interface ResourceServingPortlet, utilizada para disponibilizar recursos do servidor no Portlet.

Portlet Modes e Window States

Para cada portlet existem dois itens de estado gerenciado, que são o modo do portlet (portlet mode) e o estado da janela (window state). Cada portlet possui um “portlet mode” corrente que indica a função que o portlet está realizando.
Os modes (ou modos) definidos na especificação são VIEW, EDIT e HELP. Estes modos são utilizados pelo método de renderização render(), conforme vimos na Tabela 1, para decidir qual método de visualização deve ser chamado. Os métodos de renderização chamados são apresentados na Tabela 2.

Método
Descrição
doView()
Método chamado por render() quando o portlet está em modo de visualização (VIEW). Deve conter a lógica que apresenta a página de Visualização para o portlet.
doEdit()
Chamado por render() quando o portlet está em modo de edição (EDIT).
doHelp()
Chamado por render() quando o portlet está em modo de ajuda (HELP) .
Tabela 2. Métodos de renderização do Portlet Mode

A classe PortletMode define constantes para estes portlet modes. A disponibilidade dos modos para o portlet pode ser restrito a roles (papéis) específicos de usuários do portal. Por exemplo, um usuário anônimo pode acessar o portlet apenas nos modos VIEW e HELP, enquanto que a role EDIT pode ser utilizada somente por usuários autenticados.
Outro tipo de estado gerenciado, o estado da janela (window state), apresenta a quantidade de informações que será disponibilizada para o portlet. A especificação define três tipos de estados para cada portlet, que são: normal, maximizado e minimizado. A classe WindowState possui constantes para estes estados da janela.
Para um maior entendimento, a Figura 1 apresenta estes conceitos de portlet mode e window state aplicados a um portlet.
Figura 1. Anatomia de um portlet
Opcionalmente o desenvolvedor pode especificar tipos customizados de modo e estado de janela, alterando o arquivo portlet.xml com uso da tag custom-window-state para estados de janela e custom-portlet-mode para modos.

JSF/Portlet Bridge

Como parte do projeto OpenPortal da Sun, foi criado o projeto JSF/Portlet Bridge, que tem como objetivo fornecer uma biblioteca de integração que permita que aplicações desenvolvidas com JSF possam ser executadas em um ambiente de Portlet.
Para atender à especificação de portlets, o JCP disponibilizou a JSR 301 para definir como um portlet 286 interage com os artefatos do JSF. A especificação foi para votação em Julho de 2006, mas somente em Janeiro de 2009 o draft da proposta final foi disponibilizada para o público.
Portlet Bridge é uma tecnologia utilizada por um portlet para fazer uma ponte (por isso o nome bridge) para um ambiente de execução, onde diferentes abstrações são utilizadas para processar as interações com o usuário ou para renderizar a interface gráfica.
O Portlet Bridge age como um engine tradutor entre o ambiente de portal e o sistema destino, neste caso, uma aplicação desenvolvida com o framework JSF. Ele ainda fornece uma abstração do ambiente de portal para o ambiente do bridge, deixando os desenvolvedores livres para executar aplicações Faces como portlets, sem a necessidade de conhecerem os detalhes das APIs de portlet e seu modelo de desenvolvimento.
A Figura 2 ilustra uma aplicação portlet utilizando o JSF/Portlet Bridge para executar páginas Faces como se fossem fragmentos de um portlet
Figura 2. JSF/Portlet Bridge entre uma aplicação Portlet e uma aplicação JSF.

Transformando sua aplicação JSF em um portlet

Para tornar uma aplicação JSF compatível com a JSR 168/286 é preciso fazer algumas alterações na aplicação antes de executá-la como um portlet.
Primeiro, para utilizar o JSF Portlet/Bridge é preciso efetuar o download da biblioteca jsf-portlet.jar no site java.net (ver ao final, em Referências) e copiá-la para o diretório WEB-INF/lib da aplicação JSF que você deseja executar como portlet.
Uma vez adicionado o arquivo .jar ao classpath da aplicação, é preciso adicionar o arquivo deployment descriptor portlet.xml para o portlet. Neste arquivo vamos informar a classe com.sun.faces.portlet.FacesPortlet para a tag portlet-class. Esta classe é a implementação da interface javax.portlet.Portlet fornecida pela biblioteca do JSF/Portlet Bridge, e é ela que fará o trabalho de converter as páginas JSF para páginas de visualização no Portlet.
É preciso também informar qual página queremos utilizar como página inicial do portlet, informando o parâmetro de portlet com.sun.faces.portlet.INIT_VIEW para a página desejada, conforme mostra a Listagem 1 entre as linhas 08 e 15.


    
        Portlet JSF
        Teste
        Portlet JSF/Portlet Bridge
        
        com.sun.faces.portlet.FacesPortlet
        
        
            Página inicial do Portlet 
            com.sun.faces.portlet.INIT_VIEW
            /index.jsp
        
        
            text/html
            VIEW
            EDIT
            HELP
        
        
            Portlet JSF
            JSF
        
    

Listagem 1. Portlet.xml de uma aplicação JSF
Para incluir a página de edição do portlet, o procedimento é similar. Nos parâmetros iniciais do arquivo portlet.xml, devemos incluir o parâmetro de portlet com.sun.faces.portlet.INIT_EDIT, conforme o trecho da Listagem 2. Essa ação fará com que o contêiner de portlets interprete a página JSF editar.jsp citada na listagem, como modo de visualização EDIT.


  Página de Edição do Portlet
  com.sun.faces.portlet.INIT_EDIT
  /editar.jsp

Listagem 2. Inclusão da página de edição JSF no portlet

O mesmo se aplica para a página HELP, com a inclusão do parâmetro com.sun.faces.portlet.INIT_HELP.
Além disso, se em nossa aplicação houver mais de uma página, podemos atribuir regras de navegação para cada uma destas páginas, e por ser uma aplicação JSF o modelo de navegação é o do próprio JavaServer Faces.

O modelo de navegação do JSF torna fácil o trabalho de definir a regra de navegação das páginas do projeto, com a utilização de apenas algumas linhas no arquivo faces-config.xml da aplicação JSF. Podemos indicar qualquer página do portlet como referência para navegação, conforme demonstra a Listagem 3.

Na Listagem 3, utilizamos o modelo de navegação declarativo do próprio JSF para definir a navegação de um portlet. Como não é o escopo deste artigo, não iremos explicar o funcionamento das regras de navegação do JavaServer Faces, mas apenas para ilustrar, nesta listagem definimos uma regra que ao ser disparada uma ação na página editar.jsp, a aplicação irá navegar desta página para a página index.jsp, se o resultado referenciado pelo componente que disparou a ação de navegação da página editar.jsp for success.

  /editar.jsp
  
    success
    /index.jsp
  

Listagem 3. Navegação entre páginas JSF em um portlet
Por fim, para executar a aplicação é preciso somente efetuar o deploy do arquivo WAR para o seu servidor de portal preferido.
WSRP
WSRP significa Web Services for Remote Portlets, ou web services para portlets remotos. WSRP é uma tecnologia definida pela OASIS, e propõe um padrão para web services visuais que podem ser plugados em ambientes de portal que estejam aderentes à especificação, ou seja, se em um web service padrão nós reutilizamos o serviço com WSRP, reutilizamos toda a interface gráfica.
OASIS: Consórcio global formado por grandes empresas de tecnologia da informação como IBM, SAP, AG, Sun Microsystems, que conduz o desenvolvimento, convergência e adoção de padrões para e-business e web services, produzindo diversas especificações e padrões relacionados a áreas como SOA, web services, processamento de XML, segurança da informação e supply chain. 
Atualmente a API WSRP está na versão 2.0 e possui um fluxo bem simples. O owner do portal ou da aplicação primeiro inclui em seu ambiente de portal um web service de terceiro (WSRP) dentro de um portlet. A partir deste momento, o portlet irá interagir com o conteúdo e com os serviços descritos no documento wsdl do WSRP, conforme veremos em detalhes mais adiante.

Um WSRP define:
  • Uma interface WSDL para invocação dos serviços WSRP; 
  • Como publicar, buscar, e efetuar bind dos serviços WSRP e metadados; 
  • Regras de fragmentação por marcação, para marcações emitidas pelos serviços WSRP. 
WSDL: Significa Web Service Definition Language, é uma linguagem baseada em XML utilizada para descrever web services. Além de descrever o serviço, um documento WSDL especifica os métodos e operações disponíveis e como acessá-los. 

WSRP é útil para o desenvolvimento web pois ele desacopla o deployment da entrega da aplicação, assim como fornece tanto os dados quanto a lógica de apresentação e requer pouca ou nenhuma programação para implementação do serviço. Além disso, WSRP fornece uma série de benefícios adicionais, como interoperabilidade e portabilidade. Normalmente um servidor de portal pode atuar como um produtor ou consumidor de WSRP.
Graças a essa interoperabilidade com o WSRP, podemos então rodar portlets Java remotos em uma ferramenta de portal que não seja em Java, como no Microsoft SharePoint.
Entre as desvantagens, estão a adoção ainda baixa por parte dos fornecedores, e a performance, que tende a ser baixa em grandes aplicações.

Como funciona?

Basicamente, um WSRP envolve dois componentes, além do portlet em si, conforme demonstra a Figura 3. A aplicação remota, conhecida como WSRP Producer, implementa os padrões de web services utilizando a especificação SOAP (Simple Object Access Protocol) sobre HTTP.
O WSRP Producer fornece um conjunto de operações para os consumidores do serviço, onde dependendo da implementação, o Producer pode tanto oferecer apenas um portlet quanto pode fornecer um ambiente para gerenciamento de diversos portlets. Resumindo, o WSRP Producer é um web service verdadeiro, com um WSDL e um conjunto de endpoints. Cada WSRP Producer é descrito utilizando um documento WSDL padrão.
O segundo componente é o WSRP Consumer, que é o cliente do serviço e que age como uma aplicação de portal para consumir o serviço baseado no arquivo WSDL do Producer.
Figura 3. Consumo de um WSRP

Interfaces do WSRP
Conforme explicado, WSRP define um conjunto de interfaces que todo WSRP Producer deve implementar e que todo WSRP Consumer utiliza para interagir com os portlets remotos. O grande benefício de se padronizar estas interfaces é a possibilidade de criar portlets genéricos. Isto garante que todo fornecedor de portal que queira suportar WSRP deve seguir a especificação.
A especificação WSRP propõe as interfaces definidas na Tabela 3.

Interface
Descrição
Obrigatório?
Service Description Interface (Interface de Descrição de Serviço)
Essa interface fornece uma descrição dos serviços fornecidos pelo Producer. Baseado nestas informações, o Consumer é capaz de determinar o que é preciso para executar o portlet, como por exemplo, inicializar um cookie antes que o Consumer interaja com qualquer um dos portlets.
Sim
Mark-up Interface (Interface de Marcação)
A Interface de Marcação permite que o Consumer interaja com o portlet remoto. Por exemplo, o Consumer poderia utilizar esta interface para realizar interações quando um usuário final submete um formulário a partir de uma página de portal. Além disso, o portal pode precisar obter a última marcação baseada no estado atual do portlet (por exemplo, quando um usuário atualiza o navegador ou inicia uma interação com outro portlet na mesma página).
Sim
Registration Interface (Interface de Registro)
Esta Interface permite que o Producer obrigue que os Consumers façam um registro antes de interagir com o serviço através do uso das interfaces de Service Description e Mark-up.
Não
Portlet Management Interface (Interface de Gerenciamento do Portlet)
Esta interface fornece acesso ao ciclo de vida do portlet remoto. Um Consumer poderia customizar o comportamento do portlet ou até mesmo efetuar uma chamada ao método destroy() mediante o uso desta interface.
Não
Tabela 3. Interfaces definidas na especificação WSRP

No mais é isso, 
Diversão Garantida!!!

Web Services WS-* vs REST.

quinta-feira, 14 de maio de 2009

Muitos sites, blogs e fóruns têm colocado seus pontos de vista em relação ao uso de web services REST e SOAP, gerando muitas vezes calorosas discussões.

Na verdade, não existe uma disputa entre eles, pois cada um possui uma proposta bem diferente. Vários estilos diferentes de aplicações tem sido utilizadas para integrar sistemas de informação corporativos, entre as opções, existem os banco de dados compartilhados, transferência de arquivos (EDI ), remote procedure call (RPC), ou troca de mensagens assíncronas via uma sistema de mensageria. Ao fazermos uma comparação entre REST e WS-* (pronucia-se ws-star), precisamos fazer uma comparação quantitativa baseado em princípios arquiteturais que envolvem questões relacionadas a cenário, tecnologia, métodos, formato dos dados trafegados, segurança, transação, entre outros fatores da sua aplicação. Devemos lembrar que estas tecnologias surgiram para suprir estes problemas recorrentes na maioria dos projetos de software, que é a interoperabilidade.

Foi quando começaram a surgir esforços da comunidade de buscar dos grandes players interoperabilidade entre suas plataformas, aplicações, e linguagens de programação. Foi quando surgiram as especificações WS-*, que atendem tanto ao estilo RPC quanto mensageria. A especificação SOAP não define como deve ser um message header, ou elementos do corpo do envelope, dessa maneira podemos ter aplicações que customizem o tipo de header que ela aceita, e o tipo de informação que deve estar vinculado ao body para uma operação em particular, sem falar que algumas dessas informações podem ser compartilhadas por diferentes aplicações, sem falar em questões de segurança, roteamento de mensagens, entre outros fatores.

As especificações WS-* definem padrões para mensagem, troca de metadados, segurança, entre outros. No mundo Java, para implementar este mundo de especificações, foi aberto o projeto WSIT (antigo projeto Tango) como parte do projeto Metro, que por sua vez faz parte do projeto Glassfish, veja a Figura 01 os padrões (em verde) utilizado no projeto WSIT.

Figura 1: Padrões de Web Services utilizados no WSIT.

É claro que para a maioria dos projetos, um web service simples resolveria, mas se começarmos a entrar mais a fundo no mundo orientado a serviços, começa a surgir a necessidade de integração com diversos sistemas, naturalmente teremos que utilizar estes padrões. É somente olhar para a figura 01 que já causa calafrios em muitos desenvolvedores, mesmo com suporte eficiente nos IDEs existentes.

Com isto, vemos claramente que a arquitetura de web services baseadas nas especificações WS-* é muito bem definida, com regras para trocas de dados, segurança, o que por conta de seu excesso de padrões acabou se tornando uma solução muito complexa.

Mesmo com toda a complexidade, serviços WS-* têm tomado cada vez mais espaço no mercado, graças aos projetos SOA que tem adotado largamente serviços WS-* por sua independência e transparência de protocolo. Por outro lado, REST é muito mais simples, como uma resposta para todos estes padrões e especificações, para utilizar REST basta ter um conhecimento razoável sobre HTTP e seus métodos.

Enquanto web services WS-* são orientados a atividade/serviço, serviços REST são orientados a recurso. Quando falamos em desenvolver serviços SOAP, estamos falando em criar APIs, contratos (WSDL), onde o WSDL descreve os detalhes de implementação, como as operações e os tipos de dados trafegados. REST por outro lado, conforme explicado no inicio diz respeito a utilizar o protocolo HTTP para manipular o estado de um recurso. Fazendo uma analogia, podemos dizer que assim como a linguagem de manipulação de dados (DML) do SQL é utilizada para manipular as informações de um banco de dados transacional, REST utiliza os métodos (verbos) do protocolo HTTP para manipular o estado de uma informação. Com estes verbos, podemos fazer praticamente tudo o que quisermos com os dados, independente se usarmos SQL ou HTTP.
Ao mapear os métodos HTTP (POST, DELETE, GET E PUT) com operações DML de um banco de dados temos a seguinte estrutura, conforme ilustra a tabela 01.

Métodos HTTP / Operações CRUD
GET -> SELECT
POST -> INSERT, UPDATE
PUT -> INSERT, UPDATE
DELETE ->DELETE

Tabela 01. Associação dos métodos HTTP com operações CRUD.
Na tabela podemos notar que podemos ter mais de uma operação relacionada a um verbo HTTP, como por exemplo, o método POST, que pode ser utilizado para diversas ações. O método PUT nos dá a possibilidade de criar um novo recurso, ou substituir por outro mais atualizado. Apesar dos diversos tutoriais e exemplos que encontramos na internet sobre REST que envolvem operações CRUD, isso não quer dizer que temos que ficar presos somente a estes tipos de operações. Por conta de sua própria natureza, REST é mais fácil e funciona muito bem com CRUDs, mas podemos em nosso design criar serviços REST. Web Services RESTful.



Pontos Positivos
Pontos Negativos
  • Linguagem e plataforma agnóstica.
  • Simplicidade, interface imutável.
  • Interação assíncrona, não possui estado.
  • Facilidade de adoção, pois não requer uma grande infra-estrutura, muito menos um middleware para WS-* ou camada intermediária adicional.
  • Utiliza a própria web como meio de transporte, sendo assim uma carga baixa para a rede.
  • Utilizada por grande parte das aplicações Web 2.0. (Google, Flickr, Amazon, etc..). Portanto, ótimo para mashups.
  • Curva de aprendizagem baixa.

  • Faltam padrões.
  • Falta de segurança (dados sigilosos não deveriam ser enviados como parâmetros na URI).
  • Não é indicado para trafegar grandes volumes de parâmetros via URI, no caso de PUT/POST para inclusão de dados, por exemplo.
  • Em muitas empresas apenas os métodos GET e POST do HTTP são liberados em proxies e firewalls. Dentro desta limitação, muitos preferem utilizar os métodos GET para requisições de consulta e POST para todo o resto.
  • Não há mecanismos de transação (Do it yourself)
  • Não existe um padrão como UDDI para service discovery.

Tabela 02: Pontos positivos e negativos de REST

SOAP


Pontos Positivos
Pontos Negativos


  • Diversas ferramentas de desenvolvimento.
  • Tipagem forte e um vocabulário bem definido.
  • Quando utilizado sobre HTTP, dificilmente é bloqueado por proxies e firewalls.
  • Permite o uso de diferentes tipos de protocolos.
  • Plataforma independente.
  • Linguagem independente.
  • Diversos padrões.
  • Complexidade dos padrões.
  • Performance.
  • Mensagens podem ficar muito extensas, por serem codificadas com XML
Tabela 03: Pontos positivos e negativos com SOAP.

Fazendo esta pequena análise, chegamos á conclusão de que ambas as soluções são úteis, e a utilização de cada uma depende do contexto em que será aplicada.

Referências (Links):

[Parley] A Little REST and Relaxation: http://tinyurl.com/cm33t2
Estilo SOAP vs Estilo REST: http://www.ibm.com/developerworks/webservices/library/ws-restvsoap/
Descrevendo Serviços REST com WSDL 2.0: http://www.ibm.com/developerworks/webservices/library/ws-restwsdl/
Bruno Pereira: http://brunopereira.org/2008/05/14/precisamos-de-um-descritor-de-servicos-rest/

Just Java 2008

domingo, 31 de agosto de 2008


Esta chegando o Just Java 2008, em Setembro no mês do Java a festa do Just Java será em São Paulo nos dias 10, 11 e 12 de Setembro. Será a 7a edição do principal evento da Comunidade Java Brasileira.
Serão 3 dias com várias palestras relacionadas a Java e agora com alguns temas sobre Agile, hora de aprender um pouco mais, rever os amigos e reforçar o Networking.

Eu vou representar no Just Java com duas palestras junto com meu grande amigo Renato Bellia, no dia 10 ás 15:00 hs com a palestra Java EE 6 / EJB 3.1 e o Futuro do Java Corporativo no auditório superior 2, e no dia 11 de Setembro será a vez de falar do framework Diamond Powder - Produtividade OpenSource para JavaME, que é um projeto criado pelo Bellia.

Neste projeto do Diamond Powder, tive a felicidade de participar com o desenvolvimento de um plugin para o NetBeans para facilitar a criação do Schema, que é um Hashtable que descreve o os campos do coletor, as páginas, fluxo de navegação com opção de persistência.
Você que desenvolve aplicativos embarcados vale a pena conhecer este framework!!

Site do Evento: http://www.sucesusp.org.br/justjava2008/
Grade de Palestras:
http://soujava.org.br/display/v/Grade+de+Palestras
Diamond Powder no java.net: https://diamond-powder.dev.java.net/
Blog do Diamond Powder: https://diamond-powder.dev.java.net/

Participe, é diversão garantida !

[EJB 3.1] Novidades na especificação - Parte 2

sexta-feira, 2 de maio de 2008

Continuando o artigo sobre as novidades na Especificação EJB 3.1, nesta segunda parte vamos abordar o invoções assíncronas e EJB sem interface.

Na nova especificação um cliente pode invocar um session bean de maneira síncrona ou assíncrona. Invocações assíncronas que é a novidade nos permite efetuar uma chamada a um método remoto (assíncrono) e não precisamos esperar o seu retorno, neste caso a assinatura do método deve ser void, ou o método pode retornar um objeto Future que retorna o resultado para o cliente após o processamento, o que permite verificar as exceções ou até mesmo cancelar a invocação ao método no meio da execução.


Exemplo:

@Asynchronous
public Future executarMetodo() {
String resultado = "Executando Método";
return new AsyncResult(resultado);
}

Outra novidade é o que todos já esperavam "O Fim das Interfaces", ou pelo menos agora elas são opcionais. Antes que alguém se empolgue é bom deixar claro que isso só funciona para objetos LOCAIS, ou seja, o cliente que irá chamar o método deve estar na mesma JVM. :-(Na verdade um session bean sem interface é uma variação do EJB local, mas expõe os métodos públicos da classe bean sem utilizar uma interface de negócio separada.
A referência para o Bean sem interface pode ser passada como um parâmetro, como valor de retorno de qualquer interface de negócio local ou como método de uma classe ejb sem interface.
A implementação do contêiner para Beans sem interface é o mesmo que nós fazemos quando acessamos um método qualquer de uma classe qualquer pela referência, o método de negócio da instancia do session bean e seus interceptors são invocados conforme a necessidade.
Somente os métodos públicos da classe bean (e qualquer super-classe) pode ser invocado através do Bean sem interface. Qualquer tentativa de invocação a métodos com modificadores de acessos diferente de público, irá lançar um javax.ejb.EJBException.
Vejamos a evolução da especificação EJB, dando o mesmo exemplo nas versões 2.1, 3.0 e finalmente 3.1.

Versão 2.*

Até a versão 2.* a comunidade reclamava muito da complexidade dos EJBs, para a criação de um método simples era preciso criar as interfaces (remota e local), a interface home e finalmente a classe de negócio...

Interface Local

import javax.ejb.EJBLocalObject;

public interface SayHelloRemote extends EJBLocalObject{
public void hello();
}

Interface Home

import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;

public interface SayHelloHome extends EJBLocalHome {
SayHello create() throws CreateException;
}

Session Bean

import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

public class SayHelloBean implements SessionBean {
public void sayHello() {
System.out.println("Hello");
}

public SayHelloBean() {}
public void ejbCreate() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sc) {}
}


Cliente Session Bean 2.1

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

public class SayHelloClient {

public static void main(String[] args) {
try {
Context initial = new InitialContext();
Context myEnv = (Context)initial.lookup("java:comp/env");
Object objref = myEnv.lookup("ejb/SayHello");
SayHelloHome home = (SayHelloHome) PortableRemoteObject.narrow(objref,
SayHelloHome.class);
SayHello papagaio = home.create();
papagaio.sayHello();
papagaio.remove();
System.exit(0);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Versão 3.0

Vemos que até a versão 2.1 era muito trabalho criar um simples Hello World com EJB, a Sun vendo que o EJB estava perdendo espaço para frameworks comunitários, como Hibernate para persistência e outras alternativas para Session Beans, decidiu fazer uma mudança radical na especificação, descontinuando os Entity Beans e apresentando o JPA, e tirando a obrigatoriedade de criar a classe Home, eliminando a criação de deployment descriptors, usando e abusando da IoC com o uso extensivo de annotations. A especificação facilitou muito o desenvolvimento e a especificação EJB voltou a ser o supra sumo do Java, vejamos um exemplo

Interface de Negócio Local

import javax.ejb.Local;

@Local
public interface SayHelloLocal {
void hello();
}

Session Bean

import javax.ejb.Stateless;

@Stateless
public class SayHelloBean implements SayHelloRemote, SayHelloLocal{
public void hello() {
System.out.println("Hello");
}
}

Cliente que executa o EJB

public class SayHelloClient {
private static Properties prop = new Properties();
private static Context c;
public SayHelloClient(){
prop.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
prop.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
prop.put("java.naming.provider.url","localhost");
}
public static void main(String[] args) {
SayHelloClient main = new SayHelloClient();
SayHelloRemote remote = main.lookupSayHelloBean();
remote.sayHello();
}
private SayHelloRemote lookupSayHelloBean() {
try {
c = new InitialContext(prop);
return (SayHelloRemote) c.lookup("SayHelloBean/remote");
} catch (NamingException ne) {
throw new RuntimeException(ne);
}
}
}

Versão 3.1 Draft

Com a eliminação da classe home não precisamos mais fazer o narrow no código cliente. Agora basta efetuar um lookup na classe Bean.

Classe de implementação de negócio
// Sem Interfaces Remota ou Local
import javax.ejb.Stateless;

@Stateless
public class SayHelloBean implements SayHelloRemote, SayHelloLocal{
public void hello() {
System.out.println("Hello");
}
}

Cliente que executa o EJB

public class SayHelloClient {
// Se o cliente estiver no conteiner, Injeção nele !!!
// Veja que estamos referenciando ao session bean
// SayHelloBean e não SayHelloRemote.

@EJB SayHelloBean falaAi;
@Resource SessionContext c;
public SayHelloClient(){}
public static void main(String[] args) {
falaAi.hello();
SayHelloClient main = new SayHelloClient();
SayHelloBean sayAgain = main.lookupSayHelloBean();
sayAgain.hello();
}

// Ou podemos fazer via JNDI
private SayHelloRemote lookupSayHelloBean() {
try {
return (SayHelloBean) c.lookup("sayHello");
} catch (NamingException ne) {
throw new RuntimeException(ne);
}
}
}

Podemos observar que esta muito mais simples criar EJBs, sem as interfaces o código fica muito mais limpo e temos uma programação muito próximo de objetos POJO, entretanto, por motivos já conhecidos não é possível instanciar um objeto com o operador new, somente via injeção ou jndi. Para a especificação 2.1 por exemplo, tínhamos que criar 4 objetos para um simples hello world (local), na especificação 3.0 não é obrigatório implementar a interface SessionBean na classe session bean ou a interface Serializable, assim como as classes Interceptors. Viva a injeção de dependência !!!
Veja que ainda precisamos de 3 objetos (sai a interface home) mas o processo já simplifica com a entrada das annotations. Agora na versão 3.1 foi eliminada a necessidade de interfaces (lembre-se, apenas para objetos locais)..
Para criar um EJB sem utilizar a interface, ela deve seguir algumas seguintes regras, ela deve expor os métodos sem interface via definição de classe ou pelo deployment descriptor. E ... :
  • Se o bean não expor nenhuma outra interface(s) e não implementar nenhuma interface, então o bean define uma EJB sem interface.
  • As seguintes interfaces são excluídas quando implementamos um EJB sem interface : java.io.Serializable, java.io.Externalizable; E qualquer outra interface definida no pacote javax.ejb.
  • Todos os métodos da classe bean e qualquer superclasse são expostos como métodos de negócios através de um bean sem interface. E isto inclui os métodos de callback (muito cuidado !!!).
  • Os métodos expostos da classe bean sem interface não devem lançar a exceção java.rmi.RemoteException.

Ainda tem várias coisas legais para discutir, provavelmente será possível rodar EJB no TomCat :D, com o pacote light do EJB, no próximo post vou cobrir o calendário para o Timer e concorrência !!!

[EJB 3.1] Novidades na especificação - Parte 1

quarta-feira, 30 de abril de 2008

O mercado brasileiro ainda nem assimilou direito a especificação de EJB 3.0 e a JSR-318 - Enterprise JavaBeans 3.1 já foi aprovado pela maioria dos membros do comit executivo para as especificações SE / EE do Java. O único membro que reprovou a JSR foi a Apache.


Isso porque a Apache Software Foundation diz que a spec lead (SUN) esta em desacordo com a JSPA. O que foi explicado pela própria Sun.

The spec lead of the EJB 3.1 specification has confirmed that the TCK would contain no "field of use restrictions", as originally raised by Apache with regard to another JSR (i.e. the SE TCK licensing). That is a good thing.

However, in the absence of an explicit JSPA rule that would forbid such field-of-use restrictions, we will remain worried that a similar issue might resurface anytime, for any JSR.

Consequently, in the future, for any submitted JSR (by SUNW or not), we will specifically expect the spec lead to provide clear information on that aspect and take the answer in account when casting our vote.

As novidades na especificação 3.1 visou simplificar a já fácil especificação 3.0 dos EJBs, aumento o uso de annotations e consequentemente o uso ioc, conforme segue:

  • Uma visão Local simplificada que forneça acesso ao Session Bean sem a necessidade de uma interface de negócio local.

  • Empacotamento e o deployment de componentes EJB diretamente de uma arquivo .war sem a necessidade de um ejb-jar.

  • Um componente Session Bean Singleton que forneça um acesso fácil para estado compartilhado, assim como callbacks de startup/shutdown da aplicação.

Isso quer dizer que agora temos um novo tipo de Session Bean, diferente de um Session Beans Stateful ou Stateless, o Session Bean Singleton é um componente que é instanciado apenas uma vez por aplicação. Em casos onde o conteiner é distribuído para várias JVMs, cada aplicação irá possuir uma instância de um bean Singleton para cada JVM. O Session Bean Singleton é compartilhado e suporta acessos concorrentes.
Uma vez instanciado, o tempo de duração da instância do Session Bean Singleton é o mesmo do Contêiner onde ele foi criado. O que mantêm o estado entre as invocações do cliente mas o conteiner não é obrigado a preservar o estado do bean em um suposto crash ou shutdown no conteiner. Resumindo, Singleton Session Beans NÃO são passivados (é assim que se traduz ?).
Outra coisa, um Session Bean Singleton pode ser utilizado como um cliente web service. Somente um Session Bean Stateless ou Single podem fornece uma visão cliente de web service.

Eis o ciclo de vida de Singleton Session View.




  • O ciclo de vida de um session bean singleton inicia quando o conteiner invoca o método newInstance da classe Session Bean para uma instância do Singleton. A seguir, o conteiner realiza as injeções de dependência especificado pelas anotações na classe bean ou pela DD. O conteiner chama o método callback PostConstruct para o bean, se houver.

  • A instancia do SB Singleton esta agora pronta para delegar a chamada do método de negócio para qualquer cliente ou a chamada do conteiner para método callback disparado por timeout.

  • Quando a aplicação esta em shutdown, o conteiner invoca o método callback PreDestroy do Singleton, se houver. Isto finaliza o ciclo da instancia do session bean singleton.

Inicialização do Singleton

O conteiner decide o momento de instanciar o bean Singleton. Se o conteiner encontrar a anotação Startup na classe Singleton ou se o deployment descriptor estiver especificado startup na classe bean o conteiner DEVE instanciar durante o startup da aplicação. O exemplo abaixo inicializa a classe Singleton com estado compartilhado:

@Startup
@Singleton
public class SharedBean implements Shared {
private SharedData state;
@PostConstruct
void init() {
// initialize shared data
...
}
...
}



Outra novidade, é a possibilidade de criar uma cadeia de dependência entre múltiplos componentes Singleton em uma aplicação, através da anotação DependsOn.

@Target(value=TYPE)
@Retention(value=RUNTIME)
public @interface DependsOn


Esta anotação é utilizada quando precisamos iniciar uma instancia de um bean Singleton antes de instanciar outro objeto. Se um Singleton precisa invocar outro Singleton a partir do método PostConstruct, não é necessário uma ordenação via metadados (DD). Exemplo:

@Singleton
public class B { ... }
@DependsOn("B")
@Singleton
public class A { ... }


Essa anotação diz para o conteiner para garantir que o Singleton B é inicializado antes do Singleton A.
É possível incluir um ou mais valores no atributo value de DependensOn, onde cada valor especifica o ejb-name do Singleton destino utilizando a mesma sintaxe do atributo beanName() de @EBJ. Exemplo:

@Singleton
public class B { ... }
@Singleton
public class C { ... }
@DependsOn({"B", "C"}) // A só será iniciado após B e C serem iniciados
@Singleton
public class A { ... }



Isso garante que A só será iniciado após B e C serem iniciados. No caso de múltiplos valores, a ordem que os valores foram informados em value não garante a ordem de execução em runtime.

Ex,: Se o Singleton B possui uma dependência na ordenação no Singleton C, é a responsabilidade do Singleton B de capturar o que está explicito em seu metadado. Exemplo:

// 2 componentes Singleton empacotados em ejb-jars diferentes
// mas no mesmo arquivo .ear
// empacotado no arquivo b.jar
@Singleton
public class B { ... }
// packaged in a.jar
@DependsOn("b.jar#B")
@Singleton
public class A { ... }


Isto demonstra o uso do nome totalmente qualificado da sintaxe do ejb-name para referencia ao componente Singleton empacotado em um módulo diferente na mesma aplicação.

Lembra no EJB 3.0 para evitarmos nomes ambíguos
@EJB(beanName="netfeijao-ejb.jar#NetFeijaoEJB")

Em breve vou publicar mais sobre a nova especificação, para saber mais leia o artigo publicado no server-side, e a página da JSR..

  1. JSR 318: Enterprise JavaBeans 3.1
  2. Artigo na Server Side

Certificação SCBCD 5 (CX-310-091) - Guia de Estudo

sexta-feira, 15 de fevereiro de 2008

Recentemente tive a felicidade de passar a prova da certificação SCBCD 5.0 com o score de 75%.. não fui muito bem em JPA, pois acabei subestimando a esta parte por conta da experiência que tenho com persistência, enfim ao todo foram 61 perguntas tive e fui avaliado nas seguintes seções:
---------------------------------------------------------------

  • EJB 3.0 Overview
  • General EJB 3.0 Enterprise Bean Knowledge
  • EJB 3.0 Session Bean Component Contract & Lifecycle
  • EJB 3.0 Message-Driven Bean Component Contract
  • Java Persistence API Entities
  • Java Persistence Entity Operations
  • Persistence Units and Persistence Contexts
  • Java Persistence Query Language
  • Transactions
  • Exceptions
  • Security Management
---------------------------------------------------------------

Como fiquei alguns meses me preparando para esta prova, tive a oportunidade de conhecer as melhores fontes na Web para a preparação desta certificação tão almejada.

Mocks (Simulados):

JavaBeat - http://www.javabeat.net/javabeat/scbcd5/mocks/

Esse site possui 4 mocks bem interessantes,..

Existem também softwares comerciais ($$) de simulados conforme os links que segue, mas o 3 possuem uma versão demo para download, com várias questões, vale a pena baixar pelo menos a versão demo pois as questões são bem similares ao exame real.


Resumos (Notes) de estudo

Esse site (Java Boot) é ótimo pois oferece um material completo de cada tópico abordados nos objetos, ALTAMENTE RECOMENDADO.

Java Boot -http://java.boot.by/scbcd5-guide/

Livros:

Bom eu li todo o livro Enterprise JavaBeans 3.0 (5th.Edition)


Outro otimo livro para estudo é o Mastering Enterprise JavaBeans 3.0 que pode ser baixado FREE neste link no site ServerSide.com

E li alguns capítulos do Java EE Tutorial 5 da Sun, mais precisamente os capítulos:

Capítulo 1 - Overview.
Leitura que fornece um overview da arquitetura de servidores Java EE, os tipos de serviços que os servidores que são certificados devem implementar, e conceitos de aplicações distríbuidas, os papéis do devenvolvimento (Bean Provider, Application Assemblem, Deployer, etc...) é bom conhecer bem estes papéis, pois caiu na prova não uma, mas várias questões que exigem o conhecimento dos papéis no desenvolvimento de software corporativo. Depois vamos pular para o Capítulo 20, que aborda o assunto de EJBs em uma visão macro, é interessante estudar também o Capítulo 21, que ensina como iniciar o desenvolvimento em EJB, o Capítulo 22 que apresenta códigos de exemplo para Session Beans, o Capítulo 23 que aborda de maneira prática Message Driven Beans, os Capítulos 24, 25, 26 e 27 que aborda Java Persistence API, é bom estudar também segurança nos Capítulos 28 e 29 se você não conhece JMS, não é prioritário saber para o exame mas como o exame aborda MDB recebendo mensagens de JMS é bom ler o capítulo 31 e 32 que é feito um pente fino, outro capítulo muito importante é o Capítulo 33 que aborda transações (Transactions) , e por fim os Capítulos 34 e 35 que abordam JNDI ENC e Conectores respectivamente..


Segue o link que pode ser baixado no site da Sun ou pode ser navegado online neste link: Tutorial Java EE 5.

Outro site muito importante para quem deseja tirar qualquer certificação é o JavaRanch, o link para SCBCD 5 é o http://faq.javaranch.com/java/ScbcdLinks#scbcd50


É isso aí, Boa Sorte e com todo esse material, com certeza a diversão é garantida !!!!