De JEE 5 para JEE 6 Como modificar uma aplicação para usar os novos recursos



Documentos relacionados
Java para Desenvolvimento Web

Como criar um EJB. Criando um projeto EJB com um cliente WEB no Eclipse

Introdução. <facelets> Templates. Configurações. Componentes. Prof. Enzo Seraphim

Java para WEB. Servlets

Fundamentos da Plataforma Java EE. Prof. Fellipe Aleixo

Aula 03 - Projeto Java Web

PadrãoIX. Módulo II JAVA. Marcio de Carvalho Victorino. Servlets A,L,F,M

Universidade da Beira Interior

Arquitetura de Aplicações JSP/Web. Padrão Arquitetural MVC

Parte I. Demoiselle Mail

DOCUMENTAÇÃO DO FRAMEWORK - versão 2.0

EJB ainda tem vez no Java EE 6? Fernando Lozano Consultor 4Linux

Programação II Programação para a Web. Christopher Burrows

Desenvolvendo Websites com PHP

Tencologia em Análise e Desenvolvimento de Sistemas Disciplina: WEB I Conteúdo: WEB Container Aula 04

UFG - Instituto de Informática

Desenvolvimento de aplicação web com framework JavaServer Faces e Hibernate

Prof. Roberto Desenvolvimento Web Avançado

1 Criar uma entity a partir de uma web application que usa a Framework JavaServer Faces (JSF)

Aplicativos JavaEE 6 modularizados com Web Fragments

Como sobreviver com Java 2? Saulo Arruda

Arquiteturas de Aplicações Web. Leonardo Gresta Paulino Murta

Aula 4. Objetivos. Conteúdo dinâmico na internet.

DWR DIRECTED WEB REMOTING

Prática da Disciplina de Sistemas Distribuídos Serviços Web IFMA DAI Professor Mauro Lopes C. Silva

Autenticação e Autorização

Acessando um Banco de Dados

INTRODUÇÃO À TECNOLOGIA SERVLETS

Prática Sobre Servlets e JSP

Demoiselle Report Guide. Demoiselle Report. Marlon Carvalho. Rodrigo Hjort. Robson Ximenes

J550 Segurança e Controle de erros

WebWork 2. João Carlos Pinheiro.

Java na WEB Servlet. Sumário

Manipulação de Banco de Dados com Java. Ms. Bruno Crestani Calegaro Maio/ 2015

ENTERPRISE JAVABEANS 3. Msc. Daniele Carvalho Oliveira

Use a Cabeça! FREEMAN, Eric e Elisabeth. HTML com CSS e XHTML BASHMAN, Brian / SIERRA Kathy / BATES, Bert. Servlets & JSP

ABORDAGEM DE FRAMEWORKS PARA JSF QUE AUXILIAM O DESENVOLVIMENTO DE SOFTWARE

TUTORIAL SPRING SECURITY PROGRAMAÇÃO COM FRAMEWORKS Responsáveis: Ana Luíza Cruvinel, Maikon Franczak e Wendel Borges

Criando e Entendendo o Primeiro Servlet Por: Raphaela Galhardo Fernandes

Tutorial. Começando a Criar Aplicativos SMS

Arquitetura de uma Webapp

Como já foi muito bem detalhado no Capítulo IV, o jcompany Developer Suite pode ser

DESENVOLVENDO APLICAÇÃO UTILIZANDO JAVA SERVER FACES

PROGRAMAÇÃO SERVIDOR PADRÕES MVC E DAO EM SISTEMAS WEB. Prof. Dr. Daniel Caetano

Associação Carioca de Ensino Superior Centro Universitário Carioca

Java II. Sérgio Luiz Ruivace Cerqueira

PROJETO PEDAGÓGICO DE CURSOS

Scriptlets e Formulários

Curso de Aprendizado Industrial Desenvolvedor WEB

Enterprise Java Beans

TDC2012. EJB simples e descomplicado, na prática. Slide 1

Está apto a utilizar o sistema, o usuário que tenha conhecimentos básicos de informática e navegação na internet.

FACULDADE DE TECNOLOGIA SENAC GOIÁS CONTROLE DE ACESSO USANDO O FRAMEWORK RICHFACES. 5º PERÍODO Gestão da Tecnologia da Informação

Dicas para usar melhor o Word 2007

Aplicação Prática de Lua para Web

SISTEMA DE AGENDAMENTO E GERENCIAMENTO DE CONSULTAS CLÍNICAS

1. Introdução pág.3 2. Apresentação do sistema Joomla! pág.4 3. Acessando a administração do site pág.4 4. Artigos 4.1. Criando um Artigo 4.2.

Satélite. Manual de instalação e configuração. CENPECT Informática cenpect@cenpect.com.br

Esse manual é um conjunto de perguntas e respostas para usuários(as) do Joomla! 1.5.

ArpPrintServer. Sistema de Gerenciamento de Impressão By Netsource Rev: 02

Programando em PHP. Conceitos Básicos

MANUAL DE INSTALAÇÃO E CONFIGURAÇÃO. Motor Periférico Versão 8.0

Figura 1. A Classe Java

JSP: JAVA SERVER PAGES

JavaServer Faces (JSF) Leonardo Murta

!" # # # $ %!" " & ' ( 2

Mini-Tutorial. Como criar relatórios Java para Web com JasperReports e ireport por Roberto J. Furutani 20/07/2005

Uma Abordagem sobre Mapeamento Objeto Relacional com Hibernate

Integração de sistemas utilizando Web Services do tipo REST

Unidade 8: Padrão MVC e DAO Prof. Daniel Caetano

Introdução a Banco de Dados

UFG - Instituto de Informática

Tutorial para criação de componentes JSF Facelets Por Érico GR 07/08/2007


Orientação a Objetos

