A revolução do Java EE 6 Um overview sobre as novidades da JSR

Propaganda
artigo
Pedro Henrique S. Mariano
([email protected]) técnologo em
Análise e Desenvolvimento de Sofware pela FIAP,
possui as certificações SCJP 6 e SCRUM master
.Trabalha como consultor e desenvolvedor pela
Caelum com linguagem como Ruby e Java.
A revolução do
Java EE 6
Um overview sobre as novidades da JSR 316
Muito se fala sobre as novidades da nova
especificação Java EE 6, durante esses 3 anos
de desenvolvimento foram feitas várias drafts
(rascunhos) e só no dia 10 de dezembro de
2009 foi lançado oficialmente a especificação.
Este artigo abordará e comentará de uma
forma geral as novidades presentes no Java EE
6, que agora são oficiais!
30 www.mundoj.com.br
FQPJTEFNBJTEFBOPTEFFTQFSBOPEJBEFEF[FNCSPEF
foi lançada oficialmente a especificação enterprise da plataforma
+BWBP+BWB&&+43
&MBUFNDPNPPCKFUJWPQSPQPSDJPOBS
extensibilidade, simplicidade e principalmente right-sizing
(adaptação a diversos tamanhos de aplicações). Contando com grandes
conhecidos da comunidade como Gavin King, Bob Lee e Rod Johson, essa
nova especificação tem tudo para agradar aos desenvolvedores e melhorar a
imagem do Java EE perante à comunidade.
D
/P#SBTJMBFTQFDJmDBÎÍPGPJBOVODJBEBQFMB4VO.JDSPTZTUFNhTOPEJBEF
EF[FNCSPEFOPNBJPSFWFOUPEBFNQSFTBOP#SBTJMP4VO5FDI%BZT
O anúncio deixou muitos desenvolvedores surpresos com tantas novidades
apresentadas. No final do artigo, será dito um pouco mais sobre o evento.
"SUJHPt"SFWPMVÎÍPEP+BWB&&6NPWFSWJFXTPCSFBTOPWJEBEFTEB+43
Adaptação a
diversos tamanhos de
aplicações
Aplicações
Entreprise
Projeto JPE
.BJP
Escalabilidade
J2EE 1.3
J2EE 1.2
Servlet
JSP
EJB
JMS
RMI/IIOP
CMP
JCA
J2EE 6
Facilitar o
Desenvolvimento
EJB 3.1
J2EE 5
JPA 2.0
Web Services
Servlet 3.0
J2EE 1.3
Annotations
ISF 2.0
EJB 3
Jax-RS1.1
Management JPA 1.0
JCDI 1.0
Deployment JSF
WS
Web Profile
Managed Beans
%F[FNCSP 4FUFNCSP
TQFDT
TQFDT
/PWFNCSP
TQFDT
.BJP
TQFDT
%F[FNCSP
TQFDT
Figura 1. Resumos sobre a evolução do Java EE.
Ficou claro que a Sun trabalhou duro no Java EE 6, pois muitas ideias inteSFTTBOUFTGPSBNBEJDJPOBEBTOB+43EFJYBOEPBNFTNBNBJTDPNQMFUB
e atendendo a necessidade de muitas aplicações. Além de atender a essas
necessidades, a nova especificação vem quebrar o paradigma de que Java
EE serve apenas para aplicações robustas e de grande porte, conseguindo
assim cumprir com o seu principal objetivo, que era se adaptar a aplicações
de diferentes tamanhos. Esse right-sizing foi conquistado graças à simplificação de diversas tecnologias e com a implementação de profiles diminuindo
DVTUPTEFJNQMFNFOUBÎÍPNBOVUFOÎÍPFEFTFSWJEPSFT/BmHVSBTFHVF
um resumo do que mudou em cada versão do Java EE e qual o principal
objetivo que aquela versão buscou atingir.
" FWPMVÎÍP EP +BWB && Ï OPUÈWFM QBSB TF UFS VNB JEFJB FTQFDJmDBÎÜFT
GPSBN BUVBMJ[BEBT F DJODP DSJBEBT DPOUBOEP BHPSB DPN VN UPUBM EF ²
importante ressaltar que atualmente apenas o Glasshfish v3 oferece total
TVQPSUFBP+BWB&&$POmSBOBmHVSBPRVFGPJBUVBMJ[BEPFPRVFGPJ
BEJDJPOBEPOB+43
Novidades
Atualizações
t%*
t$%*
t#FBO7BMJEBUJPO
t.BOBHFE#FBOT
t+"934
t&+#
t+1"
t4FSWMFU
t+4'
t*OUFSDFQUPST
t$POOFDUPST
t+"984
t&OUFSQSJTF8FC4FSWJDFT
t+41&-
t"OOPUBUJPOT
Figura 2. Atualizações e novidades na JSR 316.
Neste artigo, serão mostradas algumas das novidades que estão presentes na nova especificação, apresentando como as coisas se tornaram
mais simples, mais poderosas e as tecnologias estão mais integradas.
Web Profile
1BSBNVJUBTBQMJDBÎÜFTVUJMJ[BSUPEBTBTFTQFDJmDBÎÜFTQPEFTFSEFTOFDFTTÈrio. Pensando em atingir públicos específicos foram criados os profiles. Profiles
são configurações da plataforma EE que podem incluir apenas um subconjunUPEBTUFDOPMPHJBTEB+43EFJYBOEPBTTJNBQMBUBGPSNBNBJTMFWF*TTPÏ
bastante útil para desenvolvedores que, para utilizar algumas das tecnologias
EE, ficam em dúvida se instalam um servlet container faltando alguns recursos
ou um servidor de aplicações completo que é mais pesado que o necessário.
WebProfile
4FSWMFU
+4'
+41F&-
+45-
%FCVHHJOH4VQQPSUGPS0UIFS-BOHVBHFT
%*
$%*
+1"
"OOPUBUJPOT
+5"
#FBO7BMJEBUJPO
Tabela 1. Tecnologias presentes no WebProfile.
8FC1SPmMFOBEBNBJTÏEPRVFVNQSPmMFKÈEFmOJEPDPNQPTUPQPSUFDOPMPHJBTBPJOWÏTEF"UBCFMBEFNPOTUSBUPEBTBTFTQFDJmDBÎÜFTRVFFTUÍP
dentro do Web Profile.
Lembrando que a Sun pretende lançar gradativamente mais profiles. Um que
eles têm em mente é o Minimal que irá apenas possuir suporte a JSP e Servlets.
Já que os profiles pretendem atender a apenas certas tecnologias, um servidor
Java EE pode agora dar suporte a apenas a alguns profiles e não a todas as tecOPMPHJBTEB+43GB[FOEPDPNRVFPTFSWJEPSTFUPSOFNBJTMFWFFTJNQMFT
%FQFOEFDZ*OKFDUJPO%*
"+43NBJTDPOIFDJEBDPNP%*UFNDPNPMÓEFSFTPDSJBEPSEP(PPHMF
Guice, Bob Lee e o criador do Spring, Rod Johson. A mesma foi especificada
pensando em padronizar a injeção de dependências e trazer esse conceito
para dentro do Java em um nível de aplicação (qualquer objeto e não
apenas recursos).
O objetivo é muito simples: definir uma semântica básica para injeção de
dependências com Java EE. Para definir essa semântica foram criadas anotações dentro do pacote javax.inject. Abaixo segue uma lista das anotações
definidas pela JSR:
t !*OKFDUo*EFOUJmDBDPOTUSVUPSFTNÏUPEPTPVBUSJCVUPTRVFQPEFNTFS
injetados.
t !/BNFEo%JTQPOJCJMJ[BEFUFSNJOBEPDPNQPOFOUFQBSBTFSSFGFSFOciado na camada de apresentação através de EL.
t !2VBMJmFSo2VBMJmDBEPSFTQBSBJOKFÎÍPEFEFUFSNJOBEPDPNQPOFOUF
t !4DPQFo%FmOFPFTDPQPEPDPNQPOFOUF
t !4JOHMFUPOo"QFOBTVNBJOTUÉODJBEFEFUFSNJOBEPDPNQPOFOUF
Nos próximos tópicos, será possível ver exemplos práticos da utilização
dessas anotações.
$POUFYUBOE%FQFOEFODZ*OKFDUJPO$%*
"+43BOUJHBNFOUFDIBNBEBEF8FC#FBOTFBHPSBNBJTDPOIFDJEBDPNP
Context and Dependency Injection, tem como líder Gavin King, criador do HiCFSOBUFFEP+CPTT4FBN"SB[ÍPEBNPEJmDBÎÍPEPOPNFTFEFVQFMB+43
ser a definição de serviços que se aplicam a todos os tipos de componentes EE ,
como EJB, JSF e Servlets. O nome web beans passava a ideia de que seria criado
um novo componente em vez da criação de um serviço de fato.
31
"SUJHPt"SFWPMVÎÍPEP+BWB&&6NPWFSWJFXTPCSFBTOPWJEBEFTEB+43
CDI define um conjunto de serviços para ambiente Java EE que torna o desenvolvimento de aplicações muito mais fácil. Ele disponibiliza uma arquitetura
que permite aos componentes Java EE como servlets, enterprise beans e JavaBeans existirem em um ciclo de vida de uma aplicação com um escopo bem
definido como sessão, requisição, entre outros. Esses serviços definidos pelo
CDI ainda permitem que os componentes, incluindo EJB session beans e JSF
managed beans, sejam injetados para interagirem com baixo acoplamento
através de eventos tratados pelo próprio container. Porém, sem dúvidas, o que
mais chama atenção é a unificação e simplificação na forma de trabalhar com
EJB e JSF. CDI permite que enterprise beans (EJB) atuem como managed beans
em uma aplicação JSF, assim seus serviços, como suporte transacional, estarão
disponíveis na camada web, tornando muito mais fácil o desenvolvimento de
uma aplicação web mais robusta.
Em resumo, o que o CDI faz para conseguir injetar diferentes beans em diferentes tecnologias nada mais é do que tratar todos os beans como managed
beans e, em alguns casos, como o EJB, adicionar algum serviços extras (suporte
a transação, segurança, thread safety). Managed beans são controlados pelo
container, tornando possível a injeção do mesmo em qualquer classe Java, seja
ela manipulada pelo container ou não. Também é possível utilizar esse bean na
DBNBEBEFBQSFTFOUBÎÍPDPN&-BUSBWÏTEBBOPUBÎÍP!/BNFE1SBUJDBNFOUF
qualquer classe Java poderá ser controlada pelo container, desde que anotada
DPN!.BOBHFE#FBOPVBMHVNBPVUSBBOPUBÎÍPRVFBFMFKBDPNPUBM!/BNFE!4FTTJPO4DPQFE!4UBUFGVMFOUSFPVUSBT
/BmHVSBQPEFNPTWFSVN
exemplo de como fica a arquitetura Java EE com CDI.
-JTUBHFN4UBUFMFTT4FTTJPO#FBOBOPUBEPDPN!/BNFE
@Stateless
@Named
public class OlaMundoBean {
public String digaOla(){
return “Ola Mundo”;
}
}
Um exemplo da utilização de uma aplicação com CDI pode ser visto nas ListaHFOTFPOEFVN&+#TUBUFMFTTTFTTJPOCFBOÏSFGFSFODJBEPFNVNBQÈHJOB
JSF utilizando EL de uma forma muito fácil e sem adicionar nenhum framework
adicional. Lembre-se que isso só é possível pois o CDI trata meus objetos EJBs
como managed beans e esses beans podem ser acessados via EL utilizando a
BOPUBÎÍP!/BNFE
-JTUBHFN3FGFSÐODJBBDPNQPOFOUF&+#FNVNBQÈHJOB+4'
<h:outputText value=”#{olaMundoBean.digaOla}” /> Mais detalhes e exemplos podem ser vistos no artigo sobre CDI nessa
mesma edição.
4FSWMFUT
Olhando para as tendências de desenvolvimento do mercado e evitando a
utilização de arquivos XML, o mapeamento das servlets e filtros pode agora
ser feito via anotações, o que torna a configuração no web.xml opcional.
Pensando em sites web. Suporte a servlets assícronas é outra interessante
funcionalidade que veio para facilitar o desenvolvimento de aplicações no
estilo do framework Comet. Para criar uma servlet, não é mais necessário
OFOIVNBSRVJWPEFDPOmHVSBÎÍPCBTUBBEJDJPOBSBBOPUBÎÍP!8FC4FSWMFU
que possui três parâmetros: o primeiro é o path que será utilizado para acesTBSBTFSWMFUPTFHVOEPÏPOPNFEBTVBTFSWMFUFPUFSDFJSPEJ[TFTVBTFSWMFU
suporta requisições assíncronas. Na Listagem 3 segue um exemplo de criação.
'JHVSB"SRVJUFUVSB+"7"&&DPN$%*SFUJSBEBEPTJUFUIFTFSWFSTJEFoWFSSFGFSÐODJBT
Para utilizar CDI, você deve criar um arquivo, mesmo que vazio, chamado beans.xml dentro da pasta WEB-INF da sua aplicação. Esse arquivo dirá ao servidor
que você deseja utilizar os serviços CDI e dentro dele é possível configurar os
beans sem a necessidade do uso de nenhuma anotação.
Uma parte importante de se conhecer são os tipos de ciclos de vida dos managed beans. No total, são cinco tipos diferentes de escopos, dentre eles estão os
KÈDPOIFDJEPT!4FTTJPO4DPQFE!"QQMJDBUJPO4DPQFEF!3FRVFTU4DPQFE"T
OPWJEBEFTmDBNQPSDPOUBEFEPJTFTDPQPTP!%FQFOEFOUFP!$POWFSTBtionalScoped. O primeiro é o escopo default caso nenhum seja explicitamente
configurado, ele define que uma nova instância do recurso será criada para
DBEBJOKFÎÍP+ÈP!$POWFSTBUJPOBM4DPQFEDPSSFTQPOEFBVNDPOUFYUPNFOPS
do que sessão, porém que engloba vários request, ou seja, uma conversação
que é utilizada , por exemplo, em um cadastro que inclui várias etapas onde os
dados são persistidos apenas ao fim e não em cada etapa.
32 www.mundoj.com.br
Listagem 3. Criando uma servlet.
@WebServlet(urlPatterns=”/foo”, name= “MyServlet”,
asyncSupported=true)
public class MinhaServlet extends HttpServlet{
public void doGet ...
public void doPost ..
}
Outra funcionalidade interessante é que agora não é mais necessário
configurar nada para se utilizar frameworks web de terceiros (plugins),
estes que configuram novos servlets e filtros. Basta inserir o JAR do
mesmo na pasta WEB-INF/lib. O plugin deve conter um arquivo chamado
web-fragment.xml dentro do diretório META-INF contendo configurações mínimas para o funcionamento dele, estas configurações antes
eram inseridas no web.xml por quem desejasse utilizar o framework.
"SUJHPt"SFWPMVÎÍPEP+BWB&&6NPWFSWJFXTPCSFBTOPWJEBEFTEB+43
&OUFSQSJTF+BWB#FBOT&+#
“Em um Web Archive (WAR) eu posso colocar EJBs?” Com a nova especificação sim! Agora um arquivo WAR pode conter EJBs. Além dessa agradável modificação, a nova versão do EJB conta com interface local do bean
PQDJPOBMDIBNBEBTBTTÓODSPOBTBBOPUBÎÍP!4JOHMFUPOFNCFEBCCMFT
container, invocações assíncronas, um timer service integrado, e um EJB
NBJTNBHSPDIBNBEP&+#MJUF/B-JTUBHFNTFHVFVNFYFNQMPEF&+#
OB WFSTÍP 7FKB RVF OÍP Ï NBJT OFDFTTÈSJP VUJMJ[BS JOUFSGBDFT MPDBJT
tornando mais simples a criação de um EJB local. Abaixo, segue uma
breve introdução às novidades faladas acima:
t &+#T4JOHMFUPOo6TBOEPBBOPUBÎÍP!4JOHMFUPOÏQPTTÓWFMEFmOJS
que no container deve haver apenas uma instância daquele bean,
o que não era possível na especificação anterior.
t &NCFEBCCMFT$POUBJOFSTo1PTTJCJMJEBEFEFTFVUJMJ[BS&+#TFNVN
ambiente Java SE.
t 5JNFS4FSWJDFo"USBWÏTEBBOPUBÎÍP!4DIFEVMFÏQPTTÓWFMBHFOEBS
tarefas, baseadas no Cron (serviço de agendamento do Unix), de
forma simples e declarativa.
t *OWPDBÎÜFT"TTÓODSPOBTo"USBWÏTEBBOPUBÎÍP!"TZODISPOPVTÏ
possível invocar um session bean de forma assíncrona. Cada vez
mais processamento assíncrono é uma necessidade de sistemas
de grande escala, antigamente esse tipo de processamento era
evitado pela dificuldade de implementação onde eram necessários
frameworks externos como o JMS.
t &+#-JUFo4VCDPMFÎÍPEBTQSJODJQBJTGVODJPOBMJEBEFTEBWFSTÍP&+#
completa. É utilizado quando não é necessário para uma aplicação
B QSFTFOÎB EF UPEPT PT SFDVSTPT EJTQPOÓWFJT EP &+# MFWBOEP
apenas os essenciais como local session beans, injeção de dependências, segurança, interceptadores, entre outros.
+1"
Saber mais
Oficialmente a JPA foi desacoplada do EJB sendo considerada uma API
distinta. Com grande influência de nomes conhecidos no meio ORM,
DPNP (BWJO ,JOH B +43 UFN DPNP PCKFUJWP EJTQPOJCJMJ[BS NBJT
funcionalidades para que a API se torne suficiente por si só, o que antes
não ocorria, já que era necessário utilizar frameworks como o Hibernate
para conseguir funcionalidades como a criteria. As principais novidades
(muitas delas inspiradas no próprio Hibernate) ficam por conta da inclusão da API de criteria, suporte a mapeamento de coleções de tipos
primitivos, lock pessimista, API de cache, melhor suporte a mapas, entre
outras novidades
"FEJÎÍPEBSFWJTUB.VOEPKUSB[PBSUJHPi&+#
Conheça as Novidades do Futuro do Java CorpoSBUJWPwTPCSF&+#F&+#MJUF
"FEJÎÍPEB.VOEPKUSB[PBSUJHPi+1"PT/PWPT
Recursos Inspirados no Hibernate” que possui
NBJTJOGPSNBÎÜFTTPCSFB+1"
deveria dar mais atenção para o JSF, já que ele está crescendo e adquirindo mais
espaço no mercado web. Com isso, a nova especificação suporta a utilização de
BOPUBÎÜFTQBSBSFHJTUSBSPTTFVTDPNQPOFOUFT!.BOBHFE#FBO
UPSOBOEPP
arquivo faces-config.xml é totalmente opcional. Essa é uma das novidades da
WFSTÍPEP+BWB4FSWFS'BDFTQPSÏNUFNPTWÈSJBTPVUSBTDPNPGÈDJMOBWFHBção, suporte a AJAX, componentes compostos, entre outras.
+4'TJNQMJmDPVFNVJUPPEFTFOWPMWJNFOUPXFCFNDPNQBSBÎÍPDPNTVB
WFSTÍP/BT-JTUBHFOTFRVFBQSFTFOUBNSFTQFDUJWBNFOUFNBOBHFE
CFBOTDPOmHVSBEPTOB+4'FPMFJUPSQPEFQFSDFCFSDPNPmDPVGÈDJM
criar um managed bean, não sendo mais necessário manipular arquivos XML.
-JTUBHFN$SJBOEPVNCFBODPN+4'
<managed-bean>
<managed-bean-name>login</managed-bean>
<managed-bean-class>br.com.meupacote.Login</managed-bean> <managed-bean-scope>session</managed-bean-scope>
</managed-bean>
-JTUBHFN$SJBOEPVNCFBODPN+4'
@ManagedBean
@SessionScoped
public class Login { ... }
Mais detalhes sobre as novidades podem ser encontrados no artigo sobre JSF
OFTTBNFTNBFEJÎÍP
#FBO7BMJEBUJPO
Pensando em padronizar a validação de JavaBeans no Java foi criada a JSR
&MB USPVYF VNB GPSNB NVJUP TJNQMFT QBSB WBMJEBS TVBT DMBTTFT +BWB ²
importante ressaltar que a especificação não se aplica a todas as classes Java,
sendo válida apenas aos JavaBeans. Para quem já utilizou o Hibernate Validation, sentirá o código da Listagem 6 bem familiar, onde são configuradas as
SFTUSJÎÜFTEFWBMJEBÎÍPEFVNCFBODIBNBEP&OEFSFDP"BOPUBÎÍP!/PU/VMM
EJ[RVFPWBMPSEPBUSJCVUPSVBOÍPQPEFTFSOVMP"BOPUBÎÍP!4J[FFTQFDJmDB
PUBNBOIPNÈYJNPEFTTFNFTNPWBMPSTFOEPRVFDBTPFMFTFKBNBJPSRVF
a mensagem de erro do atributo message deve ser exibida.
Listagem 6. JavaBean Endereco que possui regras de validações em
seus atributos.
public class Endereco {
@NotNull @Size(max=30, message=”maior que {max} caracteres”)
private String rua;
}
Considerações finais
+BWB4FSWFS'BDFT+4'
O JSF veio com o intuito de simplificar o desenvolvimento de projetos web
Java EE. Porém, por também usar arquivos de configuração, manter um projeto extenso utilizando JSF pode ser algo difícil. Dessa forma, a Sun percebeu que
Trazendo várias novidades, o Java EE 6 tem tudo para melhorar muito
o desenvolvimento de aplicações enterprise. A nova especificação
aprendeu com o mercado e com seus próprios erros e conseguiu trazer
para dentro dela diversas tecnologias interessantes que antes eram
possíveis apenas com a utilização de frameworks. Durante o artigo fo33
"SUJHPt"SFWPMVÎÍPEP+BWB&&6NPWFSWJFXTPCSFBTOPWJEBEFTEB+43
ram abordadas algumas dessas tecnologias com o intuito de trazer ao
leitor uma visão geral das principais mudanças. É importante também
observar que tudo caminha para um mundo onde o desenvolvimento
enterprise se torne cada dia mais fácil, escalável, simples e integrado.
Claro que ainda existe muito que melhorar, mas já é possível notar uma
evolução e, ao contrário do que muitos pensam, tecnologias como EJB
estão mais vivas do que nunca.
Pela quantidade de novidades não foi possível comentar todas elas e
nem entrar a fundo em nenhuma, porém existem materiais e cursos,
que já são atualizados e oferecem suporte a nova especificação. Nessa
mesma edição, é possível encontrar artigos que entram mais a fundo
OBT FTQFDJmDBÎÜFT EF $%* F +4' 1PS mN HPTUBSJB EF BHSBEFDFS B
%BWJE1BOJ[F4ÏSHJP-PQFTQFMBEJDBTmOBJTt
Referências
t "QSFTFOUBÎÍP +BWB&& EP 4VO5FI%BZT o +BWBIUUQEFWFMPQFSTTVODPNFWFOUT
UFDIEBZTQSFTFOUBUJPOTQEGT5%@41@+BWB&&1BSUBOE@4IJOQEG
t %FQFEFODZ*OKFDUJPOJO+BWB&&oIUUQXXXUIFTFSWFSTJEFDPNUUBSUJDMFTBSUJDMFUTT
l=DependencyInjectioninJavaEE6
t +BWB&&5VUPSJBMoIUUQKBWBTVODPNKBWBFFEPDTUVUPSJBMEPDCOBBXIUNM
t +43%*oIUUQKDQPSHFOKTSEFUBJM JE
t +43$%*oIUUQKDQPSHFOKTSEFUBJM JE
t +43+BWB&&oIUUQKDQPSHFOKTSEFUBJM JE
0 FWFOUP 4VO 5FDI %BZT F NBJT
novidades para a plataforma Java
O SunTechDays é o maior evento organizado pela Sun no Brasil,
realizado anualmente, sempre traz novidades das tecnologias
Sun, além de um ambiente agradável, ótimos coffee breakes e
uma ótima infraestrutura. Contando com participações de excelentes palestrantes, como Karen Padir, vice-presidente do grupo
de infraestrutura da Sun Microsystem's MySql, Jerome Dochez,
engenheiro-chefe do projeto Glassfish, Sang Shin, arquiteto da
plataforma Java e James Gosling, o “pai do java”. Os assuntos abordados este ano foram desde a plataforma OpenSolaris, passando
pela plataforma Java e Glassfish e terminando em Cloud Computing (que inclusive teve como palestrante o brasileiro Fábio Kung).
No geral, o evento foi bom. O primeiro dia teve como foco as
novidades do Java 7 e atenções focadas para James Gosling que
deu um breve overview sobre novas tecnologias, como Glassfish
v3 e Java 7. Já no segundo dia as atenções estavam focadas para a
PmDJBMJ[BÎÍPEB+43FTQFDJmDBÎÍPQBSBP+BWB&&
5PEBT BT BQSFTFOUBÎÜFT EP 4VO5FDI%BZT FTUÍP EJTQPOÓWFJT
em PDFs para download no site http://developers.sun.com/
FWFOUTUFDIEBZTQSFTFOUBUJPOTTBPQBVMPKTQ
34 www.mundoj.com.br
Download