02 - Usando o SiteMaster - Informações importantes

Tutorial Módulo 01 Arquitetura Anexo I. Tutorial Módulo 01 Arquitetura Anexo I. LABORATÓRIO 01 Arquitetura e Configuração

Linguagem de Programação JAVA. Professora Michelle Nery Nomeclaturas

Procedimentos para Reinstalação do Sisloc

TUTORIAL SISTEMA DE CONTROLE DE ACESSO

Programação Web. Professor: Diego Oliveira. Conteúdo 02: JSP e Servlets

Curso de Java. Geração de Páginas WEB. TodososdireitosreservadosKlais

JSP: JAVA SERVER PAGES

Prototype, um Design Patterns de Criação

OneDrive: saiba como usar a nuvem da Microsoft

J2EE. Exemplo completo Utilização Servlet. Instrutor HEngholmJr

SISTEMA DE WORKFLOW PARA MODELAGEM E EXECUÇÃO DE PROCESSOS DE SOFTWARE. Aluno: Roberto Reinert Orientador: Everaldo A. Grahl

Material de apoio a aulas de Desenvolvimento Web. Tutorial Java WEB JSP & HTML & CSS & CLASSE & OBJETOS. AAS -

Despachante Express - Software para o despachante documentalista veicular DESPACHANTE EXPRESS MANUAL DO USUÁRIO VERSÃO 1.1

Manual do Painel Administrativo

Artigo JavaMagazine (edição 58)

HTML5. Prof. Salustiano Rodrigues de Oliveira

Sistemas Distribuídos na WEB (Plataformas para Aplicações Distribuídas) Sumário. Java 2 Enterprise Edition. J2EE (Java 2 Enterprise Edition)

Portal da Prefeitura de São Paulo SECOM. MANUAL DO WARAM v. 1.5 Secretarias

Manual do Usuário Android Neocontrol

Módulo 5 JPATransaction Camadas Turma Turma TurmaBC TurmaBC TurmaBC TurmaBC

MANUAL DE UTILIZAÇÃO

Transcrição:

1/36 De JEE 5 para JEE 6 Como modificar uma aplicação para usar os novos recursos Descubra como converter uma aplicação que usa JSF, Servlets, EJBs e JPA para a nova versão e como fica a utilização de cada um desses recursos MARCELO ELIAS DEL VALLE Esse artigo ensina como migrar, passo a passo, uma aplicação Java EE 5 para Java EE 6. A aplicação utilizou JSF para criar a interface gráfica, EJBs para a conversão e JPA para ler dados de um banco de dados. Primeiramente é apresentada a parte funcional da aplicação. Em seguida, as diferenças entre as duas versões da aplicação (Java EE 5 e Java EE 6) são descritas sob várias perspectivas, por meio de diagramas de classes, de componentes e através da listagem de arquivos de cada versão. Depois disso é explicado como migrar cada camada. São mostradas as diferenças nos descritores de arquivo, na implementação dos EJBs e na chamada aos mesmos. Também é mostrado como fica o layout dos arquivos JSF com o uso de JSPs e com o uso de facelets, como fica o acesso a dados e o que muda na implementação de um Servlet. Durante todo esse processo são citadas muitas das novas características da especificação Java EE 6, como templates JSF, Criteria API, novidades no CDI, EJBs sem interface, EJBs instalados dentro de um WAR ao invés de em um EAR, servlets assíncronos e web-fragments. A especificação Java EE versão 6 trouxe muitas novidades com relação às versões anteriores e pode ser considerada uma quebra de paradigma. Finalmente, é possível desenvolver com Java EE sem uma necessidade tão grande de recorrer a frameworks de terceiros. Ficou muito mais simples desenvolver e chamar EJBs, nunca foi tão fácil organizar a parte visual da aplicação graças ao uso de templates, facelets agora é a tecnologia visual padrão, substituindo o JSP, o acesso a dados ficou menos acoplado ainda com o banco de dados graças à Criteria API e o uso de servlets assíncronas permite realizar Server Push usando apenas as ferramentas oferecidas por padrão no Java EE 6. Esse artigo fala sobre tudo isso. Funcionalmente, nada muda na aplicação da versão Java EE 5 para a versão 6, as únicas diferenças ficam na implementação. Ferramentas utilizadas O exemplo citado no artigo roda no GlassFish, mas com pode rodar em qualquer Application Server com poucas adaptações. Recomenda-se usar o Glassfish v2 para rodar a aplicação Java EE 5 e o Glassfish v3 para rodar a aplicação Java EE 6. O GlassFish é a implementação de referência da Sun (agora Oracle) para o Java EE e portanto é recomendado para o aprendizado, mas vários outros containers implementam a especificação Java EE da forma como mostrado nesse artigo, como é o caso do JBoss, da Red Hat, e do WebSphere, da IBM. As duas versões da aplicação (tanto na versão Java EE 5 quanto na versão Java EE 6), assim como a versão desse artigo em PDF, estão disponíveis para download NESSE LINK e a mesma utiliza ANT para o build e contém um arquivo de projeto para o IDE Eclipse. Contudo, é possível rodar a mesma aplicação em qualquer IDE sem necessidade de modificações no código. A aplicação faz uso de um banco de dados, acessado em tempo de execução. Nesse banco precisa existir a tabela Taxa, cujos campos são descritos mais abaixo. Os exemplos desse artigo foram testados no MySQL. Tudo o que você precisa fazer é criar o banco de dados, criar a tabela Taxa no mesmo e configurar um datasource no seu container. Um datasource é um recurso do container que permite que as configurações de banco específicas para o ambiente fiquem configuradas no mesmo e não na aplicação. Para obter uma conexão JDBC

2/36 com o banco basta dizer ao container qual é o JNDI do datasource configurado e o ele se preocupa em como criar as conexões e fechá-las, conforme necessário. O conceito de datasource já é bem conhecido pela maioria dos programadores e, como não faz parte do foco do artigo, não será explicado em detalhes como configurá-lo. No Glassfish, para criar um data source é necessário configurar um connection pool antes, no qual são especificados os dados de conexão com o banco de dados. Depois de criado o Connection Pool especificando tipo de banco e dados de conexão, deve ser cadastrado o DataSource associando o Pool com o JNDI utilizado pela aplicação: jdbc/conversords. Outro recurso utilizado foi o Realm, para autenticação. Para rodar as aplicações, é necessário cadastrar um Realm no Container com informações de usuários, grupos e senhas usados para autenticação. Será mostrado no artigo, sucintamente, como fazer isso em ambas as versões do Glassfish, mas é um recurso largamente utilizado e programadores não deveriam sentir dificuldade de realizar essa tarefa. Para rodar a aplicação, adicione no Glassfish um usuário admin com senha admin e na opção Group List insira o texto administrator, para que o usuário seja adicionado a esse grupo. Adicione o usuário no file realm (Configuration> Security> Realms> file). Descrevendo a parte funcional da aplicação A aplicação descrita nesse artigo é bem simples do ponto de vista funcional: uma aplicação que converte um valor em reais para um valor em dólares através de uma interface gráfica e de dólares para reais através de um servlet. A taxa de conversão de cada moeda é obtida a partir do banco de dados e há também interface de usuário para consultar as taxas no banco, alterar, apagar e adicionar novas taxas. Todas as telas necessitam de login para serem acessadas, então há também uma tela de login na aplicação. Na figura 1, é mostrada a tela de login e na figura 2, a tela de conversão de unidades quando a mesma é iniciada. Na figura 3, vemos a mesma tela, depois de o usuário digitar um valor em reais e o mesmo ser exibido em dólares.

3/36 Figura 1. Tela de Login Figura 2. Tela de conversão, ao iniciar Figura 3. Tela de conversão, após clicar no botão converter

4/36 Ao tentar entrar na aplicação (http://localhost:8080/jee5app ou http://localhost:8080/jee6app, assumindo que você está usando o glassfish com a porta padrão configurada: 8080), é exibida a tela de login. Uma vez logado no sistema, o usuário é redirecionado para a tela exibida na figura 2. A página JSF exibida na figura 2 tem o seguinte comportamento: quando o usuário clica no botão submit, o JSF chama um ManagedBean, que aciona um EJB do tipo SessionBean. O EJB usa um EntityBean mapeado via JPA para acessar os dados da tabela. O mesmo acontece para as telas exibidas nas figuras 4, 5 e 6. Todas elas chamam um ManagedBean, que por sua vez chama um EJB session que usa JPA para acessar o banco. A tela mostrada na figura 4 exibe a lista de moedas cadastradas e permite, para cada moeda, editá-la ou apagá-la. Ao clicar no X, a moeda é simplesmente apagada e a lista é recarregada. Ao clicar no E para editá-la, é exibida a figura 6, permitindo a alteração da moeda. Clicando no menu Adicionar Nova Moeda o usuário é levado para a figura 5, que permite que o mesmo efetue a adição. Figura 4. Lista de moedas cadastradas

5/36 Figura 5. Adicionar nova moeda Figura 6. Alterar moeda A figura 7 mostra o retorno de um servlet, que quando chamado aciona um EJB para converter um valor em dólares para Real e retorna um XML com o valor original e o valor em reais.

6/36 Figura 7. XML retornado pela chamada ao servlet A aplicação lê as taxas de conversão de uma tabela em um banco de dados. A figura 8 mostra dados de exemplo para a tabela TAXA, que deve estar disponível no banco de dados. Essa tabela o valor, em reais, da unidade de cada moeda. Na figura, vemos que um dólar, por exemplo, custa R$ 1,70 e um Iene (moeda do Japão, MOEDA = JPY) custa R$ 0,0202631. Figura 8. Taxas de conversão de outras moedas para Real Visão de classes Antes de entrarmos nos detalhes da migração da aplicação, cabe fornecer uma visão geral das classes em cada aplicação. As figuras 9 e 10 mostram como ficam as classes da aplicação com JAVA EE 5 e com JAVA EE 6, respectivamente. Perceba que na versão nova não são usadas interfaces EJB, sendo o bean injetado diretamente nas classes ConversorMoedaCliente e MoedaCliente, que são managed beans usados pela página JSF que, assim como o servlet, acessam um EJB para converter uma quantia em reais para uma quantia em dólares. Esses ManagedBeans existem nas duas versões da aplicação, o que muda é sua implementação e a forma de injetar o EJB, como veremos nas próximas seções. Managed Beans Managed Beans, ou beans gerenciados pelo container, é um conceito da especificação JAVA EE usado, sobretudo, em aplicações JSF. O conceito de managed bean é bem simples, são classes Java acessíveis por facelets que normalmente fazem a ponte entre a parte visual e a parte de negócio. O facelet, que no JAVA EE 6 substitui o JSP como tecnologia padrão para a camada visual, por boa prática deve conter somente a parte visual da aplicação, delegando para os managed beans a parte de lógica de apresentação. Os managed beans, por sua vez, devem conter somente a lógica de apresentação, delegando a parte de negócio para classes específicas de negócio ou, como é o caso dessa aplicação, para EJBs. Os facelets acessam os managed beans através de expressões EL (Expression Language), que nada mais são além de expressões misturadas no HTML delimitadas por #{... A listagem 14, por exemplo, exibe um facelet que acessa um managed bean através da expressão #{conversormoedacliente.valorconvertido.

7/36 O conceito de managed beans e EL deve ser bem conhecido também pela maioria nos leitores, então nesse artigo é feito apenas um comparativo entre as diferenças entre a versão JAVA EE 5 e JAVA EE 6. class App Jee 5 web Serv let home.jsp JEE5Serv let ejb lista.jsp «ManagedBean» Conv ersormoedacliente «interface» ConversorMoeda «EJB» Conv ersormoedabean - moedadest: String - moedaori: String - valorconvertido: Double - valororiginal: Double + converter(double, String, String) : Double «EJB» MoedaBean editar.jsp «ManagedBean» MoedaCliente «interface» Moeda + adicionar(taxa) : void + alterar(taxa) : void + apagar(integer) : void + encontrar(integer) : void adicionar.jsp - id: Integer - moeda: String - taxa: Double modelo «EJB Entity» Taxa login.jsp - id: Integer - moeda: String - taxa: Double Figura 9. Classes na aplicação JAVA EE 5

8/36 class App Jee 6 web Serv let home.xhtml JEE6Serv let lista.xhtml «ManagedBean» Conv ersormoedacliente - moedadest: String - moedaori: String - valorconvertido: Double - valororiginal: Double ejb «EJB» Conv ersormoedabean editar.xhtml adicionar.xhtml «ManagedBean» MoedaCliente - id: Integer - moeda: String - taxa: Double + converter(double, String, String) : Double «EJB» MoedaBean + adicionar(taxa) : void + alterar(taxa) : void + apagar(integer) : void + encontrar(integer) : void modelo login.xhtml «EJB Entity» Taxa - id: Integer - moeda: String - taxa: Double Figura 10. Classes na aplicação JAVA EE 6 Visão de pacotes Uma das diferenças entre as especificações JAVA EE 5 e JAVA EE 6 é o fato de que agora é possível colocar EJBs dentro do WAR diretamente, sem a necessidade de um EAR. A Figura 11 mostra como seria a visão de pacotes nas duas versões da aplicação e ilustra essa diferença do JAVA EE.

9/36 Figura 11. Diferença entre JAVA EE 5 e JAVA EE 6 com relação a pacotes Numa aplicação tradicional JAVA EE 5, contendo tanto classes web como EJB, é necessário criar no mínimo 2 pacotes para fazer deploy da aplicação: um arquivo WAR (Web ARchive) contendo as classes web, e um jar contendo os EJBs. Além desses dois, é comum empacotarmos ambos os pacotes dentro de um EAR (Enterprise Application Archive), para não precisarmos fazer o deploy do WAR e do EJB-JAR separadamente, garantindo que a versão do WAR é sempre compatível com a versão do EJB-JAR. Embora esse esquema de empacotamento possa ser interessante para aplicações realmente grandes, onde queremos fazer deploy de apenas parte da aplicação em um servidor e parte da aplicação em outro, para a grande maioria das aplicações é um grande transtorno, pelo fato de ser difícil empacotar a aplicação dessa forma. A dificuldade se deve principalmente ao fato de existirem classes na aplicação que devem ficar acessíveis tanto pela camada web quanto pela camada EJB, como é o caso das interfaces dos EJBs, das classes de domínio ou dos TOs (Transfer Objects). Como existe uma parte comum tanto para a camada web quanto para a camada de negócio, tornase complicado fazer o deploy de uma aplicação completa com JAVA EE 5. É necessário colocar as bibliotecas dentro do EAR e referenciar tanto no EJB-JAR quanto no WAR ou, então, colocar as mesmas classes compiladas tanto no EJB-JAR quando no WAR, como foi feito no exemplo desse artigo. Com JAVA EE 6 esse problema não existe, pois todas as classes de todas as camadas ficam no WEB-INF/classes, tornando tudo acessível para todos. Na figura 7 também não aparece a parte com as interfaces EJBs, pelo fato delas não existirem mais no JAVA EE 6, como veremos mais adiante. Visão de arquivos A listagem 1 mostra o local de cada arquivo da aplicação JAVA EE 5 dentro dos pacotes gerados, ou seja, qual o caminho de cada arquivo dentro EAR, do WAR e do EJB-JAR. A listagem 2 mostra

10/36 a mesma visão para a aplicação JAVA EE 6, mostrando somente os caminhos dentro do WAR, já que a aplicação migrada não tem EAR nem EJB-JAR. Cuidado para não confundir a visão de componentes com a visão dos arquivos dentro do IDE. Independente de como os arquivos ficam no seu ambiente de desenvolvimento, o que importa para o container JAVA EE quando você faz deploy é como os arquivos estão dispostos dentro dos pacotes, que é o que é mostrado nas listagens 1 e 2. Listagem 1. Arquivos em cada componente JAVA EE 5 EAR (Java EE 5app.ear): /Java EE 5app-ejb.jar /Java EE 5app.war /META-INF/application.xml /META-INF/MANIFEST.MF EJB-JAR (Java EE 5app-ejb.jar): /br/com/human/ejb/conversormoeda.class /br/com/human/ejb/conversormoedabean.class /br/com/human/ejb/moeda.class /br/com/human/ejb/moedabean.class /br/com/human/modelo/taxa.class /META-INF/MANIFEST.MF /META-INF/persistence.xml WAR (Java EE 5app.war): /default.css /style.css /adicionar.jsp /editar.jsp /error.jsp /footer.jsp /header.jsp /home.jsp /lista.jsp /login.jsp /menu.jsp /META-INF/MANIFEST.MF /WEB-INF/classes/br/com/human/ejb/ConversorMoeda.class /WEB-INF/classes/br/com/human/ejb/Moeda.class /WEB-INF/classes/br/com/human/modelo/Taxa.class /WEB-INF/classes/br/com/human/servlet/JAVA EE 5Servlet.class /WEB-INF/classes/br/com/human/web/ApplicationMessages.properties /WEB-INF/classes/br/com/human/web/ConversorMoedaCliente.class /WEB-INF/classes/br/com/human/web/MoedaCliente.class /WEB-INF/faces-config.xml /WEB-INF/lib /WEB-INF/web.xml /WEB-INF/sun-web.xml Listagem 2. Arquivos em cada componente JAVA EE 6 WAR (Java EE 5app.war): /default.css /style.css /adicionar.xhtml /editar.xhtml /error.xhtml /home.xhtml /lista.xhtml /login.xhtml /menu.xhtml /META-INF/MANIFEST.MF /WEB-INF/classes/br/com/human/ejb/ConversorMoedaBean.class /WEB-INF/classes/br/com/human/ejb/MoedaBean.class /WEB-INF/classes/br/com/human/modelo/Taxa.class /WEB-INF/classes/br/com/human/servlet/JAVA EE 6Servlet.class /WEB-INF/classes/br/com/human/web/ApplicationMessages.properties /WEB-INF/classes/br/com/human/web/ConversorMoedaCliente.class /WEB-INF/classes/br/com/human/web/MoedaCliente.class /WEB-INF/classes/META-INF/persistence.xml /WEB-INF/faces-config.xml /WEB-INF/lib /WEB-INF/web.xml

11/36 Na listagem 1, percebemos que as interfaces Moeda, ConversorMoeda e a classe Taxa ficam acessíveis tanto do EJB-JAR quanto do arquivo WAR. Note como fica mais simples na listagem 2, com JAVA EE 6. O arquivo persistence.xml, exibido na listagem 4, faz parte da especificação JPA e é usado para mapear as classes de entidade e para definir o data source usado para acessar o banco que contem a tabela correspondente à entidade. Em nosso exemplo, mapeamos a classe Taxa, nosso Entity Bean. Na versão nova (listagem 2) esse arquivo não fica mais em META-INF/persistence.xml, mas sim em /WEB-INF/classes/META-INF/, que é o local padrão para se colocar esse arquivo agora que é possível colocar EntityBeans dentro do WAR. Perceba que a classe Taxa também foi movida para dentro do WAR. O arquivo web.xml foi utilizado para configurar de forma fácil a servlet do JSF, mas não fosse por isso poderia ser omitido do WAR (ao menos segundo a especificação, embora alguns containers ainda exijam), pois a maioria das configurações agora podem ser feitas por anotações, como veremos. Migração da aplicação Teoricamente, existe backward compatibility da versão 6 para a versão 5, ou seja, tudo o que é possível fazer com JAVA EE 5 fica igual no JAVA EE 6. E então, se você tem uma aplicação desenvolvida em JAVA EE 5 poderia facilmente fazer deploy do EAR já desenvolvido num container novo, como o glassfish 3, sem precisar migrar nada. Por que migrar então? Um dos motivos é que a aplicação ficará muito mais simples de ser mantida, pois a maioria dos recursos adicionais do JAVA EE 6 facilita muito o dia a dia na hora de manter o código e diminui consideravelmente o número de arquivos necessários. Além disso, converter o código de uma aplicação é um excelente modo de se atualizar para a versão nova, já que vamos focar exatamente nas diferenças de uma versão para a outra do JAVA EE. Na prática, para projetos reais, pode ou não valer a pena migrar suas aplicações para a versão 6 da especificação JAVA EE. Espera-se que esse artigo contribua para dar ao leitor uma visão melhor das vantagens da nova versão, para que ele mesmo possa decidir se é interessante ou não migrar seus projetos. Se estiver criando aplicações a partir do zero, contudo, com certeza será uma boa idéia já usar a versão nova, a não ser que existam limitações externas, como impossibilidade de rodar um container que a suporte, como o glassfish 3. Nas seções a seguir, vamos migrar cada feature da aplicação JAVA EE 5 para utilizar os novos recursos da versão 6. Convertendo os EJBs O Entity Bean é sem dúvida a parte que menos muda, se você já estiver usando EJB 3. A classe taxa mostrada na listagem 3 é exatamente a mesma para as duas versões da aplicação. Basicamente é utilizada a anotação javax.persistence.entity para definir o bean como uma entidade e javax.persistence.id para denotar o campo correspondente ao ID. Nessa aplicação de exemplo, a camada web chama um EJB session Bean que consulta os dados utilizando esse EntityBean Taxa e retorna instâncias dessa mesma classe para a web. Embora isso funcione e esteja correto para esse caso simples, aplicações maiores deveriam transferir dados para a web através de TOs, usando os EntityBeans somente para realizar consultas no banco. Além disso, ao invés de realizar consultas diretamente do EJB Session Bean, seria interessante usar um pattern de acesso a dados, como DAO ou Active Record. Essas decisões, contudo, fazem parte da definição da arquitetura específica de cada aplicação, não havendo uma melhor forma de fazer universal. Por esse motivo, no artigo a aplicação de exemplo limitou-se a fazer apenas o necessário. Listagem 3. EntityBean Taxa.java package br.com.human.modelo;

12/36 import javax.persistence.entity; import javax.persistence.id; @Entity public class Taxa { @Id private Integer id; private String moeda; private Double taxa; public Integer getid() { return id; public void setid(integer id) { this.id = id; public String getmoeda() { return moeda; public void setmoeda(string moeda) { this.moeda = moeda; public Double gettaxa() { return taxa; public void settaxa(double taxa) { this.taxa = taxa; A configuração da persistence unit também é bem fácil e não teve mudanças. O XML de configuração é mostrado na listagem 4. Note que esse arquivo deve ficar em um local diferente dentro do pacote, conforme mostrado na seção Visão de Pacotes. Listagem 4. Unidade de persistência persistence.xml <?xml version='1.0' encoding='utf-8'?> <persistence> <persistence-unit name="conversords"> <description>unidade de persistência para acessar a tabela de moedas </description> <jta-data-source>jdbc/conversords</jta-data-source> <class>br.com.human.modelo.taxa</class> </persistence-unit> </persistence> Com relação ao EJB Session Bean, houve uma grande mudança na versão 6 do JAVA EE, que é a inexistência de interfaces. As listagens 5 e 6 mostram a versão JAVA EE 5 e a listagem 7 mostra a versão JAVA EE 6. A listagem 5 mostra a interface do Session Bean, que era incluída pelo ManagedBean ConversorMoedaCliente, exibido na listagem 18. Essa interface só existe na versão JAVA EE 5.

13/36 Na listagem 6, o EJB ConversorMoedaBean herda de ConversorMoeda, o que não acontece mais na versão nova, mostrada na listagem 7. Perceba também que na listagem 19, que mostra o ConversorMoedaCliente na versão JAVA EE 6, o EJB é injetado diretamente, não mais sua interface. Essa acabou sendo uma das grandes vantagens da nova versão do JAVA EE, já que o motivo de existir uma interface seria tornar possível ter várias implementações de um mesmo EJB em seu código, com o mesmo contrato. Na versão antiga isso nunca era utilizado e pelo fato do Session Bean ter virado um simples POJO, fica bem mais fácil usar os mecanismos de orientação a objeto da própria linguagem Java, ao mesmo tempo em que não deixamos de ter todas as vantagens do uso de EJBs, como capacidade de rodar em cluster e ser gerenciado pelo container. Comparando as implementações do EJB (listagens 6 e 7), podemos perceber uma diferença na forma de busca os dados, já que na versão JAVA EE 5 (listagem 6) é utilizado Query Language e na versão JAVA EE 6 (listagem 7) é utilizada a API de Criteria. Listagem 5. Interface EJB ConversorMoedaBean - versão JAVA EE 5 package br.com.human.ejb; import java.util.list; import javax.ejb.remote; import br.com.human.modelo.taxa; @Remote public interface ConversorMoeda { public Double converter(string moedaori, String moedadest, Double valorori); public List<Taxa> getlistataxas(); Listagem 6. Implementação EJB ConversorMoedaBean - versão JAVA EE 5 package br.com.human.ejb; import java.util.list; import javax.ejb.stateless; import javax.persistence.entitymanager; import javax.persistence.persistencecontext; import br.com.human.modelo.taxa; @Stateless public class ConversorMoedaBean implements ConversorMoeda { @PersistenceContext EntityManager em; public Double converter(string moedaori, String moedadest, Double valorori) { Double taxamoedaori, taxamoedadest; taxamoedaori = gettaxamoeda(moedaori); taxamoedadest = gettaxamoeda(moedadest); Double result = valorori * (taxamoedaori / taxamoedadest); return result;

14/36 @SuppressWarnings("unchecked") public Double gettaxamoeda(string moeda) { Double taxamoeda = 1.0; List<Taxa> resultado = em.createquery("select t FROM Taxa t WHERE t.moeda =?1").setParameter(1, moeda).getresultlist(); Taxa m = resultado.get(0); taxamoeda = m.gettaxa(); return taxamoeda; @SuppressWarnings("unchecked") public List<Taxa> getlistataxas() { return em.createquery("select t FROM Taxa t").getresultlist(); Listagem 7. Implementação EJB ConversorMoedaBean - versão JAVA EE 6 package br.com.human.ejb; import java.util.list; import javax.ejb.stateless; import javax.persistence.entitymanager; import javax.persistence.persistencecontext; import javax.persistence.typedquery; import javax.persistence.criteria.criteriabuilder; import javax.persistence.criteria.criteriaquery; import javax.persistence.criteria.predicate; import javax.persistence.criteria.root; import br.com.human.modelo.taxa; @Stateless public class ConversorMoedaBean { @PersistenceContext EntityManager em; public Double converter(string moedaori, String moedadest, Double valorori) { Double taxamoedaori, taxamoedadest; taxamoedaori = gettaxamoeda(moedaori); taxamoedadest = gettaxamoeda(moedadest); Double result = valorori * (taxamoedaori / taxamoedadest); return result; public Double gettaxamoeda(string moeda) { Double taxamoeda = 1.0; moeda); CriteriaBuilder criteriabuilder = em.getcriteriabuilder(); CriteriaQuery<Taxa> criteriaquery = criteriabuilder.createquery(taxa.class); Root<Taxa> taxa = criteriaquery.from(taxa.class); Predicate condition = criteriabuilder.equal(taxa.get("moeda"), criteriaquery.where(condition); TypedQuery<Taxa> typedquery = em.createquery(criteriaquery); List<Taxa> resultado = typedquery.getresultlist(); Taxa m = resultado.get(0); taxamoeda = m.gettaxa();

15/36 return taxamoeda; public List<Taxa> getlistataxas() { CriteriaBuilder criteriabuilder = em.getcriteriabuilder(); CriteriaQuery<Taxa> criteriaquery = criteriabuilder.createquery(taxa.class); TypedQuery<Taxa> typedquery = em.createquery(criteriaquery); List<Taxa> resultado = typedquery.getresultlist(); return resultado; Criteria API Quem está acostumado com o Hibernate deve conhecer de longa sua API de Criteria Queries. Esse foi um feature tão largamente usado por desenvolvedores que acabou entrando para a própria especificação JAVA EE nessa versão 6, embora existam rumores de que será melhorada ainda mais nas novas versões e que não tenha ficado tão boa quanto a original, do Hibernate. A vantagem é poder usá-la com qualquer implementação JPA e não só com o Hibernate, o que pode ser crítico dependendo do container sendo utilizado. Basicamente, a idéia de uma API desse tipo é poder realizar consultas no banco sem qualquer uso de uma linguagem de consulta, deixando as regras de negócio todas no código e eliminando completamente a dependência do banco de dados sendo utilizado. Uma grande vantagem que esse approach representa é o fato de o compilador lançar erro caso algo esteja errado na query, coisa que não aconteceria caso fosse usada uma string com QL. Utilizando a factory CriteriaBuilder, é possível criar uma query para uma classe considerada a raiz da busca. Com o objeto de definição de consulta criado, é possível compor uma série de critérios a partir dessa raiz da busca, tornando-a cada vez mais específica para aquilo que se deseja encontrar. Por exemplo, poderíamos adicionar para a raiz da busca definições de predicados (que corresponderiam à cláusula WHERE de um SQL), ordenações, agrupamentos, subqueries, joins, etc. Convertendo os descritores de deploy Um dos principais motivos de se querer converter uma aplicação JAVA EE 5 para a versão 6 é que na versão nova quase não é necessário escrever XML. Muito do que se configurava através de arquivos de configuração XML agora é configurado via anotações. Por exemplo, não é mais necessário declarar os servlets no web.xml. A listagem 8 mostra o web.xml versão JAVA EE 5 e a listagem 9 mostra a versão 6. Listagem 8. web.xml da aplicação JAVA EE 5 <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- Faces Servlet --> <servlet> <servlet-name>facesservlet</servlet-name> <servlet-class>javax.faces.webapp.facesservlet</servlet-class>

16/36 <load-on-startup>1</load-on-startup> </servlet> <!-- Java EE 5 Servlet --> <servlet> <servlet-name>java EE 5Servlet</servlet-name> <servlet-class>br.com.human.servlet.java EE 5Servlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <!-- Faces Servlet Mapping --> <servlet-mapping> <servlet-name>facesservlet</servlet-name> <url-pattern>/java EE 5/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>java EE 5Servlet</servlet-name> <url-pattern>/java EE 5servlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>java EE 5/home.jsp</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>administrativo</web-resource-name> <!-- The URLs to protect --> <url-pattern>*.jsp</url-pattern> </web-resource-collection> <auth-constraint> <!-- The authorized users --> <role-name>administrador</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>form</auth-method> <realm-name>file</realm-name> <form-login-config> <form-login-page>/java EE 5/login.jsp</form-login-page> <form-error-page>/java EE 5/error.jsp</form-error-page> </form-login-config> </login-config> <security-role> <role-name>administrador</role-name> </security-role> </web-app> Listagem 9. JAVA EE 6 web.xml <?xml version="1.0" encoding="utf-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <servlet> <servlet-name>faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.facesservlet</servlet-class> <load-on-startup>1</load-on-startup>

17/36 </servlet> <servlet-mapping> <servlet-name>faces Servlet</servlet-name> <url-pattern>/java EE 6/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>java EE 6/home.xhtml</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>administrativo</web-resource-name> <!-- The URLs to protect --> <url-pattern>*.xhtml</url-pattern> </web-resource-collection> <auth-constraint> <!-- The authorized users --> <role-name>administrador</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>form</auth-method> <realm-name>file</realm-name> <form-login-config> <form-login-page>/java EE 6/login.xhtml</form-login-page> <form-error-page>/java EE 6/error.xhtml</form-error-page> </form-login-config> </login-config> <security-role> <role-name>administrador</role-name> </security-role> </web-app> Como é possível notar, o servlet do faces continua sendo declarado. Em alguns containers existe como não realizar essa configuração, pois ela é feita no próprio framework, ou seja, não é necessário declarar o servlet do faces no web.xml pois o próprio jar do framework já contem um arquivo web-fragment.xml (veja quadro) que especifica o mapeamento de URL da servlet. Na implementação de referência do JSF ela ainda ficou como necessária e, se não fosse por isso, não precisaríamos de um web.xml na aplicação. Se você experimentar rodar a aplicação versão JAVA EE 6 tirando o web.xml, perceberá que o servlet continuará rodando normalmente, só as páginas JSF que não. Web Fragments Embora não tenha sido usado nessa aplicação de exemplo, uma das principais novidades do JAVA EE 6 é a existência de web fragments. A listagem 10 exemplifica como seria um arquivo webfragment.xml de um framework, embora não seja usado na aplicação. Esse arquivo ficaria dentro da pasta META-INF de um jar incluído em WEB-INF/lib. Por exemplo, se você inclui na sua aplicação o framework.jar como uma lib, esse arquivo deveria ter uma pasta META-INF e dentro dela um arquivo web-fragment.xml como o da listagem 10. Dessa forma, o container ao carregar sua aplicação já entenderia que você incluiu um módulo web, que tem servlets a serem carregadas.

18/36 A idéia de web-fragments é tornar a configuração web modularizável, de forma que seja possível construir vários módulos web independentes, cada um com sua configuração, e integrá-los de forma fácil quando desejado. Não é mais preciso desenvolver os servlets em vários JARs separados e colocar a configuração na aplicação que os utiliza, os próprios módulos podem vir com sua configuração definida. Esse arquivo poderia definir outras configurações hoje existentes no web.xml, mas no exemplo é mostrado o mapeamento de um servlet. A tag servlet é semelhante à usada no web.xml, mas no lugar da servlet-mapping é definida uma classe listener que faz o mesmo papel, programaticamente. É possível usar tanto arquivos web.xml, quanto anotações e web-fragments, mas existe uma ordem de processamento, sendo que a configuração do web.xml se sobrepõe às outras, ou seja, se existe configuração de uma servlet no web.xml, a anotação dessa servlet será ignorada. Se essa servlet foi incluída a partir de um JAR externo com um web-fragment.xml, a configuração do jar também será ignorada se a servlet for mapeada pelo web.xml da aplicação. Isso permite sobrescrever as configurações do módulo incluído. Listagem 10. web-fragment.xml novo feature do JAVA EE 6 permite modularizar o web.xml <web-fragment> <servlet> <servlet-name>myframeworkservlet</servlet-name> <servlet-class>myframework.myframeworkservlet</servlet-class> </servlet> <listener> <listener-class>myframework.myframeworklistener</listener-class> </listener> </web-fragment> Observe novamente as listagens 8 e 9. Note que existe uma diferença crucial entre os arquivos de ambas as listagens que é a designação da versão, no início do arquivo. O arquivo da listagem 8 define a versão 2.3 do servlet, enquanto que o arquivo da listagem 9 define a versão 3 (atente para o elemento web-app, atributo version). Se essa versão não estivesse configurada corretamente, o container não leria os EJBs, que não eram permitidos dentro do war no JAVA EE 5, e ignoraria completamente possíveis arquivos webfragment e anotações de mapeamento dentro de servlets. Além disso, na listagem 9 não é mapeada a servlet da aplicação, pois ela é mapeada através de anotações, conforme mostrado na próxima seção. Convertendo a servlet As listagens 11 e 12 mostram, respectivamente, as versões da servlet para as plataformas JAVA EE 5 e 6. A implementação das servlets exibidas nas duas listagens não muda praticamente nada: ambas as classes servlet recebem um parâmetro dólares vindo da URL (método GET), e retornam um XML com o valor original em dólares e o valor convertido para reais. O XML é retornado através de prints para o objeto response. Verifique, além das duas listagens, o mapeamento da servlet da listagem 11, exibido na listagem 8. A servlet está mapeada para atender a URLs do tipo: http://localhost:8080/java EE 5app/Java EE 5servlet?dolares=23.0, onde Java EE 5app é o contexto da aplicação (o nome do EAR gerado, se você fizer deploy jogando o arquivo na pasta autodeploy do glassfish) e Java EE 5servlet é o mapeamento conforme configurado no web.xml. Uma das coisas que muda de uma versão para outra é o mapeamento. Na classe exibida na listagem 11, desenvolvida para a versão JAVA EE 5, não há nenhuma configuração de mapeamento, pois a mesma é realizada no web.xml. Na classe exibida na listagem 12, desenvolvida

19/36 para a versão JAVA EE 6, o mapeamento é feito através de uma anotação: @WebServlet("/Java EE 6servlet") Verifique agora a listagem 12. A servlet está mapeada para atender a URLs do tipo: http://localhost:8080/java EE 6app/Java EE 6servlet?dolares=23.0, onde Java EE 6app é o contexto da aplicação (o nome do WAR gerado, se você fizer deploy jogando o arquivo na pasta autodeploy do glassfish) e Java EE 6servlet é o mapeamento conforme configurado na anotação da classe. Outra mudança é a forma de acessar o EJB. Na listagem 11 é necessário criar uma intância do InitialContext e então obter a referência para o EJB via JNDI, ou seja, é necessário se preocupar no código da aplicação em quando instanciar a referência para o EJB. Na listagem 12, versão JAVA EE 6, o EJB é injetado no atributo conversor com a tag @EJB. O próprio container se preocupa em obter a referência para o EJB através dessa injeção de dependência, tornando a instanciação completamente transparente para quem está desenvolvendo a aplicação. Dentro do método service, o atributo conversor é simplesmente usado, sem necessidade da aplicação instanciá-lo. Listagem 11. JAVA EE 5Servlet package br.com.human.servlet; import java.io.ioexception; import java.io.printwriter; import javax.naming.initialcontext; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import br.com.human.ejb.conversormoeda; public class JAVA EE 5Servlet extends HttpServlet { private static final long serialversionuid = 5231367249531988910L; private ConversorMoeda conversor; public void service(httpservletrequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getwriter(); Double dolares = 100.00; dolares = Double.parseDouble(req.getParameter("dolares").toString()); double reais=0.0; try { InitialContext ic = new InitialContext(); conversor = (ConversorMoeda) ic.lookup(conversormoeda.class.getname()); reais = conversor.converter("usd", "BRL", dolares); conversor = null; catch (Exception ex) { ex.printstacktrace(); out.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"); out.println("<valor>"); out.print("\t<dolar>"); out.print(dolares); out.println("</dolar>"); out.print("\t<real>"); out.print(reais);

20/36 out.println("</real>"); out.println("</valor>"); Listagem 12. JAVA EE 6Servlet package br.com.human.servlet; import java.io.ioexception; import java.io.printwriter; import javax.ejb.ejb; import javax.servlet.servletexception; import javax.servlet.annotation.webservlet; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import br.com.human.ejb.conversormoedabean; @WebServlet("/Java EE 6servlet") public class JAVA EE 6Servlet extends HttpServlet { private static final long serialversionuid = 5231367249531988910L; @EJB private ConversorMoedaBean conversor; public void service(httpservletrequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getwriter(); Double dolares = 100.00; dolares = Double.parseDouble(req.getParameter("dolares").toString()); double reais = conversor.converter("usd", "BRL", dolares); out.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>"); out.println("<valor>"); out.print("\t<dolar>"); out.print(dolares); out.println("</dolar>"); out.print("\t<real>"); out.print(reais); out.println("</real>"); out.println("</valor>"); A annotation WebServlet exibida na listagem 12 aceitaria muito mais opções de mapeamento. Um outro exemplo de possibilidade é mostrado na listagem 13. Listagem 13. Exemplo fictício do uso da annotation WebServlet @WebServlet(name="Java EE 6servlet", asyncsupported=true, urlpatterns={"/jee6servlet", "/getval") O exemplo define mais de uma URL pattern, ou seja, poderíamos chamar essa servlet usando tanto um URL como http://localhost:8080/jee6app/jee6servlet?dolares=23.0 quanto http://localhost:8080/jee6app/getval?dolares=23.0.