Sei sulla pagina 1di 68

|||erte-.

e
J.e e M+|er
www..eltwe||.cem.|r I z 1
Alguns recursos:
|a||c+cee. a+r+ +m||eate \||
Metee|ea|+ |atear+|meate ||+\
|a||c+cee. cem recar.e. e e.|tea
|.c+|+||||+e e e\ce|eate aerlerm+ace
Ma|t|c+m++. (c||eate, .er.|er e |+ace
Ma|t|a|+t+lerm+ (||aa\
(1
, \|aew.
(
e M+c
(z

teae\1e .|ma|t\ae+ + ma|t|a|e. |+ace. e +e.


|a|ter|+ ae. .|.tem+. aer+e. (|ea e tr+a.+cee.
0ereac|+meate e a.a+r|e. e ae||t|c+. e +ce..e
|aterl+ce .|.a+| r|c+ e cem cemaeaeate. |ater+t|.e.
:aaerte a+t|.e + ||emetr|+
lere e ||a|+ e ce|ae
.|.a+|
\ece ca|+ + |ea|c+ e e M+|er l+t e re.te. | e|e aaem |ater+ae cem + c+m++ e
cema|e\|+e, a+r+at|ae aae .ea .|.tem+ laac|eae cem aerle|c1e. tem
e.ea.e|.|meate +te \ m+|. r+a|e, .+| .e|r+r temae a+r+ .ece +ar|mer+r
+|a+ m+|. .a+. +a||c+cee..
:|ma||lc+me. + Iecae|ea|+
|ce..e e ae..e .|te e e.ca|r+ aaem |+ .e |||ertea
(1
) \
|a

e
w
.
e
.N
e
t .
1
e
m
+
rc
+
.
re
a
|.
tr+

+

+
M
|c
re
.
e
lt t
e
ra
e
r+
t|e
a
a
e
.
|
J
|
(2
) M
+
c
e
m
+
rc
+
re
a
|.
tr+

+

+
|
a
a
|e
t
e
m
a
a
te
r.
(3
) |
|a
a
\
e
m
+
rc
+
re
a
|.
tr+

+

e
|
|a
a
.
I
e
r
.
+
|
.
(4
) I+
.
+
e
m
+
rc
+
re
a
|.
tr+

+

+
:
a
a
M
|c
re
.

.
te
m
.
-
I
e

e
.
e
.

|re
|te
.
re
.
e
r
.
+

e
.
Ja
v
a
(4)
e
.N
e
t
(1)
\ece +|a+ e.ea.e|.e .|.tem+.
a.+ae ||aaa+aea. e arear+m+c1e!
Rev_Java53_cromo.pdf 2 Rev_Java53_cromo.pdf 2 20/12/2007 16:40:08 20/12/2007 16:40:08
E
s
p
e
c
i
a
l
ANDROID: UMA NOVA PLATAFORMA WIRELESS
MARLON LUZ
Conhea e aprenda a desenvolver uma aplicao para o Android, a nova plataforma para
celulares que usa o Java e o Eclipse para desenvolvimento
20
W
e
b
RELATRIOS NA WEB COM JAVA PERSISTENCE API
ANA ABRANTES
Crie passo a passo um relatrio com grupos e totalizaes, usando o editor de
relatrios iReport e a API open source JasperReports, alm da Java Persistence API e
o NetBeans 6.0.
44
CACHING NA WEB USANDO O PROJETO EHCACHE
ANDR SANTI
Turbinando o acesso a dados em suas aplicaes web com o ehcache, um meca-
nismo poderoso e simples de usar que permite guardar objetos muito acessados
em memria
62
C
o
r
e
26
DROOLS: APLICANDO REGRAS NO MUNDO REAL
EDGAR A. SILVA
Desacoplando regras de negcios dos cdigos Java: como construir de forma simples
aplicaes resistentes a mudanas e separadas de suas regras com Java e Drools
PERSPECTIVAS DO JAVA: A LINGUAGEM E A PLATAFORMA
OSVALDO DOEDERLEIN
O que pode acontecer no mundo da programao na era das arquiteturas massiamente
paralelas: mudanas prometidas para o Java SE 7, tcnicas de programao funcional e
memria transacional
08
54
SPRING REMOTING: ORGANIZANDO O ACESSO REMOTO
DANIEL CICERO AMADEI
Como usar o suporte fornecido pelo Spring a mecanismos de acesso remoto, que
abstraem as complexidades da comunicao via rede para o desenvolvedor
C
a
p
a
30
ECLIPSE X NETBEANS:
COMPARANDO OS GRANDES IDES LIVRES
OSVALDO DOEDERLEIN
Uma comparao realista e objetiva das duas ferramentas mais usadas por desenvol-
vedores Java: da losoa de cada produto s grandes e pequenas diferenas prticas.
Contedo
Rev_Java53_cromo.pdf 3 Rev_Java53_cromo.pdf 3 20/12/2007 16:40:08 20/12/2007 16:40:08
O
Brasil tem Java esta era a chamada de capa da primeira edio
da Java Magazine. Estvamos em julho de 2002, um momento
em que a tecnologia comeava sua escalada vertiginosa para
se tornar a mais usada no Brasil. Desde ento, esta revista acompanhou a
evoluo nacional e mundial do Java, cobriu seis eventos JavaOne e muitos
outros acontecimentos nacionais e internacionais; apoiou ou divulgou a cria-
o de dezenas de grupos de usurios e relatou mudanas de paradigmas e
revolues em vrios segmentos. E, claro, trouxe mais de 450 artigos, escritos
por mais de 100 autores diferentes, cobrindo um volume de informaes
enciclopdico.
Foi um grande privilgio estar frente dessa iniciativa e poder realizar um
sonho nutrido durante anos. Cinco anos e meio de circulao e 3 mil pginas
depois, posso dizer que todos os objetivos originais foram cumpridos: criar
uma revista com contedo de qualidade e perfil agressivamente independen-
te, apoiar o crescimento da tecnologia Java no Brasil, e inovar visualmente em
um mercado que na poca considerava que revistas tcnicas no precisavam
ser bonitas nem bem cuidadas.
Isso tudo est parecendo uma grande despedida... E . Esta a ltima edio da
Java Magazine que lidero como Editor-Chefe. A sada por iniciativa prpria; che-
gou o momento de cuidar de outros projetos tanto profissionais como pessoais.
Mas a Java Magazine permanecer com vocs, claro. Uma nova e competente
equipe editorial est montada e no haver perda alguma de continuidade.
Os sete artigos desta edio mantm a nossa tradicional variedade: voc ver
uma detalhada comparao dos principais IDEs livres; um tutorial extensivo
sobre relatrios com a API de mapeamento O/R JPA; e como usar o mecanismo
de regras Drools para deixar suas aplicaes mais adaptveis a mudanas.
Antes de continuar, devo informar que o mini-curso sobre Ajax de Fernando
Lozano precisou ser interrompido por algumas edies. O autor passou por
problemas que o impossibilitaram de manter o ritmo mensal de contribuies
mas voltar brevemente s pginas da revista.
Voltando ao contedo desta edio: voc vai conhecer a nova plataforma
para celulares liderada pelo Google, o Android, que promete mudar as bases
do desenvolvimento wireless. Outro texto analisa as mudanas e desafios
que surgem com o paralelismo crescente nos computadores atuais e o im-
pacto disso sobre as plataformas Java. Completam esta a edio um artigo
sobre o uso do Spring Remoting para criar aplicaes distribudas de forma
simplificada, e uma matria sobre o projeto ehcache, que permite aumentar
a responsividade de aplicaes web atravs de caches de objetos.
Desejo muito sucesso nova equipe editorial da Java Magazine e grandes
conquistas a vocs leitores. Um feliz 2008 e terabytes de
prosperidade tecnolgica!
Boa leitura e sucesso!
Leonardo Galvo
Fundador e Editor-Chefe
Carta ao Leitor
Edio
Publisher e Editor-Chefe
Leonardo Galvo (leonardo@javamagazine.com.br)
Editores adjuntos
Osvaldo Doederlein (osvaldo@javamagazine.com.br)
Fernando Lozano (lozano@javamagazine.com.br)
Colaboraram nesta edio
Ana Abrantes, Andr Santi, Daniel Cicero Amadei, Edgar Silva, Marlon Luz,
Osvaldo Doederlein
Arte
Diagramao Vinicius O. Andrade
Ilustraes e Capa Antonio Xavier
Produo
Gerncia de Marketing Kaline Dolabella
Distribuio
Fernando Chinaglia Distribuidora S.A.
Rua Teodoro da Silva, 907, Graja - RJ
CEP 20563-900, (21) 3879-7766 - (21) 2577-6362
Atendimento ao leitor
A DevMedia possui uma Central de Atendimento on-line, onde voc pode tirar
suas dvidas sobre servios, enviar crticas e sugestes e falar com um de nossos
atendentes. Atravs da nossa central tambm possvel alterar dados cadastrais,
consultar o status de assinaturas e conferir a data de envio de suas revistas. Acesse
www.devmedia.com.br/central, ou se preferir entre em contato conosco
atravs do telefone 21 2283-9012.
Edies anteriores
Adquira as edies anteriores da revista Java Magazine ou de qualquer outra
publicao do Grupo DevMedia de forma prtica e segura, em
www.devmedia.com.br/anteriores.
Publicidade
publicidade@javamagazine.com.br, 21 2213-0940
Anncios Anunciando nas publicaes e nos sites do Grupo DevMedia,voc divulga
sua marca ou produto para mais de 100 mil desenvolvedores de todo o Brasil,em mais
de 200 cidades.Solicite nossos Media Kits,com detalhes sobre preos e formatos de
anncios.
Reprints Editoriais Se foi publicado na Java Magazine um artigo que possa
alavancar as suas vendas, multiplique essa oportunidade! Solicite a reimpresso
da matria junto com a capa da edio em que saiu, e distribua esse reprint
personalizado entre seus clientes.
Encarte de CDs Faa como nossos maiores anunciantes. Encarte um CD com
uma amostra de seus produtos na Java Magazine e atinja um pblico segmentado
e formador de opinio.
Java, o logotipo da xcara de caf Java e todas as marcas e logotipos baseados em ou
referentes a Java so marcas comerciais ou marcas registradas da Sun Microsystems,
Inc. nos Estados Unidos e em outros pases.
|ae \| |a|c1e 1 zI |::N I-1
Apoio
Realizao
S
Rev_Java53_cromo.pdf 4 Rev_Java53_cromo.pdf 4 20/12/2007 16:40:09 20/12/2007 16:40:09
Conhea nossos frameworks open-source
O framework genesis garante uma maior produtividade no desenvolvimento de aplicaes
desktop, permitindo a utilizao de Swing, SWT e Thinlet de forma declarativa e com suporte
a anotaes como forma de evitar as complexidades e particularidades de cada API grca.
Seu modelo de integrao entre interface e camada de negcios possibilita que aplicaes
locais, implementadas de forma simples e facilmente testvel, possam ser posteriormente dis-
ponibilizadas em arquitetura rich-client distribuda, simplesmente recongurando-se sua lgica
de negcios para execuo remota em servidores Java EE. Alm de open-source e gratuito, o
genesis possui extensa documentao (em ingls e portugus) e uma ativa comunidade de
desenvolvedores.
Uma empresa premiada
Entre os projetos que j contaram com a consul-
toria da Summa Technologies, incluem-se os trs
nicos sistemas brasileiros premiados com o Duke
Award, conferido anualmente durante o JavaOne
Conference: Carto Nacional de Sade do Datasus
(2003); IRPF Multiplataforma da Receita Federal
e Serpro (2004); e Sistema Integrado de Agenda-
mento de Pacientes da Secretaria de Sade da
Prefeitura de So Paulo (2005).
E m b u s c a d e n o v o s d e s a f i o s e m s u a c a r r e i r a ? E n v i e s e u c u r r c u l o p a r a : c u r r i c u l o @s u mma - t e c h . c o m
O DevWare um ambiente virtual completo de desenvolvimento j insta-
lado e congurado, composto exclusivamente por produtos open source. Inclui
controle de issues e de verso, automao de buid, frum, wiki corporativa,
servidores web, email e ftp, repositrio maven2, servidor ldap para controle
de usurios, console administrativo, entre outros. Com baixo consumo de re-
cursos e baseado em tecnologia de virtualizao, o DevWare foi projetado
especialmente para facilitar tarefas administrativas como backup e migrao
entre mquinas. Consulte-nos para saber como o DevWare, combinado com
boas prticas de desenvolvimento, pode aumentar a qualidade e produtividade
de seus projetos Java.
Os frameworks genesis e DevWare foram criados pela
Summa Technologies, disponibilizados de forma livre e
gratuita (licena open source LGPL).
Para maiores informaes, downloads e
documentaes consulte os sites:
https://genesis.dev.java.net/
https://devware.dev.java.net/
Uma nova marca,
a conabilidade de sempre.
DevWare
genesis
Consultoria . Arquitetura . Mentoring . Treinamento . Framework . Componentes
Summa Technologies do Brasil . +55.11.3055.2060 . www.summa-tech.com
Rev_Java53_cromo.pdf 5 Rev_Java53_cromo.pdf 5 20/12/2007 16:40:10 20/12/2007 16:40:10
6 Java Magazine Edio 46
www.devmedia.com.br/javaplus
6 Java Magazine Edio 53
L
e|tere., |em|r+me. aae maaea e ceace|te ae +..|a+tar+ a+ re.|.t+ I+.+ M+a+t|ae. Ne.e. +..|a+ate. ae..aem
uma Assinatura de Contedo Java Plus:
Java Plus = Revista impressa + Vdeo-aulas + Cursos online
O pacote Java Plus inclui:
|ece||meate mea.+| a+ re.|.t+ I+.+ M+a+t|ae (z ea|cee.
|ce..e, aar+ate am +ae, +e aert+| I+.+||a., ceateaae .|aee-+a|+. e car.e. ea||ae.
O Portal continua se expandindo, com vdeo-aulas voltadas ao desenvolvedor Java e a iniciantes na tecnologia. J
so mais de 220 aulas, alm de dois cursos online. Acesse o portal JavaPlus e saiba como obter esse novo benefcio
em sua assinatura!
Cursos Online
[Novo] Desenvolvendo uma aplicao completa com Struts 2
Obtenha os conhecimentos necessrios para o desenvolvimento de aplicaes Java utilizando o Struts 2.
devmedi a. com. br/cur s os /s t udent por t al . as p?cur s o=41
Padres de Projeto em Java
Apresentando diversos design patterns e os aplicando na prtica, usando a linguagem e as plataformas Java.
devmedi a. com. br/cur s os /s ai bamai s . as p?cur s o=25
Introduo ao desenvolvimento para celulares com Java ME
Apresentando tcnicas, APIs e ferramentas para a criao de aplicaes com a tecnologia Java Micro Edition.
devmedi a. com. br/cur s os /s ai bamai s . as p?cur s o=17
N+ cemar+ ae.t+ ea|c1e tea|+ +ce..e ar+ta|te +.
5 vdeo-aulas sobre padres de projeto na prtica: Detalhes de dois design patterns fundamentais State e Command com
exemplos prticos.
2 vdeo-aulas sobre testes unitrios com JUnit e NetBeans 6.0. teme a.+r e. recar.e. ae |atear+c1e ae ||| Net|e+a. a+r+ cr|+r
e executar testes com produtividade.
Para visualizar, acesse o link: www.devmedia.com.br/articles/listcomp.asp?keyword=jm53&codigobanca=eleupheria
Na DevMedia, o leitor de banca tambm ganha!
Conhea a assinatura Java
Magazine Plus mais
contedo Java com mais
de 220 vdeo-aulas para
voc e trs Cursos Online
Novidades em vdeo-aulas
TrAX - Transformation API for XML - Partes 1 e 2
Apresentando esta poderosa API de transformao de XML.
Tarefas Ant no NetBeans 6.0
|et+||e. .e|re + |atear+c1e ae Net|e+a. . cem e |at e .e|re e. recar.e.
para criao e execuo de tarefas usado essa tecnologia.
Testes Unitrios com o JUnit 4.1 no NetBeans 6.0 Parte 1
Criando uma aplicao de exemplo e aplicando um caso de teste para
validar cenrios de variao de seus mtodos.
Testes Unitrios com o JUnit 4.1 no NetBeans 6.0 - Parte 2
Finalizando essa srie de vdeo-aulas, iremos explorar outros recursos
aae e Net|e+a. . elerece a+r+ + cr|+c1e e e\ecac1e ae te.te. aa|t1r|e.
baseados em JUnit 4.1.
Eclipse + JSF: Desenvolvendo aplicaes JSF utilizando o
Eclipse - Parte 4
Encerrando a srie sobre desenvolvimento de uma aplicao JSF no
Eclipse.
Padres de Projeto na Prtica State Partes 1 a 3
Apresentando o padro de projeto State, atravs de vrios exemplos
prticos.
iReport Criando relatrios para aplicaes web Parte 13
Ne..+ .|aee-+a|+, .ece +areaaer1 + cea.tra|r am+ +a||c+c1e we| aae
invoca um relatrio atravs da passagem de parmetros simples e de
uma conexo JDBC.
Padres de Projeto na Prtica Command Partes 1 e 2
Atravs de exemplos prticos, aprenda a utilizar o padro de projeto
Command.
Persistncia Flexvel com BoxSQL - Parte 5
A quinta parte da srie sobre como criar uma camada de persistncia
utilizando o framework BoxSQL, generics e reflection: preparao do
boxsql.properties e execuo do teste da aplicao.
Rev_Java53_cromo.pdf 6 Rev_Java53_cromo.pdf 6 20/12/2007 16:40:10 20/12/2007 16:40:10
Rev_Java53_cromo.pdf 7 Rev_Java53_cromo.pdf 7 20/12/2007 16:40:10 20/12/2007 16:40:10
8 Java Magazine Edio 53
Programao Java e novas tecnologias na era das arqui
Perspectivas em um Mu
H
quanto tempo voc programa
em Java? No vale dizer mais
de 11 anos, pois o JDK 1.0 s foi
lanado em janeiro de 1996. E mesmo esta
data generosa, pois o JDK 1.0 (c entre
ns) no passava de um brinquedinho;
um beta disfarado. O Java comearia a
ser levado a srio a partir de 1997 (JDK
1.1.x), e passaria a exibir desempenho e
funcionalidades competitivas com lingua-
gens estabelecidas como C/C++ a partir
de 2000 com o Java 2. O mesmo pode ser
dito das plataformas-filhas, J2EE e J2ME,
que nasceram h quase oito anos, mas
tambm levaram alguns anos mais para
conquistar a maturidade e o lugar ao
sol que possuem hoje.
bom lembrar como o Java ainda novo.
Quando me formei em Computao no
mesmo ano em que o Java era lanado
linguagens como C++ e Visual Basic domi-
navam, e poucos diriam que este domnio
no iria durar dcadas mais. Sim, muita
gente conhecia linguagens superiores
em algum aspecto, como Smalltalk ou
Eiffel, mas parecia impossvel quebrar
diversos obstculos:
%A superioridade de desempenho de
linguagens de baixo nvel, como C e C++,
quando comparadas a linguagens mais
puras como Smalltak;
%A facilidade de uso de ambientes de de-
senvolvimento rpido, como VB e Delphi;
%O enorme investimento feito por for-
necedores de plataformas e ferramentas,
como Microsoft, Borland etc., bem como
seus clientes, sem falar no treinamento de
muitos desenvolvedores;
%A dificuldade (ento considerada alta)
de novos paradigmas como Orientao a
Objetos (embora a linguagem C++ fosse
popular, poucos programadores a usavam
de forma realmente OO);
%Resistncia a mudanas em geral. (Isso
era ainda pior antes da crise do Y2K, que
chacoalhou mesmo as corporaes mais
conservadoras para repensar suas estrat-
gias de TI.)
Mas apesar de tudo isso, o mundo do
desenvolvimento virou de pernas para o
ar, e no foi s na adoo do Java: tambm
em outras frentes como o surgimento da
Internet e o crescimento do movimento de
software livre, ambos com grande impacto
sobre todo o cenrio do desenvolvimento
de software.
Rev_Java53_cromo.pdf 8 Rev_Java53_cromo.pdf 8 20/12/2007 16:40:10 20/12/2007 16:40:10
Edio 53 Java Magazine 9
teturas maciamente paralelas
ndo Paralelo
As prximas revolues da
Programao Concorrente:
mudanas prometidas para
o Java SE 7, tcnicas de
programao funcional e
Memria Transacional
OSVALDO PINALI DOEDERLEIN
Nada mais natural ento do que imagi-
nar quais sero as prximas mudanas. Por
exemplo, existir uma edio 173 da Java
Magazine, daqui a dez anos? Certamente
a Sun, o JCP e outros guardies do Java
ainda estaro por a, promovendo o Java
SE 12. Mas isso no ser suficiente, se for
um novo COBOL relegado manuten-
o de aplicaes empoeiradas. Ser que
o Java continuar tendo a importncia
que tem hoje por muito mais tempo? E
se continuar firme e forte, o Java de 2017
ser reconhecvel comparando-se com o
que temos hoje?
A necessidade de novas linguagens
Novas linguagens de programao no
so inventadas somente por esporte. Exis-
tem duas foras principais que motivam a
sua criao e modificao.
Evoluo da tecnologia
Idias inovadoras, inicialmente conside-
radas ineficientes, podem com o tempo ser
utilizadas de forma mais ampla, devido
evoluo das tcnicas de implementao.
Um bom exemplo a prpria Orientao
a Objetos, que surgiu nos anos 70, mas por
muito tempo foi sinnimo de cdigo lento
e inchado. Somente aps duas dcadas de
pesquisas e aperfeioamentos em compi-
ladores, linguagens OO puderam se livrar
deste estigma, sendo hoje usadas at em
software de tempo real.
Citando exemplos mais prximos a ns,
caractersticas do Java como gerenciamen-
to de memria automtico (com Garbage
Collection) e bytecode portvel (com exe-
cuo em uma VM) seguiram o mesmo
caminho da obscuridade de linguagens
acadmicas ao domnio do mercado, com
as plataformas Java e .NET. Neste segundo
caso (VMs) o caminho foi ainda mais lon-
go, pois so tecnologias anteriores mesmo
Orientao a Objetos. Ambas datam do
incio dos anos 60, mas atingiram maturi-
dade tecnolgica apenas h poucos anos
e tendo a JVM como principal protagonista
da arrancada final.
Presso das demandas do mercado
O mercado sempre quer ferramentas
que atendam s necessidades de projetos
cada vez maiores e mais complexos, e
com tempo e custo de desenvolvimento
menores. Este fator no algo especial
ao desenvolvimento de software; um
lugar-comum na tecnologia e na indstria
em geral, embora seja mais acentuado no
nosso campo profissional.
Outros fatores complicam a vida dos
designers de linguagens de programao.
Por exemplo, o perfil profissional dos pro-
gramadores cada vez mais diferenciado.
Se nos anos 50 quase 100% dos desenvolve-
dores eram engenheiros ou matemticos,
hoje h muita variedade de cursos e pro-
fisses que envolvem programao, mui-
tas especializaes; vrios paradigmas,
ideologias e metodologias competidoras.
At mesmo entre os que usam a mesma
ferramenta primria, como a linguagem
Java, existe grande variedade de gostos
e estilos haja vista o enorme nmero
de solues para certos problemas, como
frameworks web. E num extremo, temos
cada vez mais programao sendo feita por
no-profissionais sem treinamento formal
em computao: economistas e adminis-
tradores criando macros complexas com o
Excel, designers programando scripts do
Flash ou JavaScript, analistas de negcio
modelando detalhes do comportamento de
sistemas com UML, e assim por diante.
As prximas foras
Vamos tentar identificar os fatores for-
as de design que iro motivar as pr-
ximas mudanas na rea de programao.
Existem algumas foras muito importantes
e fceis de identificar.
Escalabilidade por paralelismo
Chegamos ao fim a era dos Gigahertz,
fato que j comentei nesta coluna e j pas-
sou de revelao a clich. A indstria de
semicondutores atingiu barreiras fsicas
que inviabilizam a escalada da velocidade
das CPUs, pelo menos no ritmo com que
nos havamos acostumado nas dcadas
de 80 e 90.
Alis, uma curiosidade que me aconteceu
este ano foi reler O Universo numa Casca
de Noz, um livro de 2002 do fsico Stephen
Hawking, e encontrar uma figura falando
da evoluo das CPUs projetando 10 GHz
para... 2007!
1
. Este ano j est acabando e
ainda no temos nem metade disso.
Em compensao, temos mais CPUs; para
ser exato, mais cores (ncleos) nas novas
arquiteturas multi-core. No momento em
que escrevo este artigo, j existem produ-
tos de massa (computadores pessoais e at
consoles de jogos) com at quatro ncleos.
E isso s o comeo; logo teremos centenas
ou mais ncleos por CPU.
Na vanguarda atual, a Sun j est com o
chip Rock de 16 ncleos em produo ex-
1 Esta projeo era cortesia da Intel, somente citada por
Hawking.
Rev_Java53_cromo.pdf 9 Rev_Java53_cromo.pdf 9 20/12/2007 16:40:10 20/12/2007 16:40:10
10 Java Magazine Edio 53
Perspectivas em um Mundo Paralelo
perimental ( venda em 2008), e na Intel o
projeto de pesquisa TeraScale j demonstra
80 ncelos numa nica CPU (esse projeto,
mais verde, ainda levar alguns anos para
resultar em produtos de mercado). Mes-
mo hoje, j temos o chip Vega2 da Azul
Systems que tem 48 ncleos, porm este
um chip bem mais limitado que os ou-
tros mencionados, sendo aproxidamente
equivalente
2
a um Niagara 2 da Sun (que
tem 8 ncleos fsicos, mas 32 threads via
hyper-threading).
Produtividade
Do item produtividade j falamos um
pouco: o mercado sempre nos leva a
produzir mais cada vez mais rpido. Lin-
guagens de programao que prometem
ser mais fceis esto em alta. Na verdade
sempre estiveram. O nico problema que
as linguagens milagrosas se sucedem
como a moda da alta costura: todo ano h
uma novidade maravilhosa, e a moda do
ano passado vai pro brex. Mas, apesar
dos tropeos existem avanos, com a pro-
gressiva liberao do desenvolvedor de
responsabilidades como escrever cdigo
repetitivo para diversas tarefas, como a
persistncia.
Atualmente, esta tendncia responde
pelo interesse em linguagens dinamica-
mente tipadas como Ruby, Groovy, Python
e outras, que possuem uma sintaxe mais
2 O Vega2 s capaz do executar cdigo Java (o que
para ns OK!), e com um desempenho mdio relativa-
mente baixo por core, devido ao compartilhamento de
uma quantidade pequena de cache e de unidades de
ponto utuante.
enxuta e ciclo de desenvolvimento um
pouco mais gil que o do Java. A platafor-
ma Java tem se adaptado a esta tendncia
com uma progressiva abertura da JVM
para outras linguagens, com a JSR-223
(javax.script) no Java SE 6, Groovy, JRuby;
nova instruo invokedynamic no Java SE
7 e outros.
Qualidade
A necessidade de construir software
cada vez mais correto dispensa justifica-
tivas. No entanto, a impresso geral que
a contagem de bugs s faz aumentar. Os
usurios s no nos condenam porque a
gravidade mdia dos bugs tem diminudo.
Isso, pelo menos, foi um resultado bastan-
te concreto da evoluo das linguagens,
compiladores, sistemas operacionais, ser-
vidores de aplicaes e outras ferramentas
ou componentes de infra-estrutura. Esses
softwares hoje previnem ou tratam de
forma automtica a maioria dos problemas
que antigamente causariam uma falha ca-
tastrfica (crash ou corrupo de dados).
Em Java, por exemplo, toda uma classe
de erros graves de manipulao de me-
mria que ainda infestam aplicaes
nativas impossvel, devido ao modelo
de memria gerenciado. Um stack trace de
NullPointerException um substituto desa-
gradvel para o correto funcionamento de
uma operao; mas um crash da aplicao
muito pior. No h como negar que houve
progresso.
Por outro lado, as aplicaes tm crescido
em tamanho e em complexidade, numa ve-
locidade maior do que a capacidade dessas
tecnologias de reduzir a contagem total
de bugs. Muitos reclamam de softwares
modernos que tm dezenas de milhares
de bugs conhecidos. fcil comparar isso
com os bons tempos de aplicaes que,
se tivessem uma dzia de bugs, achava-se
muito. Mas para fazer justia, devemos
lembrar que as aplicaes de 20 anos
atrs cabiam folgadas em disquetes
de 360 Kb, e as atuais j comeam
a encher DVDs de 4,7Gb (13 mil
vezes mais).
O dilema elaborar lingua-
gens de programao cada
vez mais robustas: que
auxiliem a escrever c-
digo de qualidade e de preferncia com
pouco esforo. Isso porque com bastante
esforo, h ferramentas capazes disso h
muito tempo; desde linguagens duro-
nas como Ada e Eiffel at metodologias
ultra-formais como Z ou Redes de Petri.
Mas essas ferramentas permaneceram
em relativa obscuridade, pois seu uso
difcil e caro. S so viveis em projetos
cuja extrema necessidade de corretude
justifique custos e tempos de desenvolvi-
mento at dez vezes maiores que o normal;
por exemplo, nas indstrias aeronutica,
mdica ou militar.
Para os projetos mais feijo-com-arroz
que 99% de ns somos pagos para fazer,
esquea a idia de usar ferramentas al-
tamente formais; isso jamais ir pegar.
Por outro lado, existe a possibilidade de
ferramentas mais acessveis evolurem de
forma a incorporar alguns aspectos mais
robustos, numa verso light, seja atravs
de automatizao, seja com sintaxes facili-
tadas ou outros meios.
Nesta rea no vejo grandes tendn-
cias ou revolues a caminho. No Java
SE 7, teremos a JSR-305 (Anotaes para
Defeitos de Software) que ir especificar
anotaes como @NotNull para definir que
um parmetro de um mtodo no pode ser
null, entre outras coisas do tipo. Isso per-
mite que diversos tipos de erro, que hoje
s so detectados em tempo de execuo
(resultando numa exceo), possam ser
detectados no momento da compilao.
Paralelismo
O maior desafio o do paralelismo. Este
problema extremamente importante
e tambm urgente. E como j estamos
vivendo o incio da era multi-core, toda
a indstria j est se movimentando para
responder aos desafios nesta rea. Por isso,
vamos nos concentrar no restante do artigo
na questo do paralelismo.
O problema da tecnologia multi-core
que a maioria dos programadores no
conseguiria programar cdigo concorren-
te de qualidade, nem mesmo com apenas
dois ou trs threads... quanto mais com
as centenas ou milhares que logo sero
exigidos para explorar o potencial das
novas arquiteturas.
No estou dizendo, claro, que a maioria
Rev_Java53_cromo.pdf 10 Rev_Java53_cromo.pdf 10 20/12/2007 16:40:11 20/12/2007 16:40:11
Edio 53 Java Magazine 11
dos programadores no tem competncia
suficiente. O problema que a Programa-
o Concorrente incrivelmente difcil. Se
multiplicarmos as duas dimenses desse
problema um grande nmero de thre-
ads e uma grande quantidade de dados
(objetos, variveis) compartilhados por
vrios desses threads o resultado para
qualquer aplicao de mdio a grande
porte tende a ser um emaranhado infernal
de dependncias.
Garantir a ausncia de deadlocks, livelocks
e race conditions torna-se tarefa herica.
E quando voc conseguir isso, no pode
se dar por satisfeito s porque no tem
bugs de concorrncia. Seu cdigo s
ser realmente bom se for extremamente
escalvel... Isso s ser verdade se voc
fizer poucos locks e por pouco tempo. A
estratgia espalhar synchronized por toda
parte no serve neste caso.
Quer um exemplo ilustrado da encrenca?
Ento carregue seu IDE Eclipse 3.3 com
um workspace bem populado, configure
a view Progress ativando Preferences>Show
sleeping and system operations e dispare
algumas operaes lentas, como um che-
ckout e um rebuild do workspace. Agora
veja a view Progress.
Capturei o resultado dessa experincia
na Figura 1, onde podemos observar
alguns fatos: o nmero de tarefas, a possi-
bilidade de algumas executarem em para-
lelo, dependncias entre tarefas e recursos
(como projetos ou classes), daemons
de execuo peridica e dependncias
dirigidas por eventos (por exemplo, uma
compilao gera eventos de alterao de
recursos no caso os .class que podem
disparar outras tarefas, como um publish
num Server).
Note tambm uma aparente falha de
pintura dos botes vermelhos ao lado di-
reito, os quais permitem cancelar tarefas
ou eliminar da tela as j finalizadas. que
as tarefas so criadas, executadas e removi-
das numa velocidade to grande que essa
view est sempre sendo redesenhada e
quase impossvel conseguir uma captura
de tela perfeita desse frenesi de tarefas.
praticamente um milagre que softwares
dessa complexidade funcionem. Mesmo na
plataforma Java, temos apenas recursos de
baixo nvel: threads e monitores; volatile,
synchronized, wait/notify. Implementar algo
como o Eclipse significa escrever uma
montanha de cdigo adicional para geren-
ciamento de tarefas e recursos, em especial
com a possibilidade de concorrncia.
Por outro lado, para saber se o esforo
vale a pena, basta comparar o Eclipse
com outros IDEs que no possuem esta
arquitetura. Por exemplo, o NetBeans faz
a opo de usar o Ant para a maioria das
atividades de retaguarda compilao,
teste, deploy etc. Mas como o Ant funciona
de forma seqencial
3
, o desempenho ser
sempre o mesmo, no importando se voc
tiver um nico ncleo ou um novssimo
chip quad-core. J o Eclipse poder ser
at quatro vezes mais rpido num sistema
quad-core, simplesmente por explorar
melhor o paralelismo.
Existem vrias solues para o problema
de maximizar o uso de paralelismo de for-
ma acessvel. Vamos a elas, comeando pelas
solues atuais (j amplamente utilizadas) e
avanando para as promessas futuras.
Concorrncia gerenciada pelo Container
A Programao Concorrente mais fcil
aquela que voc no tem que fazer porque
algum faz por voc. Este o modelo que
3 Em tese, o Ant permite criar scripts que executam
vrios targets de forma concorrentes (ver task <parallel>).
Mas essa capacidade rudimentar e no usada pelo
NetBeans.
funciona em milhares de aplicaes ser-
vidoras (sites dinmicos, servidores EJB,
COM, etc.). Neste modelo utilizamos um
servidor de aplicaes (no sentido geral),
que pode ser relativamente simples como
o Apache HTTPD, ou algo mais completo
e ambicioso como um servidor Java EE
cheio de extras como suporte avanado
para clusters, portais, etc.
O servidor de aplicaes administra re-
cursos como threads, conexes de clientes,
e conexes com databases. As aplicaes
so isoladas destes recursos; por exemplo,
o cdigo de aplicao jamais cria ou geren-
cia threads, o servidor de aplicaes que
faz isso. Quando chega uma requisio de
cliente, o servidor de aplicaes obtm um
thread para invocar o cdigo de aplicao.
Se qualquer sofisticao for necessria,
por exemplo usar um pool de threads
para evitar o custo de criaes repetitivas
de threads, o servidor de aplicaes que
assume a tarefa. A sincronizao tambm
assumida pelo servidor de aplicaes por
exemplo, quando threads de vrias aplica-
es solicitam dados do SGBD, o servidor
de aplicaes tem que sincronizar o acesso
a recursos compartilhados, como um pool
de conexes JDBC ou um cache de objetos
com mapeamento O/R.
Este modelo fcil de programar. Basta
ao desenvolvedor seguir a disciplina de
no fazer certas coisas; por exemplo no
Figura 1. Concorrncia numa aplicao atual (Eclipse 3.3)
Rev_Java53_cromo.pdf 11 Rev_Java53_cromo.pdf 11 20/12/2007 16:40:11 20/12/2007 16:40:11
12 Java Magazine Edio 53
Perspectivas em um Mundo Paralelo
ter variveis static que possam ser modi-
ficadas por vrios threads. Ou se precisar
fazer tais coisas raramente, assumir a
tarefa da sincronizao.
Limitaes
Infelizmente, o modelo de concorrncia
gerenciada pelo container limitado. Cada
requisio individual processada por
um nico thread: temos um modelo de
thread-por-request. Isso quer dizer que a
escalabilidade do sistema como um todo
limitada pela concorrncia das solicita-
es, ou seja, pelo nmero de requisies
ou o de clientes simultneos. Estes so os
principais problemas:
%Se voc tiver pouca concorrncia de
requests, no conseguir explorar bem
o hardware.
Por exemplo, considere um servidor
entry-level, digamos um PC bsico, mas
moderno (dual-core) que voc compra por
uns R$ 2.000. Imagine este servidor hospe-
dando um site de e-commerce que atende
a umas 86 mil requisies dirias. Pode
parecer bastante, mas menos de uma re-
quisio por segundo. Para explorar bem a
capacidade do hardware, a aplicao teria
que gastar uma mdia de 2s de CPU por
requisio
4
. Mas isso pouco provvel, a
no ser que sua aplicao seja incrivelmen-
te complexa mesmo com uso de banco de
dados, frameworks de templates e outros
modernismos, mais provvel que seu
consumo de CPU mdio por requisio
no passe de algo como 0,1 segundo.
Isso ruim, porque o tempo de resposta
percebido pelo usurio no ser de 0,1s. O
tempo total no se restringe latncia de
rede (transferncia HTTP entre o browser e
o servidor). Ele inclui tambm todas as la-
tncias internas da aplicao. Por exemplo,
quando a aplicao faz uma consulta ao
banco de dados, a CPU fica praticamente
sem uso enquanto dados so lidos do HD.
Qualquer outro tipo de I/O tem o mesmo
efeito gravao de logs, invocaes remo-
tas a algum servidor de pagamentos ele-
trnicos, aquela integrao com o Google
Maps... Graas a essas operaes, embora
o consumo de CPU seja de 0,1s, a latncia
4 E no apenas 1s, lembrando que a CPU dual-core,
portanto temos dois segundos de CPU por segundo.
mdia poder ser de 1s.
Da o usurio ir dizer:
Que site lento! Enquanto
isso, seu servidor est com
90% de CPU livre!
%Em pouco tempo, isso ser
verdadeiro mesmo para servidores
de alto volume.
O paralelismo do hardware ir au-
mentar mais depressa que o nmero de
usurios das aplicaes. O que aconte-
cer em poucos anos, quando pudermos
comprar um servidor de 100 ncleos pelo
mesmo preo? Numa estimativa grosseira
(ignorando fatores como desempenho
por ncleo, velocidade do HD etc.), esse
servidor poder processar 1.000 requests
por segundo = 86 milhes dirios. Poucas
aplicaes ou sites no mundo possuem este
volume de acessos; por isso provvel que
a sua no seja uma delas, mesmo com o
crescimento continuo do uso da inform-
tica e da internet (esse crescimento, assim
como a corrida dos Gigahertz, tambm j
encerrou a era da curva exponencial).
Alm disso, o desempenho de cada re-
quest individual ir piorar, por vrios moti-
vos. Vamos usar ferramentas cada vez mais
produtivas/de alto nvel e menos eficientes
(no h melhor exemplo que a coqueluche
Ruby on Rails; o Ruby uma das linguagens
mais lentas que conheo). Tecnologias (ou
modas) como Web 2.0, web services/SOA
e outras que viro, exigem cada vez mais
esforo de processamento por transao.
claro, a internet ser cada vez mais rpida,
e no dia em que qualquer usurio tiver um
link de 10Mbps, qualquer atraso ser per-
ceptivelmente culpa do servidor.
Alis, as novas interfaces internet ricas
pioram o problema da ergonomia versus
latncia. Se no antigo modelo o usurio se
conformava a um delay perceptvel para
um evento drstico como a recarga de uma
pgina, com Ajax o usurio s v um deta-
lhezinho sendo modificado por exemplo,
quando pressiona um boto e isso causa
o preenchimento de uma combobox. E
um evento to sutil irritante se no for
instantneo, pois estamos habituados a
isso em aplicaes desktop.
A conseqncia inevitvel de tudo isso
simples: voc ter que atender a cada
request individual com vrios threads,
pois ser a nica forma de melhorar a
latncia, explorando a abundncia de
CPUs/cores disponveis. O modelo de
thread-por-request e a moleza dos threads
gerenciados pelo container esto com os
dias contados.
Bibliotecas de concorrncia avanadas
Se a Programao Concorrente difcil,
pode ser facilitada pela oferta de APIs
mais poderosas. o que acontece com a
java.util.concurrent (JSR-166), disponvel des-
de o J2SE 5.0. Esta API implementa locks
mais poderosos, objetos atmicos, pools
de threads (executores), colees con-
correntes de alto desempenho e diversos
sincronizadores especializados (barrei-
ras, filas bloqueantes etc.). Em resumo,
oferece implementaes de alta qualidade
e reutilizveis do que h de melhor em
algoritmos e tcnicas convencionais de
Programao Concorrente. Isso livra o
desenvolvedor de ter que implementar
estas tcnicas a partir de recursos mais
primitivos.
Esta soluo melhorou um pouco a situ-
ao. E continuar melhorando no Java
SE 7 haver novas melhorias importantes
da java.util.concurrent (das quais falaremos
em outra seo). Mas no uma melhora
de ordens de magnitude; um avano in-
cremental, que s torna as tcnicas atuais
mais fceis e nos ajudar a avanar mais
alguns anos, mas no dcadas. Exceto para
certas aplicaes que sempre exigiro uma
Rev_Java53_cromo.pdf 12 Rev_Java53_cromo.pdf 12 20/12/2007 16:40:11 20/12/2007 16:40:11
Edio 53 Java Magazine 13
abordagem de relativamente baixo nvel,
com alto grau de controle do processamen-
to e do uso de recursos.
Paralelizao Automtica
No seria uma maravilha se alguma
ferramenta, por exemplo o compilador,
transformasse seus algoritmos seqenciais
em paralelos, automaticamente? A boa
notcia que esta tecnologia existe.
n public double calcula (double[] array, double k) {
double total = 0;
for (int i = 0; i < array.length; ++i)
total += array[i] * k;
}
No exemplo n, fcil ver que h uma
seqncia de operaes independentes (ou
seja, que manipulam dados totalmente dis-
tintos): a multiplicao de cada elemento
do array por k. Por outro lado, o resultado
de cada multiplicao dessas somado ao
resultado da multiplicao anterior, e estas
somas parecem ser uma etapa seqencial
do algoritmo. Mas mesmo isso pode ser
paralelizado. Veja uma verso paralela
ideal do cdigo, para quatro CPUs (ou uma
CPU quad-core
5
):
o public double calcula (double[] array, double k) {
double[] total = new double[4];
int fatia = array.length / 4;
parallel-for (int i = 0; i < 4; ++i)
total[i] = calcFatia(array, i * fatia, (i + 1) * fatia, k);
return total[0] + total[1] + total[2] + total[4];
}
private double calcFatia (double[] array, int inicioFatia,
int fimFatia, double k) {
double total = 0;
for (int i = inicioFatia; i < fimFatia; ++i)
total[r] += array[i] * k;
}
A estratgia em o simples: dividimos
o array em quatro fatias, uma por CPU,
e fazemos todos os clculos dessa fatia em
paralelo tanto as multiplicaes quanto a
acumulao parcial dos resultados. Para isso
usamos uma estrutura de controle fictcia,
parallel-for, cujo comportamento consiste em
executar todas as iteraes i=0..3 em paralelo,
cada uma num thread diferente.
Essa estrutura parallel-for no existe em
Java. Poderamos simul-la na unha: basta
criar um novo Thread para cada iterao do
5 Para simplicar, deste ponto em diante usarei apenas
N CPUs ao invs de N CPUs ou Ncores/ncleos.
loop, iniciar esses threads com start(), calcu-
lar cada fatia no run() dos threads, e aps o
final do loop, usar join() em cada thread para
esperar que todos terminem. Ou voc pode
usar uma API mais recente, java.util.concurrent,
que facilitar esse tipo de programao
(dica: use um Executor e uma CyclicBarrier).
O problema que mesmo a verso o, com a
sintaxe super-fcil que inventei, trabalho-
sa. Alm de exigir fazer alteraes pesadas
no cdigo original, ser necessrio iden-
tificar manualmente a computao que
pode ser paralelizada e como paraleliz-la
(dividir os dados em fatias, consolidar os
resultados parciais). E isso porque no
contemplei complicaes como a possibi-
lidade de array.length no ser um mltiplo
exato do nmero de CPUs, ou escolher o
nmero de fatias de forma tima para o
nmero de CPUs disponveis.
A boa notcia qual me referia que
existem compiladores que so capazes de
transformar a primeira listagem na segun-
da, de forma automtica. Estes compilado-
res geralmente suportam linguagens como
C, C++ e Fortran. Em especial, os compila-
dores da Intel e da Sun tm puxado a fila.
O suporte para Java no deve demorar,
pois essa otimizao j foi implementada
em JVMs de pesquisa (mas ainda no em
JVMs de produo).
Limitaes
A m notcia que esta tecnologia tam-
bm limitada. Tipicamente, compiladores
s conseguem paralelizar automaticamen-
te algoritmos simples. Basta que aquele
nosso loop original de duas linhas se
transforme numa pgina inteira de cdi-
go, acessando estruturas de dados muito
mais complexas do que um simples array,
e voltamos estaca zero. Isso porque os
compiladores no possuem inteligncia
para entender qualquer trecho de cdigo
alm do trivial.
Paralelizao automtica com linguagens
funcionais
Para a paralelizao automtica ser
realmente eficaz, precisamos de novas
linguagens ou construes. Por exemplo,
veja o seguinte cdigo:
p total := reduce(+, map(*, array, k))
Isso parecer estranho a programadores
Java, mas natural para quem j teve
contato com linguagens funcionais (como
LISP, Scheme, ML, Haskell e vrias outras).
Mesmo que voc no conhea linguagens
desta espcie, no difcil entender o
cdigo em p:
1. A funo map(f, col, args...) recebe como
argumentos uma funo f, uma coleo col
que fornecer o primeiro argumento para
f, e argumentos adicionais fixos args... para
f. O map() aplica f (no caso o operador *)
6
a
todas as listas de argumentos (col[n], args...).
O resultado ser uma coleo de valores:
array[0] * k, array[1] * k, ..., array[n-1] * k.
2.A funo reduce(f, col) recebe argumentos
parecidos, mas o comportamento dife-
rente. Ela calcula f(col[0], ..., f(col[n-2],
col[n-1])...)). No exemplo, isso ser: array[0] +
... + array[n-2] + array[n-1].
Trocando em midos, o que aquela nica
linha de cdigo executa pode ser enuncia-
do assim:
Multiplique cada elemento de array por k,
e some os resultados de todas essas multipli-
caes.
Por exemplo, se array = [0, 17, -1, 3] e k = 2,
ento
total = reduce(+, [0 * 2, 17 * 2, -1 * 2, 3 * 2])
= reduce(+, [0, 34, -2, 6])
= 0 + 34 + -2 + 6
= 38.
Mas por que estamos gastando espao
explicando uma linguagem totalmente
diferente de Java? Porque fcil mostrar
que o estilo funcional de programao
facilita muitas coisas... pelo menos para
os compi ladores. Basta que o leitor
observe que no enunciado acima no
existe nenhuma dependncia temporal. O
mesmo se d com o cdigo p, o qual no
possui qualquer especificao explcita
da ordem de execuo das operaes. Re-
petindo parte do enunciado, multiplique
cada elemento de array por k, no estamos
dizendo em que ordem estas multiplica-
es devem acontecer. Isso significa que
o compilador tem a liberdade de realizar
as multiplicaes na ordem que quiser,
6 Um operador binrio pode ser visto como uma fun-
o de dois argumentos.
Rev_Java53_cromo.pdf 13 Rev_Java53_cromo.pdf 13 20/12/2007 16:40:12 20/12/2007 16:40:12
14 Java Magazine Edio 53
Perspectivas em um Mundo Paralelo
e tem a liberdade de executar todas ao
mesmo tempo, em paralelo.
J no cdigo n em Java, as estruturas de
controle como o for manifestam a ordem de
execuo de cada etapa do processamento
de forma explcita: devemos calcular pri-
meiro array[0] * k, depois array[1] * k e assim
por diante. Isso significa que o compilador
no possui, em princpio, a liberdade de re-
ordenar operaes, nem (por conseqncia)
de execut-las em paralelo.
Para que a paralelizao automtica
seja vivel numa linguagem como Java, o
compilador precisa deduzir que a ordem de
execuo de cada etapa do loop no im-
portante. Esta deduo muito difcil, pois
exige que o compilador perceba que cada
etapa do processamento, no caso cada itera-
o do for, possua independncia de dados em
relao s demais. Ou seja, que cada etapa
manipula dados disjuntos dos usados pelas
demais etapas. Esta independncia nem
sempre existe. Veja este exemplo:
qpublic double[] fib (int n) {
double[] array = new double[n];
array[0] = array[1] = 1;
for (int i = 2; i < n; ++i)
array[i] = array[i-2] + array[i-1];
return array;
}
O mtodo fib() retorna um array preenchi-
do com a famosa seqncia de Fibonacci:
[1, 1, 2, 3, 5, 8, 13...]. O loop for deste algorit-
mo no possui independncia de dados,
pois cada iterao usa como dados de
entrada os resultados das duas iteraes
anteriores. Por isso, a paralelizao parece
impossvel.
O dilema que o compilador precisa
diferenciar os cdigos que possuem in-
dependncia de dados, como n, dos que
no possuem esta propriedade, como q.
Numa linguagem imperativa como Java,
essa diferenciao extremamente difcil.
J em linguagens funcionais, isso trivial.
No s devido ao uso de estruturas de
controle como map() e reduce(), mas princi-
palmente porque as linguagens funcionais
no possuem atribuio destrutiva. Uma
atribuio destrutiva a modificao de
uma varivel que j estava associada a um
valor anterior, por exemplo:
r x = 10;
s x = 10; x = 20;
Numa linguagem como Java, os dois
trechos r e s so obviamente vlidos. J
numa linguagem funcional, somente r
legal. A linha s ilegal, porque no se pode
alterar o valor associado a uma varivel (ou
a um elemento de uma coleo): todas as
variveis, aps inicializadas, so imutveis.
Uma conseqncia natural da imutabili-
dade que todas as operaes individuais
realizadas por uma funo possuem
independncia de dados. Se voc exami-
nar novamente o exemplo q, ver que a
dependncia de dados s existe porque
array est sendo continuamente modificado.
Caso array fosse imutvel, esta dependncia
no existiria. J no cdigo n, no incio da
seo, array no alterado, s lido. Por isso
mais fcil provar que este cdigo possui
independncia de dados. (O cdigo n ainda
tem uma varivel total, que sofre atribuies
destrutivas; isso quer dizer que o esforo de
um compilador com paralelizao autom-
tica ser menor, porm no trivial.)
Uma curiosidade: veja como implemen-
tamos o mtodo fib(n) numa linguagem
funcional:
t fib (0) = []
fib (1) = [1]
fib (2) = [1, 1]
fib (n > 1) = fib(n - 1) : (last(fib(n - 2)) + last(fib(n - 1)))
Observe que usamos recurso. O resultado
da funo uma constante para os argumen-
tos 0, 1 e 2, e para qualquer argumento n>1,
retornamos a concatenao (:) entre fib(n - 1)
(invocao recursiva) e um novo elemento,
que ser a soma entre os ltimos elementos
de fib(n - 2) e de fib(n - 1) (mais invocaes re-
cursivas). A recurso a nica estrutura de
iterao das linguagens funcionais.
Note que no cdigo t acima, existe uma
exigncia explcita de ordem de execuo e
de dependncia de dados. Por exemplo, o
clculo de fib(10) depende dos clculos de
fib(8) e fib(9), que devem ser realizados an-
tes. Por isso, a paralelizao no parece ser
possvel. Mas, pelo menos, isso tambm
fcil de ser identificado pelo compilador.
A regra simples (em linguagens funcio-
nais): Qualquer uso de recurso gera depen-
dncia de dados; e qualquer outra operao no
gera dependncia de dados.
Numa linguagem funcional, a parale-
lizao sempre possvel, mesmo com
dependncia de dados. Por exemplo, em
t, aquelas trs invocaes recursivas a
fib() poderiam ser realizados de forma
paralela, com um thread para cada uma.
Ou melhor: duas invocaes paralelas,
pois fib(n - 1) usado duas vezes, mas como
o resultado ser sempre o mesmo
7
basta
fazer esta invocao uma vez. Na prtica,
porm, a paralelizao de invocaes
recursivas difcil, pois corre o risco de
gerar um nmero de threads muito alto,
e incompatvel com outras otimizaes
crticas em linguagens funcionais (em es-
pecial, a recurso costuma ser eliminada
sem isso, uma anlise aprofundada do
exemplo t mostraria que este cdigo seria
extremamente ineficiente).
Tudo isso que discutimos pode ser resu-
mido da seguinte forma:
%Em linguagens imperativas como Java,
a paralelizao automtica possvel, mas
dificlima.
%Em linguagens funcionais, a paraleli-
zao automtica extremamente fcil. A
nica exceo sendo recurso (e mesmo
neste caso, mais fcil do que em lingua-
gens imperativas).
%Conseqentemente, os adeptos de
linguagens funcionais esto em grande
vantagem para explorar arquiteturas
massiamente multi-core, que exigiro
paralelizao intensa.
Uma nova esperana para Java (I):
Imutabilidade
Se neste ponto do artigo voc est de-
sanimado com este problema do Java e
qualquer outra linguagem imperativa,
incluindo C/C++, C# etc. e j planejando
aprender Haskell e cancelar sua assinatura
desta revista, no se precipite! Ainda h
muitas coisas que podemos fazer.
A atitude mais bvia simplesmente
copiar algumas caractersticas das lingua-
7 Este fato tambm um bnus das linguagens fun-
cionais: o valor de retorno de uma funo s depende
dos argumentos. Em linguagens imperativas isso no
garantido, devido atribuio destrutiva. No exemplo a
seguir, o valor retornado por next() ser diferente a cada
invocao, ainda que os argumentos (no caso, nenhum)
no variem, devido atribuio destrutiva de n.
class Contador {
private int n = 0;
public int next () { return n++; }
}
Rev_Java53_cromo.pdf 14 Rev_Java53_cromo.pdf 14 20/12/2007 16:40:12 20/12/2007 16:40:12
Edio 53 Java Magazine 15
gens funcionais. O resultado no seria um
programa puramente funcional; seria algo
hbrido
8
, talvez bom o suficiente para per-
mitir que o compilador realize otimizaes
como a paralelizao automtica.
A principal coisa que podemos fazer
trabalhar com variveis imutveis, para
ajudar o compilador a determinar a depen-
dncia de dados. Veja este exemplo:
upublic double calcula (final double[] array, final double k) {
double total = 0;
for (int i = 0; i < array.length; ++i)
total += array[i] * k;
}
8 Mesmo as linguagens funcionais ditas puras nunca
so 100% funcionais. Qualquer aplicao no-trivial pre-
cisa de pelo menos um mnimo de estado mutvel. Ou-
tro problema realizar qualquer tipo de I/O, que algo
intrinsecamente destrutivo. Mas as melhores linguagens
funcionais tm mecanismos para isolar o cdigo no
funcional (por exemplo as mnadas do Haskell), de tal
forma que esta parte do cdigo ca muito bem identi-
cada e segregada, e o compilador s precisa reservar oti-
mizaes como paralelizao automtica para as partes
puramente funcionais.
Comparando os cdigos n e u, a dife-
rena que este ltimo declara como final
as variveis que no sofrem atribuio
destrutiva. Isso significa que o compilador
no precisa fazer nenhum esforo para
saber se existe alguma dependncia de
dados envolvendo estas duas variveis
9
.
O compilador ainda ter que se esforar
para determinar as dependncias de da-
dos que envolvem as variveis no-final,
como total e i, e os elementos individuais
de array
10
. Mas pelo menos, reduzimos um
pouco o trabalho do compilador. Isso tor-
na a paralelizao automtica um pouco
mais fcil.
9 Do ponto de vista do compilador no h diferena
entre parmetros, variveis locais e atributos tudo
varivel.
10 Infelizmente, o final do Java no pode ser aplicado
aos elementos de um array, s referncia para o array.
No possvel especicar que o contedo de um array,
aps ser inicializado, nunca mais ser mudado. Esta uma
decincia grave, mas no seria difcil corrigi-la no futuro,
por exemplo com uma anotao (ex.: @FinalElements).
A paralelizao automtica no a nica
otimizao que se beneficia de variveis
final e objetos imutveis (ou seja, objetos
que s possuem atributos final). Existem
vrias outras, por exemplo:
vpublic double f (Point p) {
return p.x * g(p) - p.x;
}
No mtodo f() do cdigo v, se os atribu-
tos x, y de Point forem final, o cdigo gerado
pelo compilador ser mais eficiente. Por
que isso? que normalmente, parmetros
e atributos precisam ser lidos da memria
(sendo que os parmetros ficam na rea de
stack e atributos ficam no heap). Leituras
repetitivas da memria so caras, por isso
o otimizador tentar manter os valores das
variveis usadas por um mtodo em regis-
tradores, cujo acesso muito mais rpido.
O problema que, em f(), temos dois aces-
sos varivel p.x, e no meio destes acessos
h uma invocao ao mtodo g() que recebe
Rev_Java53_cromo.pdf 15 Rev_Java53_cromo.pdf 15 20/12/2007 16:40:12 20/12/2007 16:40:12
16 Java Magazine Edio 53
Perspectivas em um Mundo Paralelo
p. Supondo que o compilador no saiba
nada sobre g() (pois est otimizando f()
de forma isolada
11
), o compilador deve
ser conservador e supor que g() poder
alterar p.x. Por isso, o cdigo gerado para
f() (se x e y no forem final) ser algo assim
(em pseudocdigo, para nos poupar de
Assembly):
public double f (Point p) {
R1 = READ[p];
return READ[R1.x] * g(R1) READ[R1.x];
}
Embora p.x j tenha sido lido da me-
mria antes da invocao a g(), aps esta
invocao precisamos repetir essa leitura,
pois o compilador no sabe se g() alterou
o valor desta varivel. Por outro lado, se
a classe Point definisse x e y como final, o
cdigo seria:
public double f (Point p) {
R1 = READ[p];
R2 = READ[R1.x];
return R2 * g(R1) R2;
}
Na nova verso, a leitura de p.x s feita
uma vez, mantendo-se um cache desta
varivel no registrador R2. Aps a invoca-
o a g(), podemos continuar usando o va-
lor j carregado em R2, pois sabemos que
p.x no pode ter mudado, j que final.
E no s isso: outra oportunidade que
as variveis final nos do , novamente, na
Programao Concorrente mesmo sem
paralelizao automtica. Explico. Suponha
que voc tem vrios threads acessando
determinado objeto compartilhado. Se
este objeto for mutvel, ou seja, se ele
possuir atributos no-final e setters ou ou-
11 O que o caso comum quando no ocorre inlining.
tros mtodos que alteram estes atributos,
voc ser obrigado a sincronizar o acesso
a este objeto. Ser preciso usar synchronized
em algum lugar. Porm, se o seu objeto
for imutvel, no preciso sincronizar
o acesso a ele nunca. Vrios threads
podero usar o mesmo objeto sem usar
nenhum synchronized. Elimina-se, assim, o
custo desta sincronizao.
Uma nova esperana para Java (II):
Novos frameworks para paralelismo
J dissemos que bibliotecas como a
java.util.concurrent so uma melhoria incre-
mental, que no mudam o paradigma de
Programao Concorrente. Podem facilitar
o nosso trabalho no paradigma ou lingua-
gem atual, mas no podero dar o salto
exigido pelas arquiteturas massiamente
paralelas. Mostramos um novo paradigma
a programao funcional que permite
este salto. Porm, vimos tambm que po-
demos adotar em Java algumas tcnicas
deste paradigma, como a imutabilidade.
No seria possvel, talvez, ir mais alm
nesse caminho, com outros truques que
tragam ainda mais vantagens da progra-
mao funcional para o Java, mas sem ter
que mudar de linguagem?
Isso pode ser possvel, sim, e tiraremos
a prova quando o Java SE 7 for disponibi-
lizado. Esta nova verso do Java ter uma
java.util.concurrent estendida com um grande
nmero de novas classes, que constituem o
chamado Fork-Join Framework. De forma
resumida, este framework implementa em
Java um novo paradigma de Programao
Concorrente que utiliza princpios de pro-
gramao funcional. Veja este exemplo:
w public double calcula (final ParallelArray<Double> array,
final double k) {
return array.withMapping( { Double d => d * k } ).sum();
}
Se voc acompanhou todo este artigo
at aqui, no ter dificuldade de enten-
der o cdigo w. O mtodo withMapping()
equivalente ao map() que vimos em p. A
expresso entre {} uma closure. (Closures
so um novo recurso da linguagem Java
planejado para o Java SE 7, que no temos
espao para explicar aqui, mas so algo
como inner classes melhoradas.) O mtodo
sum() faz as vezes do reduce() de p. O efeito
da expresso inteira, uma vez conhecendo
a nova API, intuitivo: retorna a soma
das multiplicaes de cada elemento de
array por k. E interessante observar que a
sintaxe quase to simples quanto das
linguagens funcionais, com operaes
map() e reduce() nativas.
Outro detalhe importante que os dados
de entrada para a computao no so
recebidos na forma de um array primitivo
ou mesmo de uma coleo comum. Estes
dados vm na forma de um ParallelArray,
uma coleo especial para computaes
paralelas. Acompanhe a seqncia de
eventos que acontece quando o mtodo
calcula() de w executado:
1. O mtodo withMapping() no executa
computao alguma. Este mtodo, bem
como alguns outros do framework, s
constri objetos que descrevem a compu-
tao que ser feita.
2. Somente quando o mtodo de redu-
o invocado, no caso sum(), a compu-
tao ser iniciada, de fato, com as etapas
a seguir.
3. O framework analisa o array paralelo
e a estrutura de computao (que no caso
simples: um mapeamento seguido de
uma reduo), e verifica quantas CPUs
so disponveis. Com estas informaes,
o framework decide quantas CPUs sero
usadas (= grau de paralelismo).
4. Fork: O framework cria vrios threads,
um para cada fatia do array. Cada thread
ir executar uma parte da computao
(tanto o mapeamento, que totalmente
independente para cada elemento do array,
quanto a reduo, que neste caso permite
executar uma soma parcial dos resultados
de cada mapeamento para depois agregar
as somas parciais.)
5. Join: O framework aguarda o trmino
de todos os threads, cada um dos quais re-
tornando um resultado parcial da reduo.
Esses resultados parciais so combinados
Rev_Java53_cromo.pdf 16 Rev_Java53_cromo.pdf 16 20/12/2007 16:40:13 20/12/2007 16:40:13
Edio 53 Java Magazine 17
numa reduo final. Isso produz o resul-
tado final da computao.
Essa explicao mostra uma soluo
engenhosa para o problema da paraleliza-
o em Java: ao invs de responsabilizar
o runtime (no caso o compilador JIT) por
fazer esta otimizao de forma totalmente
automtica (coisa que extremamente dif-
cil para uma linguagem como Java, como
j vimos), divide-se a responsabilidade
entre trs entidades: um framework, o
programador e o runtime:
%O programador deve organizar os
dados de entrada da computao numa
coleo especial, como ParallelArray. Deve
tambm codificar a computao utili-
zando uma composio de operaes do
framework, como withMapping() e sum().
possvel usar closures para trechos de com-
putao ad-hoc, portanto, esta composio
no limitada s operaes primitivas
do framework. No entanto, estas closures
devem conter cdigo em estilo funcional,
ou seja: sem dependncia de dados, sem
atribuies destrutivas, e de preferncia
usando apenas objetos imutveis.
%O framework se encarrega de estruturar
a computao de forma paralela, fatian-
do os dados de entrada, criando threads
e os coordenando. Tambm responsvel
por vrias otimizaes, como usar um pool
de threads para evitar o custo de criaes
de threads repetitivas, e coordenar os thre-
ads de forma ultra-leve sem praticamente
nenhum custo de sincronizao (essas
otimizaes usam recursos j existentes
da API java.util.concurrent, como Executor e
objetos atmicos).
%O runtime responsvel por otimi-
zaes de baixo nvel exigidas pelo fra-
mework.
O resultado que temos uma soluo de
paralelizao semi-automtica bastante
interessante: eficiente e razoavelmente
fcil de usar. E principalmente, que no
exige do otimizador um esforo enorme
e talvez invivel, que vimos ao discutir a
paralelizao totalmente automtica.
O leitor ter entendido, agora, a minha
inteno desde o incio deste artigo: no
se trata de criticar a linguagem Java e
promover outras linguagens; os Java-
fanticos (como eu) podem guardar os
tomates e ovos podres. A minha inteno
era prepar-los para uma nova ordem,
na qual determinadas tcnicas se tornaro
extremamente importantes, seja qual for a
linguagem. verdade que as linguagens
funcionais puras saem na dianteira, pois
tm propriedades que facilitam enorme-
mente o paralelismo automtico. Mas
todas as linguagens possuem vantagens
e desvantagens; as linguagens funcionais
tm os seus problemas. Se no tivessem,
no seriam to pouco populares quase 50
anos aps a inveno do LISP.
O futuro do qual falamos no distante.
As CPUs multi-core j so uma realidade,
e o nmero de cores/ncleos ir aumentar
rpido. O Java SE 7, com seu Fork-Join
Framework, j est em desenvolvimento,
e estar disponvel talvez apenas um ano
aps voc ler esta edio. Mas para quem
no tiver familiaridade com conceitos de
programao funcional, este framework
parecer uma API complexa, cheia de
conceitos exticos e fcil de usar de
forma incorreta. Os programadores que
tero facilidade e sucesso em us-la sero
os que tiverem absorvido a mudana de
paradigma.
STM (Software Transactional Memory)
Agora vamos explorar outra idia ra-
dicalmente inovadora. Que tal se nunca
precisssemos fazer lock de nada, mesmo
com dados mutveis? Essa a proposta da
STM, ou Memria Transacional.
Thread 1: synchronized (...)
{ // begin transaction
x = x + 10; y = x + 20;
} // end transaction
Thread 2: synchronized (...)
{ // begin transaction
x = x + 99; y = y + 77;
} // end transaction
O exemplo parece cdigo Java comum,
com atribuio destrutiva e com o uso
de blocos synchronized para guardar sees
crticas de cdigo. A grande diferena
que estes blocos no fazem lock algum. O
que eles fazem, em vez disso, iniciar uma
transao no incio e fechar a transao
no final. Com a STM, toda a memria de
objetos do Java (heap e stack) como um
banco de dados transacional: alteraes
feitas por um thread s sero visveis por
outros threads aps um commit.
Se acontecer concorrncia real ou seja,
se os threads 1 e 2 executarem os trechos
de cdigo indicados ao mesmo tempo o
que acontece? Ambos os threads entram
nos blocos synchronized ao mesmo tempo;
nenhum deles fica bloqueado. Mas nenhum
deles altera as variveis x e y; o que eles
alteram so cpias dessas variveis numa
regio de memria privada a cada thread/
transao. (Esta regio, assim como em
SGBDs, chamada log de transaes.)
Somente ao final da transao, estas alte-
raes so copiadas atomicamente para as
variveis x e y.
Porm, quando existe conflito de updates
entre duas transaes, s uma delas po-
der fazer commit com sucesso. Digamos
que o thread 1 chegue primeiro no final
do bloco (comentado com end transacion;
este thread far o commit normal. Quando
o thread 2 chegar no final do seu bloco
sincronizado e tentar fazer a mesma coisa,
a JVM ir detectar o conflito: este thread
possui updates de variveis que foram atu-
alizadas por outra transao que executou
concorrentemente. Ento, a transao do
thread 2 sofre um rollback. O programador
no precisa tomar nenhuma providncia
na verdade, nem fica sabendo deste
rollback pois aps o mesmo, o thread
faz um retry automtico da transao. Ou
seja, o processamento volta ao incio do
bloco synchronized, e comea a execut-lo de
novo (s que dessa vez, comeando com os
valores de x e y setados pelo thread 1).
Utilizamos o velho synchronized para
ilustrar esta tcnica, pois de fato existem
implementaes disso para Java (em JVMs
de pesquisa) que exploram o synchronized
para demarcar transaes. Neste caso,
o objeto que usado como lock pelo
synchronized totalmente ignorado. Isso
deselegante, mas tem a vantagem de no
exigir nenhuma alterao em cdigo lega-
do. Outros pesquisadores preferem propor
uma nova sintaxe: atomic { cdigo }, sendo que
a nica diferena que o bloco atomic no
possui a clusula (lock). uma sintaxe mais
limpa, mas que exigiria modificaes de
cdigo preexistente e tambm tornaria
a STM obrigatria, enquanto o reuso do
synchronized permite que a STM seja mero
Rev_Java53_cromo.pdf 17 Rev_Java53_cromo.pdf 17 20/12/2007 16:40:13 20/12/2007 16:40:13
Perspectivas em um Mundo Paralelo
18 Java Magazine Edio 53
detalhe de implementao: o mesmo c-
digo funcionaria em JVMs mais velhas
fazendo locks, e em JVMs mais recentes
com memria transacional.
Uma mozinha do hardware: HTM
Voc pode estar se perguntando se, assim
como a paralelizao totalmente autom-
tica, a STM no parece algo bom demais
para ser verdade... deve haver um porm.
Existe sim, mas est desaparecendo: o
custo de tratar o heap inteiro de forma
transacional; em especial, o custo de trans-
formar todas as atribuies destrutivas em
alteraes de um log de transao, e ao
final das transaes, o custo de detectar
conflitos com outras transaes.
Estes custos esto destinados a desapa-
recer, pois j comeam a surgir CPUs que
implementam transaes por hardware
(HTM Hardware Transactional Memory). A
prpria CPU implementa um pequeno log
de transaes, bem como o suporte bsico
para commit, rollback e deteco de confli-
tos. Isso pode parecer um abuso, mas quem
conhece arquiteturas de CPUs sabe que, na
verdade, as CPUs modernas j possuam a
maior parte dos recursos para implemen-
tar estas operaes, bastando melhorias
relativamente pequenas para dar suporte
a transaes. Especificamente:
1) Os caches L1, que j intermedeiam as
alteraes da RAM (ou de outros caches
acessveis s demais CPUs), podem ser
usados facilmente para implementar um
log de transaes;
2) Os protocolos de coerncia de cache
podem ser explorados para detectar con-
flitos entre transaes. Esses protocolos
executam no barramento do sistema, em
mquinas com mais de uma CPU, para sin-
cronizar alteraes de memria realizadas
nos caches privados de CPUs diferentes.
Transaes Hbridas
A desvantagem da HTM que limita-
da por parmetros rgidos do hardware.
Ento, se o cache L1 de uma CPU for de
16Kb, este ser o tamanho mximo do log
de transaes; portanto, nenhuma tran-
sao individual poder ter um change set
(conjunto de posies de memria modifi-
cadas) maior que 16Kb de dados.
Mas a soluo para este problema
simples. Verificou-se que, na prtica, a
maioria das transaes possui um change
set pequeno. Estas transaes portanto
sero satisfeitas pela HTM. Para as poucas
transaes cujo change set exceder a capa-
cidade de HTM, a CPU ir gerar uma falta
(fault) de hardware, capturada pela JVM.
Ento, a JVM ir executar aquela transao
por software (STM), com um log mantido
na RAM. Este modelo hbrido tem de-
sempenho mdio quase igual ao da HTM
pura, pois as transaes que precisam de
execuo por software so raras.
Esta tcnica est um pouco mais alm
no horizonte, se comparada s outras que
exploramos. J existem muitos relatrios
de pesquisa (papers) descrevendo JVMs
com STM, e tambm CPUs recentes com
implementaes preliminares de HTM.
Sendo mais concreto, a Sun uma das em-
presas que tem investido nessa tecnologia,
possuindo inclusive patentes importantes
sobre HTM. muito provvel que JVMs
futuras da Sun para SPARC/Solaris imple-
mentem o modelo hbrido de STM+HTM.
Mas trata-se de especulao para o Java
SE 8. Isso sendo otimista, pois estamos
falando de uma grande revoluo, que
para ser completa precisar ser suportada
por todo o stack de hardware e software.
Por exemplo, seria necessria uma nova
verso do Solaris adaptada para tambm
tirar proveito de memria transacional (ou
pelo menos, para auxiliar processos que
faam isso, como uma JVM).
Ainda mais vantagens para programao
funcional
Finalmente, se voc acha que com a STM
se livrou de aprender conceitos de progra-
mao funcional, no tenha tanta esperan-
a. Entre todos os trabalhos que j foram
publicados sobre o assunto, o mais im-
pressionante o paper Composed Memory
Transactions, que aborda a implementao
de STM para Haskell. No entraremos em
detalhe, mas as mesmas qualidades que
tornam as linguagens funcionais ideais
para outras otimizaes vistas em sees
anteriores, tambm so ideais para a
STM. As linguagens funcionais permitem
implementar a STM de forma muito mais
eficiente (at mesmo dispensando a ajuda
da HTM) e de forma ao mesmo tempo
mais poderosa e elegante.
Os fornecedores de plataformas de
desenvolvimento no esto desligados
desta tendncia. Uma das respostas
o j comentado Fork-Join Framework
do Java SE 7. Outra melhoria prevista
para o Java SE 7 a implementao de
tail calls na JVM. De forma simples, isso
permitir codificar mtodos recursivos
com desempenho muito melhor e sem o
risco de StackOverflowException. Dessa forma,
programas Java podero usar e abusar de
recurso no lugar de loops, imitando ainda
mais tcnicas comuns em programao
funcional. Isso tambm beneficiar im-
plementaes de linguagens funcionais
para a JVM.
Rev_Java53_cromo.pdf 18 Rev_Java53_cromo.pdf 18 20/12/2007 16:40:13 20/12/2007 16:40:13
Edio 53 Java Magazine 19
Mas o futuro no reserva apenas estes
passos incrementais. Existe tambm inves-
timento em novas linguagens funcionais.
Por exemplo, a Sun est elaborando uma
nova linguagem chamada Fortress (es-
pecializada em computao numrica de
alto desempenho), que uma linguagem
funcional hbrida.
Tambm o caso da linguagem Scala.
Esta uma iniciativa da comunidade open
source, e uma variante do Java com facili-
dades como inferncia de tipos e recursos
de programao funcional. Tanto Fortress
quanto Scala geram bytecode Java que exe-
cuta em JVMs e interopervel com classes
Java comuns. E na plataforma .NET, a Mi-
crosoft oferece o F#, uma nova linguagem
funcional (derivada de OCaml).
Ainda cedo para dizer se estas novas
linguagens tero sucesso, mas suficiente
verificar que os fornecedores de tecnologia
da Sun Microsoft comeam a lev-
las muito a srio, no mais defendendo
religiosamente suas linguagens primrias
(como Java ou C#). Preferem abrir o leque
das linguagens para manter a relevncia
e a competitividade das plataformas e
frameworks subjacentes.
Concluses
Em fruns e blogs que discutem propos-
tas como as novidades sintticas planejada
para o Java SE 7, comum vermos opinies
mais conservadoras reclamando que im-
portar para o Java recursos como closures
ir estragar a simplicidade de algo que j
bom. Essas crticas no deixam de ter
algumas razes, mas se as examinarmos
bem, elas mostram grande falta de viso.
A linguagem Java, do jeito que est hoje,
no boa o bastante para atravessar os pr-
ximos dez ou vinte anos provavelmente,
nenhuma linguagem atual . As linguagens
de programao so como as espcies vi-
vas que, como j disse Darwin, devem se
adaptar com o tempo ou se extinguir.
Existe um ritmo e um processo saudveis
para esta evoluo; por exemplo, as melho-
rias sintticas que j tivemos na linguagem
Java, como as introduzidas no Java 5, sem-
pre foram elaboradas de forma a manter a
compatibilidade com todo o cdigo e APIs
preexistentes, e at facilitar a migrao
destas APIs. As prximas novidades, seja
Osvaldo Pinali Doederlein
(opinali@gmail.com)
Mestre em Engenharia de
Software Orientado a Objetos,
membro individual do Java Community
Process e trabalha na Visionnaire Informtica como
arquiteto e desenvolvedor.
no Java SE 7 ou em
verses futuras, no
sero diferentes.
O leitor mais descon-
fiado no precisa se pre-
ocupar. O J ava que voc
conhece e gosta no ser des-
caracterizado ou abandonado.
S haver um tempo de adaptao
para absorver novos conceitos. Uma
opo alternativa, e mais ousada,
partir de uma vez para solues
mais definitivas como linguagens
totalmente diferentes. preciso avaliar
bem esta opo, pois uma linguagem de
programao possui muitos aspectos
importantes. Paralelismo no tudo, e
h muitas razes pelas quais o Java pos-
sui sua atual presena no mercado. Mas
mesmo que esta opo radical prevalea
no longo prazo, certo que a platafor-
ma Java ir evoluir de forma a receber
novas linguagens de braos abertos.
jcp.org
JSRs que podero fazer parte do Java SE 7. J disponveis:
277 (Mdulos), 292 (invokedynamic), 294 (Superpa-
ckages), 295 (Beans Binding), 296 (Swing Application
Framework), 303 (Validao de Beans), 305 (Anotaes
para Deteco de Erros), 308 (Anotaes para Tipos), 310
(Ne.+ ||| a+r+ a+t+./temae., 1I (I|| z.. I+m|em
haver atualizaes da JSR 166 (java.util.concurrent) e
talvez outras JSRs/APIs.
www.javac.info
Propostas para melhorias de sintaxe no Java SE 7,inclusive
closures (ainda sem JSR).
ksl.dev.java.net
Kitchen Sink Language,projeto de laboratrio para novos
recursos da linguagem Java
haskell.org/haskellwiki/Research_papers
Papers de pesquisa sobre a linguagem Haskell, ver em
especial a seo Parallelism and Concurrency.
www.gotw.ca/publications/concurrency-ddj.htm
Artigo The Free Lunch is Over, de Herb Sutter.
amazon.com/Java-Concurrency-Practice-Brian-
Goetz/dp/0321349601
Java Concurrency in Practice, o melhor livro sobre o
estado da arte em programao concorrente para Java.
Inclui tcnicas como imutabilidade.
planetjdk.org
Blogs sobe o futuro do Java.
gee.cs.oswego.edu/dl/concurrency-
interest
JSR-166y com implementao preliminar e javadocs
do Fork-Join Framework.
gcc.gnu.org/projects/tree-ssa/vectorization.
html
Informaes sobre o progresso da implementao de
otimizaes de paralelizao automtica (via instrues
SIMD) no GCC, suite de compiladores livres (incluindo o
GCJ para Java).
labs.google.com/papers/mapreduce.html
Paper MapReduce: Simplified Data Processing on Large
Clusters, explica como o Google paraleliza tarefas de pro-
cessamento gigantesca (dezenas de terabytes) em clusters
gigantescos (milhares de mquinas) com princpios de
programao funcional.
www.intel.com/technology/itj/2007/v11i4
Edio da Intel technology Journal dedicada a Multi-Core
Software. Inclui artigos sobre compiladores com parale-
lizao automtica.
jikesrvm.org/Publications
Papers sobre pesquisa de JVM (com a VM de pesquisa open
source JikesRVM); inclui vrios papers sobre STM.
research.sun.com/spotlight/2007/2007-08-
13_transactional_memory.html
Resume as pesquisas da Sun sobre STM,HTM e TM hbrida
(siga o link para os papers).
Rev_Java53_cromo.pdf 19 Rev_Java53_cromo.pdf 19 20/12/2007 16:40:14 20/12/2007 16:40:14
20 Java Magazine Edio 53
Wireless Update
Android vai de Java
E
m novembro deste ano, foi anun-
ciada a criao da Open Handset
Alliance, um grupo com mais de
trinta empresas que tem o objetivo de
construir uma plataforma aberta, nova
e mais rica para aparelhos celulares. O
grupo inclui operadoras de telefonia, fa-
bricantes de chips e de celulares e empre-
sas de software. Participam, entre outras
empresas, Google (na liderana), T-Mobile,
Telefonica, TIM, LG, Motorola, Samsung,
Intel e NVidia.
Essa aliana disponibilizou a plataforma
Android (tambm chamada de Google An-
droid), que inclui um sistema operacional,
aplicaes intermedirias e servios-chave
para celulares, como agenda, envio/recep-
dispositivo possa executar mltiplas m-
quinas virtuais eficientemente.
importante destacar que o Android no
compatvel com nenhuma das platafor-
mas ME, SE ou EE. Trata-se, na verdade,
de uma variante que suporta vrias partes
do Java, como a sintaxe da linguagem,
o modelo de segurana e algumas APIs
(sendo estas complementadas pelas APIs
android.*). Isso torna o Android familiar e
fcil de dominar para milhes de desen-
volvedores Java, os quais basicamente s
precisaro aprender algumas novas APIs
e ferramentas.
O Android altamente compatvel com cdigo
e bibliotecas Java preexistentes (desde, claro, que
o de SMS, browser web e gerenciamento
de ligaes telefnicas. O sistema opera-
cional da plataforma baseado na verso
2.6 do kernel do Linux e atua como uma
camada de abstrao entre o hardware e
o resto da pilha (stack) de softwares (veja
a Figura 1).
A mquina virtual do Android foi desen-
volvida pelo Google e chamada Dalvik.
diferente da JVM que conhecemos, pois
no executa arquivos .class e sim .dex
(Dalvik Executable). Uma caracterstica
importante deste formato ser otimizado
para menor uso de memria. A VM Dalvik
executa classes compiladas pelo compila-
dor do Java, que so transformadas para
o formato .dex. Foi criada de forma que o
Rev_Java53_cromo.pdf 20 Rev_Java53_cromo.pdf 20 20/12/2007 16:40:14 20/12/2007 16:40:14
Edio 53 Java Magazine 21
Conhea e aprenda a
desenvolver uma aplicao
para o Android, a nova e
aberta plataforma para
celulares
MARLON LUZ
estas no utilizem APIs Java SE/ME no disponveis
no Android). Mesmo o uso de um formato binrio
diferente (.dex) no grande problema, pois arqui-
vos JAR podem ser convertidos em .dex.
O Google disponibiliza um kit de de-
senvolvimento (SDK) completo para o
Android, o qual inclui um emulador e um
plug-in para o Eclipse. O SDK est dispon-
vel para Windows, Linux e Mac OS X.
Preparando o ambiente
Na rea de downloads do site da platafor-
ma (code.google.com/android/download.html)
faa o download do SDK para a verso do
seu sistema operacional e descompacte o
arquivo num local de sua preferncia. Feito
isso, necessrio adicionar o diretrio das
ferramentas do SDK (subdiretrio tools) na
varivel de ambiente PATH.
O prximo passo instalar o plug-in
do Android para o Eclipse. A verso do
IDE pode ser a 3.2 ou a 3.3. Tambm
necessrio ter o JDK 5 ou 6 instalado.
Inicie o Eclipse e chame Help>Software
Updates>Find and Install. Na janela que apa-
recer escolha o item Search for new features
to install e clique em Next. Clique em New
Remote Site e no campo Name insira um
nome para identificar o site de atualizaes
(ex. Plug-in Android). No campo URL
inclua o endereo https://dl-ssl.google.
com/android/eclipse. Clique em OK, e a
lista ser atualizada com o novo item (que
j dever estar marcado).
Voc j pode clicar em Finish. O Eclipse
ir baixar o plug-in e instal-lo aps as
confirmaes de praxe. Depois de reini-
ciar o Eclipse, chame Window>Preferences.
Localize o Android no painel da esquerda
e no campo SDK Location fornea o dire-
trio onde foi descompactado o SDK. Ter-
mine a configurao clicando em Apply e
depois em OK.
Desenvolvendo uma aplicao
Tendo configurado o ambiente, vamos
agora criar uma aplicao para entender
melhor o plug-in e a arquitetura do An-
droid. Criaremos um conversor de medi-
das, no qual podemos transformar valores
entre metros, jardas e ps.
A aplicao ter apenas uma tela. Nela a
unidade de entrada ser indicada em um
componente android.widget.Spinner. O valor de
entrada ser fornecido em um android.widget.
EditText, e em outro Spinner ser indicada a
unidade de sada. O resultado ser mostra-
do em um android.widget.TextView. A tela de
aplicao, j executando no emulador do
Android, pode ser vista na Figura 2.
Gerando o esqueleto
Para criar a aplicao com o plug-in do
Eclipse, execute File>New>Other, expanda
a pasta Android e selecione Android Project.
Entre com o nome do projeto, Conver-
Figura 1. A arquitetura do Android
Figura 2. Emulador do Android executando
a aplicao de converso
Rev_Java53_cromo.pdf 21 Rev_Java53_cromo.pdf 21 20/12/2007 16:40:14 20/12/2007 16:40:14
22 Java Magazine Edio 53
Wireless Update
O
Android suporta quatro tipos de aplica-
es, que podem ser usadas individual-
mente ou em conjunto:
%Activity o tipo mais comum e o usado
no exemplo deste artigo. Cada atividade
uma tela, portanto se sua aplicao precisa de
duas telas, dever ter duas classes estenden-
do a classe Activity. Para ir a uma nova tela,
necessrio iniciar uma nova atividade; quando
isso acontece, a tela anterior entra no estado
de paused e colocada num histrico, o qual
representado por uma pilha. Para retroceder
para a tela anterior basta ento desempilhar
a ltima atividade do histrico. Essa tcnica
similar utilizada por browsers web, com a
diferena de que no Android a aplicao tem
controle bem maior sobre a navegao.
% Intent Receiver uma aplicao que
reage a eventos indicando, por exemplo, que
o telefone est tocando, que chegou uma
hora determinada, que um dado na rede est
disponvel, e assim por diante. Esse tipo de
aplicao no possui interface com o usurio,
mas pode gerar uma notificao para alertar
outra aplicao sobre o evento ocorrido.
%Service Um servio que fica executando
no dispositivo, por exemplo um tocador de m-
sica. Para este exemplo, o usurio selecionaria
uma msica atravs de uma aplicao comum
(do tipo Activity), e essa aplicao ento chama-
ria o servio para iniciar o player. Dessa forma,
seria possvel sair da aplicao chamadora e
acessar outras atividades do dispositivo sem
interromper a msica.
%Content Provider um tipo de aplicao
que serve para armazenar e buscar dados. O
Android disponibiliza um banco de dados SQLite
para isso. Os dados armazenados podem ser
trocados entre diferentes aplicaes.
Com isso, podemos notar que o Android in-
centiva a criao de solues componentizadas
por exemplo, usando uma aplicao Activity
para a GUI, uma Intent Receiver para o trata-
mento de eventos e uma Service para funes
de background. Essa estrutura melhor que
uma aplicao monoltica. Por exemplo, no
causa problemas nem requer programao
especfica quando uma aplicao precisa ser
interrompida por outra devido a um evento:
o evento simplesmente causar a execuo
simultnea (multitarefa) do Intent Receiver,
sem necessariamente bloquear a Activity em
andamento.
Tipos de aplicaes do Android
Figura 3. Configurando a execuo da aplicao
sorMedidas, e o do pacote, com.java-
magazine.android.conversorMedidas.
Esse pacote deve ser nico em relao a
todas as outras aplicaes instaladas no
sistema; portanto deve-se ter cuidado
para escolher um nome que realmente
represente a sua aplicao. Esta uma
limitao especfica plataforma Android
e tem a ver com o seu suporte eficiente a
mltiplos processos.
No campo Activity Name insira Conver-
sorMedidas. O plug-in ir criar uma classe
stub (modelo) com esse nome, estendendo
a classe android.app.Activity, que anloga
MIDlet do Java ME. a partir desta classe
que o programa comea a executar (veja
tambm o quadro Tipos de aplicaes do
Android). Para o nome da aplicao, for-
nea Conversor de Unidades de Medidas.
Clique em Finish e o projeto ser criado.
Voc ver que o plug-in cria uma pasta
/src para os fontes do projeto, bem como
o pacote e a classe stub. Tambm criado
um arquivo R.java. A classe neste arquivo
mantida pelo prprio plug-in e no deve
ser editada manualmente. Ela possui
ndices para todos os recursos (resources)
do projeto, facilitando a referncia a estes
no cdigo Java. Outra pasta gerada /res,
onde devem ficar todos os recursos do
projeto, como imagens e arquivos XML,
entre outros. Qualquer alterao no con-
tedo da pasta /res pasta ir se refletir no
arquivo R.java.
Na subpasta /res/layout, temos o arquivo
main.xml, onde definida a interface gr-
fica da aplicao. No Android, as telas so
definidas de forma declarativa e no com
cdigo Java.
Definio bsica da GUI
Abra o arquivo main.xml e substitua o con-
tedo pelo cdigo da Listagem 1. Observe
que nosso XML comea definindo o layout
da tela atravs da tag <TableLayout> (que de-
fine uma estrutura tabular). Usando os atri-
butos android:layout_width e android:layout_height
e o valor fill_parent, definimos que toda a
rea da tela deve ser preenchida. E com o
atributo android:strechColumns indicamos que a
primeira coluna deve ocupar todo o espao
definido pelos atributos anteriores.
Com a tag <TableRow>, definimos a pri-
meira linha do layout. Dentro dela colo-
Rev_Java53_cromo.pdf 22 Rev_Java53_cromo.pdf 22 20/12/2007 16:40:14 20/12/2007 16:40:14
Edio 53 Java Magazine 23
Listagem 1. Definio da GUI: main.xml
<?xml version=1.0 encoding=utf-8?>
<TableLayout xmlns:android=
http://schemas.android.com/apk/res/android
android:layout_width=fill_parent
android:layout_height=fill_parent
android:stretchColumns=1>
<TableRow>
<TextView
android:text=Unidade
android:textStyle=bold
android:textAlign=end
android:padding=3dip />
<Spinner id=@+id/unidade1
android:layout_width=fill_parent
android:layout_height=wrap_content
android:drawSelectorOnTop=true/>
</TableRow>
<TableRow>
<TextView
android:text=Quantidade
android:textStyle=bold
android:textAlign=end
android:padding=3dip />
<EditText id=@+id/qtd1
android:text=0
android:layout_width=fill_parent
android:layout_height=wrap_content
android:numeric=true
android:maxLength=6/>
</TableRow>
<TableRow>
<TextView
android:text=Unidade
android:textStyle=bold
android:textAlign=end
android:padding=3dip />
<Spinner id=@+id/unidade2
android:layout_width=fill_parent
android:layout_height=wrap_content
android:drawSelectorOnTop=true/>
</TableRow>
<TableRow>
<TextView
android:text=Quantidade
android:textStyle=bold
android:textAlign=end
android:padding=3dip />
<TextView id=@+id/qtd2
android:text=
android:textStyle=bold
android:textAlign=end
android:padding=3dip />
</TableRow>
</TableLayout>
camos os componentes TextView e Spinner,
tendo o primeiro o texto Unidade (o
seu label). Note que os componentes tm
atributos que definem o estilo da fonte e o
alinhamento. Alm disso, o Spinner possui
um atributo id que o identifica na classe
R.java. Na prxima linha colocado, alm
do TextView, um EditText. Os atributos do
EditText definem o tipo de entrada de dados
como numrico e com tamanho mximo
de seis posies. Na linha seguinte temos
um novo Spinner. E na ltima linha so
inseridos dois TextViews.
Lgica da aplicao
Agora que j montamos a tela da aplica-
o, vamos acrescentar a lgica principal.
Para isso precisamos de cdigo dentro da
classe ConversorMedidas. Abra essa classe e
substitua seu cdigo pelo da Listagem 2.
A classe ConversorMedidas implementa trs
interfaces de listeners, para calcular a
converso das medidas em trs momentos:
ao selecionar uma unidade diferente no
Spinner, ao mudar o foco do EditText e ao ser
pressionada a tecla Enter sobre o campo
EditText. Os mtodos onClick(), onItemSelected()
e onFocusChanged() apenas chamam o mtodo
converter(), que l os dados dos campos,
calcula a converso e preenche o campo
de resultado.
Na classe ConversorMedidas tambm so
definidos atributos para os campos da tela.
Observe que no Android existem classes
correspondentes aos tags no arquivo main.
xml (EditText, TextView etc.). Existe tambm
um atributo de tipo String[], contendo os
nomes das medidas usadas na aplicao.
Este atributo usado para preencher os
componentes Spinner.
O ltimo atributo uma matriz de
converso entre as unidades. Basta multi-
plicar o valor a ser convertido pelo valor
associado na matriz, como pode ser visto
no mtodo converter().
O mtodo onCreate() por onde a atividade
inicia. Na primeira linha, chamamos o m-
todo correspondente na superclasse, pas-
sando o parmetro recebido. Logo aps,
colocamos o layout na tela, chamando o
mtodo setContentView(), que recebe como
parmetro o main.xml, que definido au-
tomaticamente como um atributo esttico
na classe R.java. Em seguida criado um
ArrayAdapter com os nomes das unidades
de medidas. Este objeto configurado
para funcionar de modo drop-down, per-
mitindo selecionar um dos valores dentro
do Spinner.
Para obter a referncia para os objetos
da tela, chamamos o mtodo findViewById(),
passando como parmetro o nome do
componente definido no arquivo main.xml,
novamente atravs da classe R.java. O
ArrayAdapter ento associado aos Spinners
para preench-los com os valores. Por lti-
mo, buscamos as referncias para todos os
outros componentes da tela e associamos
os listeners para cada um deles.
Executando o exemplo
J podemos executar a aplicao. Chame
Run>Open Run Dialog, o que abrir uma
tela como a da Figura 3. Escolha a opo
Android Applicationno menu lateral e clique
sobre o cone no canto superior esquerdo,
para criar uma nova configurao de exe-
cuo. Na parte direita da tela, preencha
o campo Name com ConversorMedidas.
Abaixo, clique em Browse e escolha o nosso
projeto. Mais abaixo, escolha a atividade a
ser lanada (para o exemplo, temos apenas
uma). Clique em Apply, depois em Run.
O emulador do Android ser lanado e a
aplicao, iniciada.
Rev_Java53_cromo.pdf 23 Rev_Java53_cromo.pdf 23 20/12/2007 16:40:14 20/12/2007 16:40:14
24 Java Magazine Edio 53
Wireless Update
Concluses
O Android, mesmo no sendo compa-
tvel com o Java ME, mostra-se muito
poderoso na criao de aplicativos Java
para dispositivos mveis. Nota-se um
grande esforo por trs de todo o projeto.
A criao de uma mquina virtual prpria
um bom exemplo disso e deixa claro
porque a Google passou os ltimos anos
contratando e mantendo vrios gurus
que no passado ajudaram a criar e desen-
volver partes importantes da tecnologia
Java, como Joshua Bloch e Neal Gafter. O
Google est investindo cada vez mais pe-
sado em tecnologia Java, o que s beneficia
a nossa comunidade de desenvolvedores.
Embora a competio entre o Android e
as plataformas tradicionais da Sun/JCP
tambm tenha seu lado negativo, ao exigir
o aprendizado de novas APIs, talvez seja
uma competio saudvel e necessria
para o Java ME.
Para incentivar a criao de aplicaes
para o Android, o Google lanou um con-
curso de desenvolvedores que distribuir
10 milhes de dlares em prmios para as
melhores aplicaes desenvolvidas sobre a
plataforma. O concurso estar aberto para
submisso de aplicaes entre 2 de janeiro
e 3 de maro de 2008.
Finalmente, sobre a disponibilizao dos
novos dispositivos Android no mercado, a
Open Handset Alliance promete os primei-
ros j para o segundo trimestre de 2008.
code.google.com/android
Android
openhandsetalliance.com
Open Handset Alliance
Marlon Luz
(marlon.luz@lightmobile.com.br)
consultor Java e possui as certifi-
caes SCJP, SCMAD, SCJA, SCWCD.
membro individual do Java Community
Process e integra o Expert Group da JSR-271 (MIDP 3.0)
Listagem 2.ConversorMedidas.java
package com.javamagazine.android.conversormedidas;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.AdapterView.OnItemSelectedListener;
public class ConversorMedidas extends Activity implements OnItemSelectedListener,
OnClickListener, OnFocusChangeListener
{
private EditText etQtd1;
private TextView tvQtd2;
private Spinner sUnidade1;
private Spinner sUnidade2;
private static final String[]medidas = {
Metros, Jardas, Ps
};
private static final double[][] matrixConversao = {
// m yd ft
{1.0, 1.0936, 3.2808}, // m
{0.91440, 1.0, 3.0000}, // yd
{0.30480, 0.33333, 1.0 } // ft
};
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
ArrayAdapter <String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, medidas);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sUnidade1 = (Spinner) findViewById(R.id.unidade1);
sUnidade1.setAdapter(adapter);
sUnidade2 = (Spinner) findViewById(R.id.unidade2);
sUnidade2.setAdapter(adapter);
sUnidade2.setSelection(1);
sUnidade1.setOnItemSelectedListener(this);
sUnidade2.setOnItemSelectedListener(this);
etQtd1 = (EditText) findViewById(R.id.qtd1);
etQtd1.setOnClickListener(this);
etQtd1.setOnFocusChangeListener(this);
tvQtd2 = (TextView) findViewById(R.id.qtd2);
}
public void converter() {
double qtd = Double.parseDouble(etQtd1.getText().toString());
int linha = sUnidade1.getSelectedItemIndex();
int coluna = sUnidade2.getSelectedItemIndex();
double resultado = qtd * matrixConversao[linha][coluna];
tvQtd2.setText( + resultado);
}
public void onClick(View arg0) {
converter();
}
public void onItemSelected(AdapterView parent, View v, int position, long id) {
converter();
}
public void onFocusChanged(View arg0, boolean arg1) {
converter();
}
public void onNothingSelected(AdapterView arg0) {
}
}
Rev_Java53_cromo.pdf 24 Rev_Java53_cromo.pdf 24 20/12/2007 16:40:14 20/12/2007 16:40:14
Rev_Java53_cromo.pdf 25 Rev_Java53_cromo.pdf 25 20/12/2007 16:40:14 20/12/2007 16:40:14
26 Java Magazine Edio 53
Desacoplando Regras de Negcios dos Cdi
Drools: Regras na Prti
O
s mecanismos de regras tm como
um de seus principais objetivos
separar as regras de negcios dos
cdigos de infra-estrutura (ex. persistn-
cia, transaes, e-mail, mensageria etc.).
Este artigo demonstra a aplicabilidade
prtica do engine de regras open source
Drools, um dos mais tradicionais e pode-
rosos do mercado.
Histrico e exemplo
O Drools foi lanado pela Codehaus
(codehaus.org) e posteriormente adotado
como um projeto do JBoss, empresa que
emprega em tempo integral um bom
nmero de profissionais da equipe de de-
senvolvimento do projeto. Por um tempo,
o Drools foi conhecido como JBoss Rules,
porm na sua verso mais atual, o ttulo
da verso comunitria voltou ao original
Drools. A distribuio com suporte da Red
Hat, entretanto, ainda mantm o nome
JBoss Rules.
O contexto do nosso exemplo uma
hipottica corretora de seguros, em que
os valores das propostas de seguro so
determinados por regras definidas exter-
namente, em um arquivo do Drools. Novas
regras criadas nesse arquivo refletiro au-
tomaticamente sobre resultados da execu-
o do sistema. Ao usar o Drools, portanto,
temos mais liberdade para alterar as regras
de negcios e eliminamos a necessidade de
deploy ou compilao da aplicao quando
essas regras mudarem.
Os objetos de domnio do exemplo fica-
ro dentro do pacote jm.seguros.beans. So
eles: Proposta, Cliente e Bem. Tambm temos
um enum Tipo (usado para indicar o tipo de
cada bem). Veja esses itens na Listagem 1.
Observe que a classe Proposta contm um
Cliente e um Bem como atributos. O valor fi-
nal da proposta depende destes atributos,
que so usados nos clculos especificados
no arquivo de regras.
Para compilar e executar a aplicao de
exemplo, voc precisar apenas do JDK e
do Ant, configurados apropriadamente, ou
qualquer IDE Java moderno. A estrutura
do projeto e as bibliotecas utilizadas so
ilustradas na Figura 1.
Rev_Java53_cromo.pdf 26 Rev_Java53_cromo.pdf 26 20/12/2007 16:40:14 20/12/2007 16:40:14
Edio 53 Java Magazine 27
gos Java
ca
Como construir de forma
simples aplicaes
resistentes a mudanas
e desacopladas de suas
regras com Java e Drools
EDGAR A. SILVA
Alguns conceitos fundamentais
Uma regra no Drools tem um ou mais
condies (ou fatos). Estas condies levam
a uma ou mais aes (ou conseqncias).
Esta a estrutura bsica de uma regra:
when
<condies>
then
<aes>
No bloco when, assim como num bloco if
do Java, voc pode incluir vrias condi-
es. Estas, por sua vez, podem gerar uma
ou mais aes no bloco then. No Drools, as
regras ficam em arquivos com a extenso
.dlr. Um arquivo de regras pode conter os
seguintes elementos:
a) declarao package Similar a Java,
usada para organi zar as regras em
pacotes.
b) imports Importaes das classes que
o arquivo de regras poder acessar para
avaliar suas regras; a sintaxe idntica
de Java.
c) globals Declaraes globais de objetos
que sero visveis a todas as regras.
d) functions Declaraes de funes que
podem ser usadas no arquivo de regras
e) rules A principal parte do .drl, onde
so definidas as regras em si.
Outro elemento importante do Drools
a classe WorkingMemory, que representa o
contexto onde as regras sero executadas.
Geralmente inserimos no WorkingMemory os
objetos a serem analisados pelas regras.
Este objeto tambm permite disparar as
regras definidas.
Criando a aplicao de exemplo
Na classe principal de nosso exemplo
(Listagem 2) vamos criar trs objetos Cliente
e um objeto Bem. Depois criamos trs obje-
tos Proposta e a estes adicionamos os objetos
Cliente e Bem correspondentes. Figura 2. Aplicao de exemplo no Eclipse com o plugin do Drools
Figura 1. Estrutura e bibliotecas do projeto
Rev_Java53_cromo.pdf 27 Rev_Java53_cromo.pdf 27 20/12/2007 16:40:15 20/12/2007 16:40:15
28 Java Magazine Edio 53
Drools: Regras na Prtica
O engine de regras e o WorkingMemory so
inicializados com as regras descritas no
arquivo DRL, como a seguir:
...
PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl(new InputStreamReader(
Proposta.class.getResourceAsStream(regras.drl)));
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(builder.getPackage());
...
WorkingMemory workingMemory = ruleBase.
newStatefulSession();
Depois de inserir as trs propostas
no WorkingMemory, disparamos todas as
regras:
workingMemory.fireAllRules();
Veja uma das regras usada o exemplo:
rule "perfil-mulher-experiente"
when
proposta : Proposta(cliente.sexo=="F" && cliente.idade>21)
then
proposta.setValor(proposta.getBem().getValor() * (0.025));
end
Com base nas regras (veja a Listagem 3)
chegamos aos valores das propostas. Note,
na classe Main, que definimos o valor da
Listagem 2. Classe Main.java
package jm.seguros;
import java.io.InputStreamReader;
import jm.seguros.beans.*;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.WorkingMemory;
import org.drools.compiler.PackageBuilder;
public class Main {
public static void main(String[] args) throws Exception {
PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl(new InputStreamReader(
Proposta.class.getResourceAsStream(regras.drl)));
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(builder.getPackage());
Cliente cliente1 = new Cliente();
cliente1.setSalario(5000.0);
cliente1.setIdade(19);
cliente1.setSexo(M);
Cliente cliente2 = new Cliente();
cliente2.setSalario(12000.0);
cliente2.setIdade(25);
cliente2.setSexo(F);
Cliente cliente3 = new Cliente();
cliente3.setSalario(8000.0);
cliente3.setIdade(39);
cliente3.setSexo(M);
Bem bem1 = new Bem();
bem1.setTipo(Tipo.CARRO);
bem1.setValor(82000.0);
Proposta proposta1 = new Proposta();
proposta1.setBem(bem1);
proposta1.setCliente(cliente1);
Proposta proposta2 = new Proposta();
proposta2.setBem(bem1);
proposta2.setCliente(cliente2);
Proposta proposta3 = new Proposta();
proposta3.setBem(bem1);
proposta3.setCliente(cliente3);
WorkingMemory workingMemory = ruleBase.newStatefulSession();
workingMemory.insert(proposta1);
workingMemory.insert(proposta2);
workingMemory.insert(proposta3);
workingMemory.fireAllRules();
System.out.println(Valor da proposta 1: + proposta1.getValor());
System.out.println(Valor da Proposta 2: + proposta2.getValor());
System.out.println(Valor da Proposta 3: + proposta3.getValor());
}
}
Listagem1.Beans doexemplo(todos nopacotejm.seguros.beans)
Proposta.java
public class Proposta {
private Integer id;
private Cliente cliente;
private Bem bem;
private Double valor;
...
}
Cliente.java
public class Cliente {
private String nome;
private String email;
private Integer idade;
private Double salario;
private String cidade;
private String bairro;
private String sexo;
...
}
Bem.java
public class Bem {
private Tipo tipo;
private Double valor;
private String descricao;
...
}
Tipo.java (enum)
public enum Tipo{
CARRO, CASA;
}
proposta do seguro para trs clientes,
todas para o mesmo bem mas que os re-
sultados variam de acordo com a execuo
das regras.
Para testar a aplicao, basta executar a
classe Main (o projeto completo est dispo-
nvel para download). O resultado ser:
Valor da proposta 1:9020.0
Valor da Proposta 2: 2050.0
Valor da Proposta 3: 4510.0
Nosso exemplo muito simples, mas com
base nele j podemos ter idia de como
criar novas regras. Outras regras poderiam
considerar, por exemplo, outros atributos
do cliente, como o bairro e a cidade (que
tm influncia sobre o risco de roubos e
acidentes), alm do tipo do bem, etc.
Plugin Drools para o Eclipse
Na pgina de downloads do Drools
Rev_Java53_cromo.pdf 28 Rev_Java53_cromo.pdf 28 20/12/2007 16:40:15 20/12/2007 16:40:15
Edio 53 Java Magazine 29
Figura 3. Editando DSLs (em portugus) no plugin do Drools
(labs.jboss.com/drools/downloads.html), voc
encontrar um plugin para o Eclipse com
suporte extensivo programao com
regras. Esto disponveis releases para
a verso 3.2 e 3.3 do IDE (usamos neste
exemplo o Drools 4.0.3 Eclipse Europa
3.3 Workbench).
Com este plugin, ganhamos no s re-
cursos comuns, como editores amigveis
e auto-completamento (veja a Figura 2),
mas tambm recursos avanados e espe-
cficos, entre eles o Rules Flow (acessvel
via File>New>Other>Drools>Rule Flow File;
veja a Figura 3), e um editor de linguagens
de domnio especfico (DSLs), mostrado
na Figura 4.
Concluses
Com o uso do Drools, possvel tornar
muito mais rpidas as mudanas em regras
de negcios nas suas aplicaes Java, sepa-
rando-as efetivamente do cdigo voltado
infra-estrutura. Ter maior agilidade em
atender a alteraes em requisitos e novas
demandas algo que os clientes esperam dos
Figura 4. Editor do RulesFlow
Listagem 3. O Arquivo regras.drl
package jm.seguros.beans
import jm.seguros.beans.*;
rule perfil-mulher-jovem
when
proposta : Proposta(cliente.sexo==F && cliente.idade<21)
then
proposta.setValor( proposta.getBem().getValor() * (0.04) );
end
rule perfil-mulher-experiente
when
proposta : Proposta(cliente.sexo==F && cliente.idade>21)
then
proposta.setValor( proposta.getBem().getValor() * (0.025) );
end
rule perfil-homem-experiente
when
proposta : Proposta(cliente.idade>21 && cliente.sexo==M)
then
proposta.setValor( proposta.getBem().getValor() * (0.055) );
end
rule perfil-homem-jovem
when
proposta : Proposta(cliente.idade<21 && cliente.sexo==M)
then
proposta.setValor( proposta.getBem().getValor() * (0.11) );
end
labs.jboss.com/drools
Site do Projeto Drools
edgarsilva.com.br/?p=110
Entrevista com Edson Tirelli (Brasileiro que traba-
lha no projeto Drools)
Edgar A. Silva
(edgar.silva@redhat.com,
www.edgarsilva.com.br)
Solutions Architect da Red
Hat. Como Arquiteto Java, ajuda no
desenvolvimento de solues de middleware de misso
crtica e SOA. Possui nove anos de experincia com Java,
alm de vrias certificaes na tecnologia, entre elas
SCEA, e j ministrou palestras e treinamentos sobre
Java no Brasil e no exterior.
departamentos de desenvolvimento e os
engines de regras esto despontando como
uma tima ajuda em muitos casos.
Rev_Java53_cromo.pdf 29 Rev_Java53_cromo.pdf 29 20/12/2007 16:40:15 20/12/2007 16:40:15
30 Java Magazine Edio 53
Os Grandes IDEs Open Source Comparados
Eclipse x NetBeans
P
ara quem usa e acompanha IDEs
Java, o ano de 2007 foi excepcional.
Considerando apenas os produ-
tos mais populares, tanto o Eclipse 3.3
Europa quanto o NetBeans 6.0 foram
atualizaes de grande importncia.
Nesse contexto, o leitor ainda indeciso
poder perguntar: enfim, qual o melhor
IDE? Mas no h uma resposta simples.
Ambos os softwares so muito grandes e
multifacetados.
s por que um competidor deu um passo
frente e se tornou o melhor por um
breve perodo. Voc abandona o seu time
de futebol s porque no venceu o campe-
onato deste ano?
A proposta deste artigo comparar o
NetBeans com o Eclipse, mas com uma
abordagem voltada s diferenas funda-
mentais de design, de arquitetura ou de
esprito entre os dois produtos. Estas
diferenas, na maioria das vezes, no so
do tipo que permita um julgamento entre
Certo ou Errado, Melhor ou Pior. Porm,
ser fcil ver que elas permitem a cada
leitor e talvez, para cada empresa ou pro-
jeto decidir qual IDE mais adequado.
Um IDE uma das principais ferramentas
de trabalho do desenvolvedor, e o IDE
perfeito aquele que se adapta cultura
do desenvolvedor: sua metodologia de
trabalho, seu ambiente, outras ferramentas
preferidas e at suas manias e valores.
Software Livre ou Proprietrio?
O tema do software livre/open source
continua crescendo em relevncia. Para
usurios comuns, o software livre de
desktop tem crescido de forma lenta e
ainda luta para conquistar espao. Mas
entre os desenvolvedores, no h dvida
que j existe uma grande preferncia pelo
software livre (embora esta preferncia
tambm no seja unnime, certamente
prevalece entre os que optaram pelo Java:
uma plataforma portvel, aberta e, final-
mente, tambm livre).
Tanto o Eclipse quanto o NetBeans
posam de campees do software livre,
mas como veremos, cada um destes IDEs
possui um histrico e um status diferente
nesta rea.
Eclipse
Os usurios mais antigos do Eclipse lem-
braro o seu lanamento, anunciado pela
Uma comparao no estilo checklist,
batendo funcionalidade com funcionalida-
de, poderia dar respostas para perguntas
mais granulares, como qual IDE tem o
melhor depurador, o melhor editor de JSP,
a melhor integrao com servidores de
aplicaes e assim por diante. Esse tipo
de comparao, no entanto, tem valor no
mximo provisrio. Por exemplo, h um
ano poderamos apontar para a grande
superioridade do editor de cdigo do
Eclipse; mas o NetBeans 6.0 recuperou o
atraso nesta rea, com um editor totalmen-
te renovado. Da mesma forma, o NetBeans
costumava estar muito frente no suporte
a Java EE, mas o Eclipse 3.3 (com o WTP
2.0) tambm correu atrs do prejuzo.
A escolha do IDE um investimento
de longo prazo; uma ferramenta que
demanda meses para ser dominada. E
pouca gente troca de IDE a cada semestre,
Rev_Java53_cromo.pdf 30 Rev_Java53_cromo.pdf 30 20/12/2007 16:40:15 20/12/2007 16:40:15
Edio 53 Java Magazine 31
Uma comparao p-no-cho
das duas ferramentas mais
usadas por desenvolvedores
Java: da filosofia de cada
produto s pequenas
diferenas prticas
OSVALDO PINALI DOEDERLEIN
IBM como uma doao comunidade de
US$ 40 milhes o custo de desenvolvi-
mento do Eclipse 1.0, entre 1999 e 2001. Isso
realmente impressionante, mas tambm
mascara o fato que o Eclipse foi desenvol-
vido sob portas fechadas at o release 1.0.
comum que isso acontea em projetos livres
patrocinados por grandes corporaes:
estas esperam at que o projeto atinja um
ponto sem volta, no qual a maturidade
do software garanta a preservao das suas
principais decises arquiteturais.
Um exemplo concreto o SWT, o toolkit
de GUI que at hoje causa polmica. Se
o Eclipse fosse aberto desde o comeo,
algum poderia ter decidido fazer uma
verso que usasse o Swing. No seria pou-
co trabalho, mas seria vivel: um esforo
incremental, acompanhando o trunk do
Eclipse. Mas o cdigo s foi aberto quando
o Eclipse 1.0 j estava pronto, incorporando
dois anos de trabalho (1999-2001) e j era
muito cdigo. Os fs do Swing comeariam
o fork com um enorme atraso, correndo
atrs de um projeto que j tinha alguns
milhes de linhas de cdigo e (na poca)
uma equipe de 40 desenvolvedores em
tempo integral. Quando a converso do
Eclipse 1.0 para Swing fosse finalizada,
certamente j estaria sendo lanando o
Eclipse 2.0 ou talvez at o 3.0. E os usu-
rios que precisassem das melhorias mais
recentes condenariam o fork baseado em
Swing ao ostracismo.
Essa ttica no exclusividade da IBM;
alis, est se popularizando. Outro exem-
plo recente o Google Android, nova
plataforma para smartphones baseada em
Linux e em Java (mas no em Java ME). O
Google alardeia que o Android ser open
source, mas note o ser: o SDK disponibi-
lizado em novembro de 2007 no vem com
os fontes, que s sero liberados no final
de 2008, com o Android 1.0 pronto e os
primeiros produtos j no mercado. A essa
altura, o Android j estar bem maduro;
j existiro montes de ferramentas, deze-
nas de fabricantes j tero feito os portes
para seus hardwares. Qualquer mudana
fundamental, por exemplo em APIs, cau-
saria quebra de compatibilidade com tudo
isso. Assim, o Google tambm poder se
posicionar de grande defensor do cdigo
livre, enquanto exerce firme controle sobre
a tecnologia. Mesmo que verses futuras
venham a ser desenvolvidas de forma
mais aberta pela Open Handset Alliance,
no podero desviar da direo escolhida
pelo Google. (Veja mais sobre o Android na
coluna Wireless Update desta edio.)
No lado positivo, o Eclipse por muito
tempo foi visto como o IDE Java mais
adequado a sistemas livres. Isso aconteceu
devido a dois fatores:
%A CPL (e depois EPL), licenas open
source permissivas e bem aceitas pela co-
munidade, em especial mais bem aceitas
que as licenas da Sun (mesmo a CDDL do
NetBeans pr-6.0).
%O uso do SWT, que contornava defici-
ncias do Swing em sistemas livres.
Este ltimo fator vale explicao. Em
sistemas como Linux e FreeBSD, as im-
plementaes livres de Java (como GCJ
e Kaffe) durante muitos anos no foram
capazes de rodar programas com interfa-
ces grficas complexas feitas com Swing.
Mas conseguiam rodar bem o SWT, que
(ao contrrio do Swing) era open source,
permitindo comunidade contribuir
portes e correes. O Swing s viria a ter
esta vantagem com o recente release GPL,
somente em maio de 2007
1
. Por isso, a
penetrao do Eclipse tem sido bem mais
rpida em distribuies de sistemas livres.
1 O projeto OpenJDK foi disparado no nal de 2006, mas
somente nesta data a maior parte do cdigo-fonte do
OpenJDK, inclusive o Swing e adjacncias (AWT, Java2D)
foi disponibilizado.
A ltima novidade o Red Hat Developer
Studio, novo IDE baseado no Eclipse e em
projetos em volta do JBoss-IDE. O Studio,
sendo fornecido pela Red Hat, legitimiza
ainda mais o Eclipse junto grande comu-
nidade de adeptos do Linux.
Um ltimo aspecto importante o con-
trole do desenvolvimento. O Eclipse
guiado pela Eclipse Software Foundation
(ESF), uma organizao independente,
a princpio livre do comando da IBM. A
ESF, porm, sustentada por contribuies
dos seus membros (em dinheiro ou em
desenvolvedores), portanto essa indepen-
dncia parcial. Grandes empresas podem
contribuir mais, e assim acabam tendo
mais committers e mais influncia, mesmo
quando assumida uma estrutura perfei-
tamente meritocrtica. Mas isso ocorre em
maior ou menor grau com qualquer projeto
open source de grande porte.
NetBeans
O NetBeans tambm teve uma origem
fechada, mas sua transio para o cdigo
aberto foi mais gradual e menos planeja-
da. Comeou em 1996 no alvorecer da
era Java como projeto de um grupo de
estudantes tchecos, com o nome preli-
minar Xelfi (em homenagem ao Delphi).
Em 1999 (quando o desenvolvimento do
Eclipse estava iniciando), o projeto j ha-
via evoludo para um IDE proprietrio, o
NetBeans DeveloperX2. No final de 1999,
a Sun adquiriu a empresa e incorporou o
NetBeans ao seu leque de produtos. Mas
o manteve parcialmente proprietrio
por um bom tempo. O cdigo foi aberto
em meados de 2000, mas a Sun tinha
uma linha de IDEs comerciais Forte,
Creator, etc. que a partir dessa poca,
passaram a ser baseados no NetBeans. O
IDE disponvel em netbeans.org era uma
verso bsica de produtos proprietrios
mais completos.
Rev_Java53_cromo.pdf 31 Rev_Java53_cromo.pdf 31 20/12/2007 16:40:15 20/12/2007 16:40:15
Eclipse x NetBeans
32 Java Magazine Edio 53
Por volta do NetBeans 5.5, a Sun entrou
na fase final de um longo caminho na dire-
o do cdigo livre, no s com o NetBeans
mas com outros projetos como GlassFish,
Solaris e o prprio JDK. Todos os fontes fo-
ram disponibilizados para o netbeans.org,
inclusive ferramentas avanadas para JSF,
UML, SOA etc. Hoje j se pode dizer que o
NetBeans totalmente livre. A Sun conti-
nua oferecendo servios comerciais, como
suporte, para estes produtos open source,
mas estes contratos comerciais no mais
contemplam distribuies proprietrias
com funcionalidades exclusivas.
Essa histria parece familiar: vrios
membros da ESF vendem IDEs baseados
no Eclipse. A diferena que o Eclipse est
um passo atrs do NetBeans, pois estes
IDEs comerciais continuam sendo diferen-
ciados por funcionalidades exclusivas. Isso
especialmente verdadeiro para a linha de
IDEs IBM Rational (RAD, RSM, RSA).
Estes IDEs possuem muitas funcionalida-
des adicionais e proprietrias inclusive
itens percebidos como deficincias do
Eclipse. Por exemplo, os IDEs IBM Rational
possuem h anos o suporte completo a
desenvolvimento J2EE/Java EE que faltava
ao Eclipse. No que a IBM e a ESF no
tivessem recursos ou competncia para
implementar tais funcionalidades, como
poderia pensar algum que conhecesse
somente a verso open source. Tudo j
havia sido implementado, s no havia
ainda sido doado para a ESF.
Parece ser um ponto a favor do NetBeans
e da Sun, que joga mais limpo, sem utilizar
um produto livre bsico como isca para
vender um produto proprietrio mais
completo. um lado da verdade, mas h
outros. A Sun nunca teve grande sucesso
no mercado com seus IDEs Java, e mesmo
com outros produtos como servidores de
aplicaes J2EE. J a IBM h muito tempo
lder de ambos os mercados, sempre fatu-
rou enormemente com seus produtos para
os dois segmentos. Este sucesso foi prova-
velmente um forte incentivo manuteno
do status hbrido (livre bsico + comercial
completo) assim como o pouco sucesso da
Sun ter facilitado a deciso de partir para
um modelo de software totalmente livre.
Neste modelo, o carter livre (e gratuito)
do software um facilitador do negcio
de servios, pois elimina uma barreira de
entrada para clientes potenciais.
Falando um pouco mais de licenas...
Tanto a EPL quanto a CDDL so licenas
livres, mas a EPL mais bem aceita (a Free
Software Foundation, por exemplo, aponta
que a CDDL complexa e possui clusulas
agressivas sobre patentes). Porm o jogo
virou com o NetBeans 6.0, que adotou
licena dual CDDL + GPLv2 (com Classpath
exception). Isso excelente, pois o NetBeans
6.0 100% compatvel com a vastido
de cdigo GPL presente na maioria dos
sistemas livres.
No s com o NetBeans, mas com todos
os projetos livres que lidera, a Sun tem se
movido rapidamente em direo GPL.
O OpenOffice j GPLv2; o OpenJDK
(Java SE), phoneME (Java ME) e GlassFish
v2 (Java EE) tambm. S o OpenSolaris
continua com a licena CDDL, mas est
sendo estudada a migrao para licena
dual, provavelmente a GPLv3. tanto
cdigo que a Sun provavelmente passar
frente da FSF e da comunidade Linux
como patrocinadora da maior quantidade
de software GPL, medindo em linhas de
cdigo ou em nmero de usurios
2
.
Veredicto
Os dois principais IDEs Java esto numa
briga de foice pelo ttulo de mais aberto,
mais livre, mais open source. A escolha
difcil, pois cada lado superior num
aspecto importante.
O NetBeans 6.0, com sua licena GPLv2,
ser o preferido de usurios engajados de
software livre. Por outro lado, para a turma
que prefere licenas permissivas, no-copy-
left como a EPL, poder preferir o Eclipse,
mais amigvel a derivativos proprietrios.
Para quem se importa com questes de
independncia e comunidade, o NetBeans
tem seu controle bem mais centralizado; o
netbeans.org, apesar de aberto para contri-
buintes de fora, est longe do status de inde-
pendncia da ESF (mesmo com as ressalvas
que fizemos). Mas tambm h quem tenha
antipatia a comits em geral (ESF) e prefira
um ditador benevolente (Sun).
Paradigma de ferramenta
Esse um ttulo difcil de explicar, mas
fcil de entender de forma intuitiva. Um
2 S o fantstico nmero de celulares que rodam Java
ME quase um bilho de novos aparelhos vendidos ape-
nas em 2007 excede o volume de usurios de qualquer
outra coisa, inclusive o Windows.
Rev_Java53_cromo.pdf 32 Rev_Java53_cromo.pdf 32 20/12/2007 16:40:16 20/12/2007 16:40:16
Edio 53 Java Magazine 33
IDE apenas uma ferramenta a mais, em
meio a muitas outras que voc usa: sistema
operacional, editor de texto, shell de linha
de comandos etc. Existem basicamente
dois modelos ou paradigmas.
Eclipse
O Eclipse pertence ao que eu chamaria
paradigma Apple/Microsoft. um IDE
que prima por uma GUI completa, sofisti-
cada e auto-suficiente. Algumas crticas ao
Eclipse atacam justamente as conseqncias
disso. O look-and-feel superior vem custa
do SWT, que criou um verdadeiro cisma
no universo Java. Tambm h quem acuse
a GUI do Eclipse de ser complexa e polu-
da parece ter tantos botes, dilogos e
rebuscamentos quanto um Microsoft Office
ou Adobe Photoshop.
Outra crtica comum que o Eclipse
um tanto fechado; em especial, seu sistema
de workspace e de projetos utiliza um
bom nmero de arquivos especficos ao
Eclipse, que no so interoperveis com
outras ferramentas. A ESF no teme impor
suas prprias tecnologias e ferramentas
para muitas coisas. J falamos do SWT,
mas h outros casos: at hoje vejo gente
que experimenta o Eclipse pela primeira
vez e se espanta ao descobrir que usa um
compilador Java prprio ao invs do javac.
Esse item em particular s vezes causa
problemas. Recentemente fui auxiliar um
colega que estava sofrendo erros de compi-
lao ao rodar um build do Ant para gerar
a distribuio de um projeto, sendo que os
mesmos fontes compilavam normalmente
no IDE. Descobri que os fontes tinham
bugs de tipos genricos, e que o javac
(invocado pelo Ant) flagrava estes bugs
corretamente, mas o compilador do Eclipse
era mais permissivo e deixava passar os
erros
3
. E isso j com o Eclipse 3.3.0, que j
a segunda reviso importante desde o
suporte inicial a Java 5 (que vem desde o
Eclipse 3.1.0).
Em defesa do Eclipse, deve-se dizer que
suas idiossincrasias so com freqncia
3 O projeto possua cdigo como: Conta<? extends
Cliente> x = localizaConta(); onde localizaConta () retornava
Conta<?> e esta classe era declarada como class Conta<?
extends Cliente>. Mas a converso de captura resultante,
um tpico complicado de tipos genricos, era ilegal. A
correo foi simples: Conta<?> x = localizaConta().
superiores ao padro (de fato ou de direi-
to) usado pela maioria dos competidores.
A vantagem do SWT, para quem valoriza
uma GUI rica e eficiente, ainda notvel.
O compilador do JDT (que j cobrimos em
diversos artigos) pode ter eventuais bugs,
mas muito mais rpido e avanado que
o javac, e responsvel pela compilao
incremental transparente e pela abun-
dncia de diagnsticos do Eclipse. Veja
na Figura 1 uma pequena amostra das
opes de diagnstico deste compilador,
capaz de identificar muitos erros poten-
ciais de programao e at de estilo de
cdigo e at mesmo de gerar arquivos
.class para fontes contendo erros (desa-
tivando o ltimo checkbox), muito til
para prototipagem. Num ltimo exemplo,
o gerenciamento de projetos do Eclipse
pode ser fechado, mas muito poderoso
e fcil de usar. O IDE suporta projetos
de enorme complexidade, inclusive com
recursos de extenso (plug-ins podem
criar novos tipos de projeto, ou adicionar
novos aspectos aos tipos existentes). As
abundantes pginas de propriedades de
projetos do Eclipse, tambm ilustradas
pela Figura 1, so outro aspecto que re-
vela esta riqueza.
O Eclipse extremamente componenti-
zado e extensvel, tendo a melhor arquite-
tura de plug-ins de qualquer software que
eu conhea. Seu microkernel de plug-ins,
o Equinox, uma implementao de um
padro aberto (OSGi v4 ratificado inclu-
sive pelo JCP), e o Plug-in Development
Environment (PDE) tornou o desenvolvi-
mento destes plug-ins acessvel de uma
Figura 1. Opes do compilador do JDT (exibindo apenas parte das disponveis)
Rev_Java53_cromo.pdf 33 Rev_Java53_cromo.pdf 33 20/12/2007 16:40:16 20/12/2007 16:40:16
Rev_Java53_cromo.pdf 34 Rev_Java53_cromo.pdf 34 20/12/2007 16:40:16 20/12/2007 16:40:16
Rev_Java53_cromo.pdf 35 Rev_Java53_cromo.pdf 35 20/12/2007 16:40:16 20/12/2007 16:40:16
36 Java Magazine Edio 53
Eclipse x NetBeans
forma tambm indita. Por outro lado,
o Eclipse limitado no sentido que exige
plug-ins para ser estendido. Historicamen-
te, o Eclipse tem sido pouco amigvel com
mtodos mais simples, leves e abertos de
extensibilidade, como scripts e macros;
ou atravs da integrao com ferramentas
tradicionais como o Ant. E mesmo com o
PDE, desenvolver um plug-in no trivial;
exige aprender diversas APIs do Eclipse.
S recentemente isso comeou a mudar,
com projetos como o Eclipse Monkey, que
permite usar JavaScript para automatizar
tarefas no IDE.
NetBeans
O NetBeans joga no time do para-
digma Unix. um IDE que pode ter
eventuais deficincias em ferramentas
visuais, mas prima em outros aspectos.
Para comear, ao invs da estrutura rgi-
da de workspace do Eclipse, o NetBeans
armazena suas configuraes e arquivos
temporrios num subdiretrio oculto
do diretrio home do usurio, como
costumeiro entre aplicaes Unix; e
permite abrir simultaneamente projetos
localizados em qualquer lugar do siste-
ma de arquivos.
O NetBeans utiliza o Ant como sua fer-
ramenta de build. Existe uma GUI para a
configurao dos projetos, mas esta GUI
manipula scripts do Ant. Para conhecedo-
res do Ant (ou seja, um grande nmero),
isso tem vantagens:
%Se o projeto tiver alguma necessidade
de configurao, compilao ou outra ati-
vidade que no seja bem suportada pelo
NetBeans, possvel editar manualmente
esses scripts Ant, e adicionar qualquer tipo
de funcionalidade suportada pelo Ant (o
que muita coisa).
% possvel usar os mesmos scripts sem
o IDE; por exemplo, como parte de um
procedimento de integrao contnua.
Qualquer ferramenta de linha de co-
mando se integra bem e facilmente com o
Ant. O mesmo se aplica (em menor grau)
ao Maven, outra ferramenta de build (e
muito mais) que vem se popularizando.
O NetBeans 6.0 conta com um plug-in que
permite criar projetos baseados em arqui-
vos do Maven 2 (Figura 2). (Tambm h
um plug-in de Maven para o Eclipse, mas
bem inferior, no permite criar projetos
gerenciados somente pelo Maven.)
O NetBeans tira proveito de muitas ou-
tras ferramentas tradicionais. Por exemplo,
a compilao de fontes Java feita com
o javac do JDK. Tarefas mais complexas,
como o deploy de uma aplicao num
servidor Java EE, ou a gerao de cdigo
para um web service, costumam ser feitas
invocando vrias ferramentas de linha de
comando, sempre com a coordenao do
Ant. A janela Output do NetBeans permite
acompanhar tudo o que acontece, como
podemos ver na Figura 3. um IDE que
encarna a idia de ser uma casca visual
para integrar qualquer ferramenta.
Isso no quer dizer que o NetBeans tam-
bm no possa ter uma GUI sofisticada e
muito visual: isso tambm ocorre, mas
primariamente em funcionalidades que
se beneficiam disso, tais como editores vi-
suais de telas Swing, JSF e LCDUI (Figura
4), ou as ferramentas para UML e BPEL.
Todas essas ferramentas esto entre as
melhores da indstria (inclusive contando
competidores proprietrios).
O NetBeans possui seu sistema de plug-
ins que j foi muito inferior ao do Eclipse,
mas desde a verso 5.5 amadureceu na
qualidade e na estabilidade de APIs, e nas
ferramentas para criao de plug-ins. Mas
o NetBeans bem mais amigvel a outras
tcnicas de extenso:
%Seu sistema de templates de cdigo
muito poderoso (embora o do Eclipse
tenha melhorado);
%O editor de cdigo tem a capacidade de
gravar e reproduzir macros, que permitem
automatizar tarefas de edio repetitivas
sem programao;
%Tcnicas inovadoras suportam scripts
especializados em tarefas de compreenso,
manipulao e refactoring de cdigo, e h
suporte a novas linguagens de programao
(Schliemann) sem a dificuldade de aprender
APIs e escrever um monte de cdigo Java.
interessante observar que a relao
do NetBeans com a Sun muitas vezes
vantajosa, e faz o NetBeans ser (ou pare-
cer) mais aberto. Por exemplo, o Matisse
inicialmente era um editor de GUIs que
dependia de uma biblioteca de extenso
do Swing, mas esta logo foi includa
no Java SE 6 (javax.swing.GroupLayout). Em
Figura 2. O Net|e+a. e c+a+t ae +|r|r a|ret+meate am are|ete ae M+.ea (ceatr+ae ae aem.\m|
Rev_Java53_cromo.pdf 36 Rev_Java53_cromo.pdf 36 20/12/2007 16:40:16 20/12/2007 16:40:16
Edio 53 Java Magazine 37
Figura 3. O Net|e+a. cem .ea. are|ete. |+.e+ae. em .cr|at. ae |at (+ce..|.e|. ae|+ |+ae|+ |||e.. |eaeme. .er aae e aea|e ae am+ +a||c+c1e I+.+ || ae 0|+..||.| le| tet+|meate ceeraea+ae aer
t+.|. ae |at, e.aec|l|c+. a+r+ e.te .er.|aer, ceal|aar+a+. +atem+t|c+meate ae|e Net|e+a.
outro exemplo, o NetBeans Profiler ini-
cialmente dependia de JVMs especiais
com extenses da Sun para possibilitar
funcionalidades avanadas de profiling.
Mas essas melhorias (JVMTI) tambm
foram incorporadas ao Java SE 6, e tam-
bm a updates recentes do J2SE 5.0. Em
contrapartida, o Eclipse tem o profiler
do TPTP, que durante muito tempo de-
pendia de um daemon especial e muito
inconveniente chamado RAC (Rational
Agent Controller). Somente a partir do
Eclipse 3.3, com o suporte JVMTI, o
TPTP deixou de exigir o uso do RAC,
pelo menos para atividades comuns de
profiling. Mesmo assim, a funcionalidade
de profiling do Eclipse continua atrs do
NetBeans (exceto por funcionalidades
secundrias, como gerao de diagramas
de seqncia UML, teis para anlise de
comportamento).
No h dvida que a posio da Sun,
como autora da implementao principal
do Java e lder das JSRs da plataforma Java
SE no JCP, agilizou muito a transio das
tecnologias inicialmente proprietrias
usadas pelo NetBeans para o status muito
mais politicamente correto de funcio-
nalidades padronizadas. E a tendncia
continua: uma das coisas que me irritam
no NetBeans 6.0 que os projetos JSF
estilo Visual Web exigem componentes
especiais, que no fazem parte do padro
JSF. Por enquanto, pois j est avanada a
definio de uma nova verso do JSF e de
novos padres, visando resolver as defi-
cincias que o Visual Web procura suprir,
mas sem fugir das especificaes do JSR.
Veredicto
O Eclipse foi projetado pela IBM, desde
o incio, para concorrer diretamente com
Rev_Java53_cromo.pdf 37 Rev_Java53_cromo.pdf 37 20/12/2007 16:40:16 20/12/2007 16:40:16
38 Java Magazine Edio 53
Eclipse x NetBeans
o Microsoft Visual Studio uma histria
que j contei nessas pginas. Da o seu
grande esmero em questes como aspecto
e funcionalidade de GUI, que deu origem
ao SWT. Porm, nem todo mundo ex-f
do Visual Studio e do paradigma de fer-
ramentas poderosas, porm relativamente
fechadas e auto-suficientes. Para a turma
que no vive sem a linha de comando,
adora as ferramentas do Unix/Linux, faz
misria com scripts e sabe combinar d-
zias de ferramentas simples para construir
solues poderosas, o NetBeans um IDE
que parece fazer tudo certo.
Natureza
Eclipse e NetBeans no so projetos com
objetivos idnticos, e isso se reflete direta-
mente na natureza dos produtos dispon-
veis para download em cada site.
Eclipse
A ESF no produz um IDE Java, nem
mesmo uma coleo de IDEs (que hoje su-
porta Java, C++, PHP e outras linguagens).
O que a ESF produz uma plataforma de
ferramentas (especialmente de IDEs, mas
tambm de vrias outras). IDEs como o
JDT so apenas um bnus, ou talvez,
IDEs de Referncia desta plataforma.
Por essa perspectiva, idealmente voc
deveria utilizar IDEs e outras ferramentas
mais completas baseadas no Eclipse, e pro-
duzidos por membros da ESF: IBM, BEA,
Borland etc. Estas ferramentas podem ser
comerciais ou gratuitas, livres ou proprie-
trias (a licena EPL permite isso).
Sabemos, no entanto, que milhes de de-
senvolvedores usam os IDEs de referncia
disponveis em eclipse.org, seja por serem
gratuitos, seja por serem livres. Como a
plataforma Eclipse prima pela extensibi-
lidade, h centenas de plug-ins livres que
competem com os pacotes comerciais. Por
exemplo, muito antes do WTP havia uma
diversidade de plug-ins para suporte a
J2EE: Lomboz, Tomcat Launcher, editores
de XML, de configurao do Struts e por
a vai. A existncia destes plug-ins gera-
va presso para o avano dos produtos
comerciais, que precisavam implementar
funcionalidades exclusivas ou mais avan-
adas para justificar o preo. Mas era uma
presso aceitvel, que no comprometia
o modelo de negcios da ESF. Os IDEs de
referncia da ESF tambm avanavam em
funcionalidades a cada nova verso, mas
numa velocidade calculada para no cau-
sar rupturas no ecossistema comercial.
Esse equilbrio, no entanto, foi rompido
pela Sun, quando esta mergulhou de vez
no caminho do software livre e comeou
a descarregar funcionalidades avanadas
no NetBeans.
Ainda assim, o Eclipse continuava
pecando em outros aspectos, como fa-
cilidade de instalao e de atualizao.
Os releases Callisto e Europa avanaram
bastante nesses dois pontos, mas ainda
no esto no mesmo patamar que IDEs
comerciais ou mesmo que o NetBeans:
por exemplo, no existem instaladores
oferecendo facilidades como uma seleo
das funcionalidades desejadas
4
.
Em contrapartida, o Eclipse uma plata-
forma de primeira linha o que excelente
para quem deseja uma base slida sobre a
qual desenvolver, como autores de plug-ins
ou de aplicaes RCP e outras que utilizem
os frameworks da ESF. Primeira linha
significa que as APIs so bem planejadas,
so estveis (mantendo compatibilidade
em novos releases), e bem suportadas por
4 S existem trs opes: 1) baixar pacotes integrados
como Eclipse IDE for Java EE Developers, com montes de
funcionalidades que sero todas instaladas; 2) baixar to-
dos os componentes individuais (Platform, JDT, PDE, GEF,
WTP...), mais trabalhoso e exige conhecer bem o Eclipse;
3) baixar o IDE bsico e usar o Update Manager para sele-
cionar itens extra, o que tem a desvantagem de exigir um
novo download dos mesmos para cada instalao.
Figura 5. m+ a+. te|+. ae |a.t+|+aer ae Net|e+a.. Nete aae e Net|e+a. |1 e.t1 a+rc|+|meate |a.t+|+ae, e am+ ae.+
execuo do instalador permite adicionar ou remover componentes da mesma instalao
Figura 4. |+rte ae ea|ter ae 0|. |t|| (M||| ae Net|e+a..
visual para ningum botar defeito
Rev_Java53_cromo.pdf 38 Rev_Java53_cromo.pdf 38 20/12/2007 16:40:16 20/12/2007 16:40:16
Edio 53 Java Magazine 39
ferramentas como o PDE.
Isso tudo especialmente verdadeiro
para as verses a partir do 3.0, quando
ocorreram as ltimas revises de maior
porte, especialmente a adoo do Equi-
nox. Praticamente todos os plug-ins
escritos para o Eclipse 3.0 funcionam em
todas as verses mais recentes, como o
3.3. (O oposto nem sempre verdadeiro,
como ocorre com qualquer plataforma,
pois plug-ins mais recentes tendem a usar
novas APIs.) Em contrapartida, o NetBe-
ans s muito recentemente (desde o 5.5)
passou a levar a srio seu lado de platafor-
ma, procurando consolidar um conjunto
de APIs estvel e de qualidade. Mas para
quem planeja grandes investimentos em
aplicaes dependentes das APIs de al-
gum desses dois projetos, o Eclipse ainda
uma aposta mais segura.
NetBeans
O NetBeans um IDE antes de mais
nada. (Recentemente, uma coleo de
IDEs para Java, C/C++, Ruby e outras
linguagens.) Por isso o NetBeans sempre
teve uma experincia fora da caixa muito
boa para os desenvolvedores. Isso comea
com instaladores para as principais plata-
formas, e bundles contendo dependncias
como o JDK, WTK e servidores de aplica-
es veja a Figura 5.
A fase final de desenvolvimento de cada
verso maior do NetBeans tambm mais
aprimorada, resultando em releases mais
redondos, com menos bugs. comum
que releases atrasem somente para atingir
objetivos de qualidade o NetBeans 6.0
atrasou quase um ms. Em oposio, a ESF
usa cronogramas rgidos: a data de release
da verso 3.4 (Ganymede) j foi marcada
para 29 de junho de 2008, e se pode ter
certeza que no haver um s dia de atraso,
como no houve para o Europa nem para
o Callisto. O custo disso costuma ser uma
maior tolerncia a defeitos de baixa priori-
dade
5
. A responsabilidade pelo polimento
final, que diferencia um produto de boa
qualidade de outro excelente, pertence aos
fornecedores de IDEs baseados no Eclipse.
Ento, se voc preferir usar os IDEs de
referncia da ESF, fica sem este polimento
final pelo menos com as verses ponto
zero como o 3.3.0. A ESF compensa isso
liberando atualizaes mais freqentes:
enquanto o NetBeans 5.5 s precisou de
um update de manuteno em um ano (o
5.5.1), o Eclipse 3.2 teve duas atualizaes
oficiais (3.2.1 e 3.2.2) e mais um stream de
builds de manuteno ps-3.2.2
6
.
J dissemos que o NetBeans ainda est
5 Para se exato, o critrio mais forte para releases do
Eclipse a estabilidade da plataforma; por exemplo no
pode haver bugs cuja correo implicaria em mudanas
de APIs. J bugs que afetam apenas o produto (ou seja, um
IDE como o JDT), mas cuja correo no causaria transtor-
nos de compatibilidade, so menos prioritrios e tm me-
nos chance de bloquear releases. mais um aspecto da
diferena: Eclipse=Plataforma; NetBeans=Produto.
6 Esse stream possui correes crticas, portadas do
3.3.x para o trunk do 3.2.2. Seria natural que isso resul-
tasse num release estvel 3.2.3, mas esse release no
est planejado, talvez para empurrar o Eclipse 3.3 para
quem deseja as ltimas correes. Fornecedores de IDEs
baseados no Eclipse 3.2.2 podem tirar proveito do stream
de manuteno, bem como usurios dos IDEs de refern-
cia que tenham coragem para baixar builds no-estveis
como M20071129-1100.
atrs do Eclipse como plataforma, o que
reflete o maior foco do NetBeans nos seus
usurios finais e no em desenvolve-
dores de plug-ins ou de IDEs comerciais.
Tambm por isso
7
, o NetBeans possui um
acervo de plug-ins (mdulos) de terceiros
bem mais modesto que o do Eclipse. Isso
talvez mude com as ltimas verses, cujas
APIs e ferramentas de desenvolvimento de
extenses avanaram muito.
Finalmente, j ouvi muita gente falar
que o NetBeans mais bem integrado,
enquanto o Eclipse seria um amontoa-
do de plug-ins com pouca coeso, por
exemplo na GUI. Mas muito disso o
que em ingls se chama F.U.D. (numa
traduo livre: cascata da grossa!). O fato
que o Eclipse tem uma arquitetura de
plug-ins to boa que permite que dzias
de componentes sejam desenvolvidos de
forma praticamente independente mas
se integrem to bem, inclusive na GUI,
que o resultado funciona como um IDE
monoltico. A grande exceo costuma
ser para plug-ins de terceiros (criados
externamente ESF), que so freqente-
mente produzidos com poucos recursos
muitos tm uma equipe de um nico
desenvolvedor e por isso acabam no
investindo o esforo necessrio para uma
integrao de qualidade com as outras
ferramentas da ESF.
Acredito que a m fama de integrao
do Eclipse um resqucio do passado,
quando a falta de componentes impor-
tantes obrigava todos os desenvolvedores
a usar um grande nmero de plug-ins
de garagem. Um bom exemplo o
suporte a J2EE/Java EE: plug-ins como o
Lomboz eram peixes fora dgua, pouco
integrados ao resto do IDE; mas o WTP
um exemplo de integrao seamless
(suave, sem remendos) uma extenso
natural do JDT, indistinguvel de um IDE
monoltico. E h exemplos mais severos;
j cheguei a ver plug-ins para o Eclipse
que eram to toscos que chegavam a ter
GUIs construdas com Swing, verdadei-
ros Frankensteins no meio da GUI SWT.
7 Pois outro fator importante que o NetBeans cos-
tumava ser mais completo fora da caixa, dependendo
menos de plug-ins. Mas este fator tem sido minimizado
nos ltimos anos, medida que o Eclipse se torna mais
completo.
Figura 6. 0acee. ae |+.+c ae Net|e+a.. t1e .|ma|e. aae |e|r+ e e.a+rt+ae
Rev_Java53_cromo.pdf 39 Rev_Java53_cromo.pdf 39 20/12/2007 16:40:16 20/12/2007 16:40:16
40 Java Magazine Edio 53
Eclipse x NetBeans
Eram ferramentas que j existiam antes
do Eclipse (ex.: Jalopy), j tinham GUIs
feitas com o Swing e foram transforma-
das em plug-ins a toque de caixa, sem o
esforo de reconstruir a parte visual com
SWT, JFace e outras APIs do Eclipse.
Veredicto
O Eclipse atrai o desenvolvedor aventu-
reiro, que no se incomoda com alguma
integrao manual, o que tem suas van-
tagens pois o Eclipse mais componen-
tizado e flexvel. Para desenvolvedores
de plug-ins, aplicaes RCP e outras que
dependam dos seus frameworks, o Eclipse
ainda leva vantagem, mas j no a van-
tagem esmagadora do passado.
O NetBeans preferido para quem no
quer uma plataforma, mas simplesmente
um IDE, e valoriza um produto mais
acabado. Em especial, estudantes e instru-
tores de programao costumam adorar
o NetBeans por oferecer um instalador
nico que configura o IDE e todas as suas
dependncias em minutos. E as novas
verses so mais estveis. Simplesmente
funciona: parece chavo de marketing,
mas reflete a minha experincia.
Outro ponto onde o Eclipse parece supe-
rior na internacionalizao: traduzido
para 23 idiomas (Eclipse 3.2)... exceto
pelo detalhe que os translation packs
costumam ser doados pela IBM com
vrios meses de atraso aps cada rele-
ase, e cobrem somente os componentes
principais, mas nem de longe a totalidade
dos plugins da ESF. J as tradues do
NetBeans so em nmero mais modesto,
mas melhorando rapidamente: seis para o
5.5.1, doze para o 6.0 (isso considerando as
tradues completas; h vrias tradues
parciais em outros idiomas). Vrias das
tradues so mantidas pela comunidade
(com apoio da Sun). A lista de idiomas
suportados j inclui o portugus brasilei-
Figura 7. O Package Explorer do Eclipse, cheio de enfeites e opes teis
ro
8
, que hoje um dos idiomas oficiais
do NetBeans, juntamente com japons,
chins e ingls.
Funcionalidade, desempenho e
usabilidade
Toda funcionalidade implementada por
qualquer aplicao tem algum custo, no
mnimo no seu tamanho e em consumo
de recursos, e freqentemente tambm na
curva de aprendizado. Quem j no recla-
mou de aplicaes inchadas, complexas
e devoradoras de memria devido a uma
lista interminvel de funcionalidades, 90%
das quais inteis para a grande maioria dos
usurios? Os IDEs no escapam do conflito
entre esses trs critrios fundamentais
de design nmero de funcionalidades,
desempenho e facilidade de uso. Pelo con-
trrio, esto na classe de aplicaes que
mais sofrem com isso, devido demanda
imposta por plataformas e projetos cada
vez mais complexos.
Eclipse
O Eclipse pertence, indiscutivelmente, ao
grupo das aplicaes que primam pelo re-
finamento ou para os crticos, que pecam
pelo excesso. No falo da presena de fun-
cionalidades, pois nisso h uma paridade
entre todos os IDEs de primeira linha: todos
fazem de tudo, do bsico (editor, compila-
dor, depurador...) ao avanado (EJB, JSP, web
services etc.), ltima moda (SOA, Ajax, ...).
Existem poucas excees, por exemplo o
Eclipse ainda se arrasta no suporte a Java
ME, mas so questes pontuais. Eu me
referia mesmo ao nvel de sofisticao de
cada funcionalidade que implementada.
Tudo aquilo que feito pelo Eclipse, parece
ser feito da maneira mais completa possvel.
Ou pelo menos, da maneira mais configur-
vel possvel mas isso certamente d uma
forte impresso no sentido de funcionali-
dades mais completas.
Um bom exemplo disso a j mostrada
Figura 1. Compare-a ao espartano dilogo
de opes de compilao de projetos do
NetBeans (Figura 6), que expe somente
duas opes do javac, respectivamente
para os switches -g e -deprecation. Uma ter-
8 Numa iniciativa de grande sucesso, coordenada pelo
SouJava.
Rev_Java53_cromo.pdf 40 Rev_Java53_cromo.pdf 40 20/12/2007 16:40:16 20/12/2007 16:40:16
Edio 53 Java Magazine 41
ceira opo, Track Java dependencies, desa-
bilita a recompilao automtica de fontes
modificados em aes como Run (mesmo o
Eclipse tem uma opo semelhante). E um
quarto e ltimo campo, Additional Compiler
Options, permite digitar quaisquer opes
extras para o javac.
Parte dessa diferena se deve grande
inferioridade do javac em comparao
com o compilador do JDT, o qual possui
um nmero muito maior de opes de
compilao. Mas outra parte omisso
mesmo; o NetBeans no possui um dilogo
de configurao que suporte nem mesmo
o nmero reduzido de opes do javac o
que inclui algumas importantes, como
Xlint, ou a possibilidade de especificar
opes -source e -target distintas.
Exi stem cenrios em que um alto
grau de controle e configurabilidade
valioso. No Eclipse, por exemplo, veja
Window>Preferences>Java>Code Style. Nes-
te dilogo, pode-se configurar opes de
Clean up (revises automatizadas de
cdigo), Code Templates (modelos para
gerao de cdigo), Formatter (forma-
tao automtica), e Organize Imports
(ordenao e agrupamento dos imports).
Algum poder argumentar que o Net-
Beans tem as mesmas capacidades, mas
a configurabilidade do Eclipse quase
sempre maior. Por exemplo, o recurso de
organizao de imports permite especifi-
car critrios de ordenao no-alfabtica,
ou o nmero de imports do mesmo pacote
exigidos para justificar um import sob
demanda (.*).
H casos importantes em que a confi-
gurabilidade no implica somente em
mais opes, mas torna-se uma funcio-
nalidade parte, de grande valor. Por
exemplo, no Eclipse no h apenas uma
configurao global nica das opes
de estilo de cdigo citadas acima.
possvel definir diversos perfis de Clean
up e de Formatter, e alternar entre estes
perfis. Cada projeto individual pode ser
configurado para usar um desses perfis,
portanto vrios projetos com padres de
estilo diferentes por exemplo, voltados
a clientes diferentes podem conviver.
Melhor ainda, todas essas configuraes
(mesmo aquelas que no contam com o
recurso de perfis) podem ser definidas
nas propriedades de cada projeto. Este
ltimo recurso crtico para ambientes
de desenvolvimento profissionais, espe-
cialmente em equipe, pois permite que
todas as configuraes que afetam um
projeto sejam versionadas no repositrio
de fontes (junto com o resto do projeto).
Assim, no ser preciso que cada desen-
volvedor configure opes globais do
IDE da mesma forma.
O Eclipse tambm se esmera em expor
o mximo de informaes possveis sobre
tudo. Veja, por exemplo, o Package Explorer,
que exibe os recursos (classes, bibliotecas
e outros artefatos) de cada projeto. Dando
uma rpida olhadela, voc poder achar que
o Eclipse e o NetBeans so equivalentes nes-
se aspecto, pois a janela Projects do NetBeans
(mostrada na Figura 2) tambm bonita e
organizada. Mas considere a lista de exclu-
sividades do Eclipse (veja a Figura 7):
%Suporte a decoraes, que so modi-
ficaes na apresentao de cada recurso,
podendo ser contribudas por plug-ins
9
.
Os exemplos mais bsicos so as deco-
raes de modificadores, por exemplo,
um S no canto superior direito do cone
de um mtodo ou atributo indicando
que este static. Mas h muito mais. O
controle de verses mostra os recursos
9 O NetBeans tambm parece ter uma capacidade se-
melhante, porm provavelmente menos capaz, e certa-
mente muito menos explorada por ferramentas tanto do
IDE bsicos quanto de plug-ins.
modificados, nmero de verso, data
da ltima modificao etc. Um plug-in
de cobertura de cdigo (por exemplo)
indica quais classes tiveram seu nvel de
cobertura com um mini-cone no canto
superior esquerdo da classe; e direita
da classe, vemos o resultado da cobertu-
ra. Alm disso, um cone de advertncia
mostrado na figura (um tringulo ama-
relo com um !) no foi produzido pelo
compilador, e sim pelo PMD, um plug-in
de validao de cdigo.
%Vrios filtros permitem determinar
quais artefatos sero exibidos ou ocultados.
Por exemplo, voc no acha uma boa idia
que ao expandir uma classe, seus membros
privados no sejam exibidos na sub-rvore
de itens da classe (pois isso economiza
espao e ajuda a focar nos itens que fazem
parte da interface pblica da classe)? H
um filtro para isso, e muito mais.
%O recurso de Working Set do Eclipse
permite agrupar ou filtrar projetos.
%H alguns controles para navegao en-
tre projetos (Back, Up, etc.) e outras opes
de exibio.
Agora, vamos ao outro lado da moeda.
Um leitor mais crtico poder argumentar
que nenhuma das funcionalidades des-
critas nessa seo absolutamente fun-
damental. Mesmo os recursos mais teis
apresentados, como os perfis e a configura-
bilidade por projeto de opes de estilo de
Figura 8. |..|.teate ae cr|+c1e ae are|ete we| ae Net|e+a.
Rev_Java53_cromo.pdf 41 Rev_Java53_cromo.pdf 41 20/12/2007 16:40:16 20/12/2007 16:40:16
Eclipse x NetBeans
42 Java Magazine Edio 53
cdigo, podem ser contornados sem tanto
trabalho. Por exemplo, um usurio do
NetBeans poderia utilizar um workspace
10
diferente para os projetos associados a
cada cliente ou outro critrio que exige
um estilo de cdigo particular. (Mesmo
no Eclipse h quem faa isso, porque no
gosta de workspaces gigantes, ainda que
contando com o recurso de Working Sets
para minimizar a confuso.)
E a contrapartida de todo o rebuscamento
do Eclipse a complexidade da sua GUI,
que impe uma curva de aprendizado
sem dvida maior que a do NetBeans.
Entretanto, essa uma reclamao questio-
nvel, principalmente quando vemos que
novas verses do NetBeans correm atrs
do Eclipse por exemplo, at a verso 5.5
o NetBeans oferecia uma capacidade de
auto-formatao pfia, mas o 6.0 tem um
formatador sofisticado com centenas de
opes, como o do Eclipse. Ento, criticar
10 Embora o NetBeans no possua este conceito (um
diretrio que contm as conguraes, projetos e ar-
quivos temporrios), fcil simul-lo: basta invocar o
NetBeans com a opo netbeans_default_userdir.
o Eclipse pela sua GUI barroca, com infin-
dveis enfeites para ver, botes para clicar
e dilogos para configurar, parece uma
forma de dizer que as uvas esto verdes.
NetBeans
O NetBeans ganhou fama por ter uma
GUI consistente e eficiente, com uma
curva de aprendizado suave. Parte dessa
qualidade se deve ao design e implemen-
tao unificados. Os projetos do Eclipse
para aproveitar sua prpria metfora
astronmica podem ser vistos como
um bando de planetas e satlites girando
de forma relativamente independente,
ainda que integrados em mtua rbita
por um excelente sistema de plug-ins e
frameworks fundamentais. Assim, a equi-
pe da IBM implementa o JDT, enquanto
uma equipe da Actuate cuida do BIRT,
a Nokia cuida do MTJ... J o NetBeans
(mantendo a metfora) uma estrela
massiva de energia concentrada: h uma
equipe nica da Sun responsvel por
praticamente todo o projeto
11
. Em tempos
de valorizao do cdigo livre e do ideal
do desenvolvimento por comunidades,
um rpido reality check revelar que o
desenvolvimento e principalmente, o
planejamento centralizado ainda pro-
porciona vantagens substanciais.
Vimos, no entanto, que o NetBeans pa-
rece perder para o Eclipse no nvel de de-
senvolvimento de cada funcionalidade que
est presente em ambos. Na maioria dos
casos essa diferena pode ser apenas de
flexibilidade ou de facilidade de customi-
zao; mas uma diferena que no pode
ser negada. Um aspecto dessa diferena
que o Eclipse parece ser superior para
usurios ou projetos avanados. Outro
aspecto que o Eclipse se revela muito
mais complexo, e o benefcio que justifica
esta complexidade no atinge todos os
usurios ou todos os projetos.
Uma tendncia de quase t udo en-
volvendo tecnologia o aumento de
complexidade, e, mais uma vez, os IDEs
esto entre os produtos que mais sofrem
com isso. Mas em anos recentes, temos
percebido uma onda de reaes a esta
tendncia. Exemplos: metodologias
geis como XP, persistncia baseados
em POJOs, injeo de dependncias, e a
configurao por exceo populariza-
da pelo Ruby on Rails.
Vejamos um estudo de caso: ao criar
um projeto web, o NetBeans apresenta
um assistente com duas pginas bem
organizadas e racionais, contendo apenas
questes importantes e compreensveis
por qualquer um que conhea Java EE:
verso da plataforma, raiz do contexto
web, servidor e frameworks usados. No
parece faltar nada. Veja a primeira pgina
desse wizard na Figura 8.
Mas se examinarmos o Eclipse 3.3/WTP
2.0, veremos que o assistente equivalente
possui at cinco pginas. E inclui questes
como: O projeto deve ter a facet de JPA? Se
tiver (Figura 9), voc quer que as classes
JPA sejam descobertas automaticamente
pelas suas anotaes, ou que seja obriga-
11 Tanto a ESF quanto netbeans.org possuem diversos
colaboradores individuais, ou de pequenas empresas, e
este comentrio no pretende desvalorizar sua contri-
buio. No entanto, inegvel que em ambos os projetos,
a colaborao de gigantes como a IBM e a Sun ainda
excessiva para que estes projetos possam ser descritos
como de comunidade.
Figura 9. Assistente de criao de projeto web do Eclipse, na pgina de JPA
Rev_Java53_cromo.pdf 42 Rev_Java53_cromo.pdf 42 20/12/2007 16:40:17 20/12/2007 16:40:17
Osvaldo Pinali Doederlein
(opinali@gmail.com)
Mestre em Engenharia de
Software Orientado a Objetos,
membro individual do Java Community
Process e trabalha na Visionnaire Informtica como
arquiteto e desenvolvedor.
trio list-las no persistence.xml? Precisa
de um orm.xml?... Algumas opes so
conceitos especficos ao Eclipse/WTP (ex.
facets). Algumas outras so flexibilidades
de raro valor.
No so poucos os casos em que a con-
figurabilidade e a flexibilidade extra do
Eclipse o tornam mais complicado para
todo mundo, e mais til s para muito
poucos. E estes casos raros quase sempre
podem ser atendidos pelo NetBeans, s
vezes exigindo alguma configurao ma-
nual, s vezes exigindo outros mtodos
de trabalho (por exemplo, ferramentas de
validao de cdigo podem ser usadas
por arquitetos e gerentes de projeto para
garantir a observncia de muitas diretri-
zes). Em resumo: o NetBeans torna o caso
excepcional um pouco mais trabalhoso,
mas em troca mantm mais simples o
caso comum.
Observe que o NetBeans muitas vezes
tambm possui facilidades extra, que o
Eclipse no tem. Por exemplo, no NetBeans
o assistente de criao de projeto web
pergunta se voc quer usar o Struts, e se
quiser, configura totalmente o projeto,
adicionando bibliotecas e modificando
descritores. O WTP no inclui nenhum
suporte a Struts, pois este no um pa-
dro Java EE. O NetBeans tambm prio-
riza os padres oficiais das plataformas
Java; afinal o IDE da Sun, a principal
criadora e mantenedora desses padres.
Mas faz algumas concesses para pa-
dres de fato como o Struts. O NetBeans
faz a coisa certa ao levar em considerao
a popularidade ainda enorme do Struts.
um exemplo de extra que simplifica o
IDE: pois muita gente usa esse framework
da Apache e quem usa s precisa ativar
um checkbox.
A deciso do Eclipse mais um vestgio
da sua natureza de plataforma e no de pro-
duto: para um componente de plataforma
como o WTP, faz sentido mapear funcio-
nalidades de forma rgida a especificaes
como a Java EE. O trabalho de adicionar
extras importantes no mundo real, que ge-
ralmente mais complicado que o mundo
das JSRs, fica por conta dos fornecedores de
produtos IDEs baseados no Eclipse. Ex-
perimentei vrios, inclusive os da prpria
IBM, que tm suporte a Struts.
E o desempenho?
No lado do desempenho vejo pouca di-
ferena; ambos os IDEs consomem muitos
recursos. Os dois podem devorar centenas
de megabytes com facilidade, especialmen-
te ao usar as ferramentas mais avanadas
(editores visuais, modelagem, SOA etc.).
O fato que ambos os IDEs so vtimas
da escalada de funcionalidades avana-
das que caracteriza qualquer plataforma
madura e de sucesso, como as plata-
formas Java. Estas plataformas, como
sabemos, suportam aplicaes avanads-
simas, tm uma abundncia incrvel de
bibliotecas, frameworks e ferramentas. O
resultado que os IDEs tm que suportar
tudo isso, e ainda por cima com a maior
produtividade possvel. Mesmo para os
puristas que preferem ter apenas um bom
editor de cdigo (talvez um depurador
e olhe l), a tecnologia moderna oferece
tantas tentaes... por exemplo, auto-
completamento de cdigo visto como
um recurso essencial de qualquer editor
moderno. O que muitos no param para
pensar que este recurso um enorme
consumidor de recursos. Exige que o IDE
construa um ndice de todas as classes,
mtodos e outros elementos, tanto de
todas as bibliotecas disponveis quanto
dos fontes de todos os projetos sendo
editados. A atualizao destes ndices
exige bastante I/O e CPU, embora cos-
tume ser otimizada com a persistncia
dos ndices pr-computados em disco.
Ao usar o editor, os ndices devem ser
acessveis muito rapidamente por isso
costumam ser mantidos (pelo menos
parcialmente) em memria, o que torra
RAM. Desligue o auto-completamento,
e voc ganhar muitos megabytes de
volta. Mas quem pode se dar ao luxo de
desligar isso? Temos APIs com milha-
res de classes; de quantos mtodos de
JComponent (por exemplo) voc se lembra
de cor, inclusive com os parmetros na
ordem e tipos corretos?
Minha dica: memria RAM cada vez
mais barata, instale 2Gb e pare de reclamar
do seu IDE. O pobrezinho s est tentando
ajud-lo a ser mais produtivo!
Concluses
Nessa guerra de gigantes, o grande ven-
cedor o desenvolvedor, que conta com
pelo menos uma excelente opo ideal
para suas preferncias, seu estilo de tra-
balho. O nico ponto a lamentar que os
dois IDEs poderiam ser mais prximos. J
se falou de compatibilidade de APIs para
desenvolvimento de plug-ins portveis,
mas isso resultou num fiasco, previsto por
esta coluna (JSR-198). O que eu realmente
gostaria de ver uma aproximao das
licenas idealmente, com a adoo dual
da GPL pela ESF. Isso permitiria um forte
intercmbio de tecnologia entre ambas
comunidades. Por outro lado, tambm
podemos lembrar do velho ditado em
time que est ganhando no se mexe.
E nesse jogo fcil ver que os dois times
esto ganhando, pois h poucos exemplos
da competio entre dois produtos ou
projetos de software resultando em tantos
benefcios para seus usurios.
Edio 53 Java Magazine 43
Rev_Java53_cromo.pdf 43 Rev_Java53_cromo.pdf 43 20/12/2007 16:40:17 20/12/2007 16:40:17
44 Java Magazine Edio 53
Crie passo a passo um relatrio com grupos e
Relatrios com Jasper
N
este artigo, vamos mostrar, em
um exemplo realista e prtico,
como combinar duas tecnologias
importantes em aplicaes comerciais: a
API de gerao de relatrios JasperReports
e a Java Persistence API (JPA).
O exemplo visa suportar o levantamento
das horas gastas em projetos de desen-
volvimento para funcionrios de uma
empresa de software. A Figura 1 mostra
o resultado final do relatrio que ser
criado. O projeto web usado neste artigo
tem uma nica pgina JSP que contm um
link para o servlet que executa o relatrio.
Ele baseado em trs entidades: Projeto,
Funcionrio e Lanamento. Os dados
do relatrio so obtidos a partir de um
banco MySQL. O diagrama de classes do
projeto mostrado na Figura 2 e as tabelas
do banco na Figura 3. Disponibilizamos
para download no site da Java Magazine o
projeto completo, juntamente com o script
para criao do banco de dados.
Para facilitar o desenvolvimento, vamos
usar o iReport para o layout do relatrio e o
NetBeans 6.0 para desenvolver a aplicao
web e as entidades JPA. Usaremos tambm
o servidor de aplicaes Apache Tomcat
6, que vem integrado com o NetBeans,
bem como a implementao JPA fornecida
com este IDE (o TopLink Essentials). Voc
pode obter o iReport em jasperforge.org/sf/
projects/ireport (todas as bibliotecas neces-
srias, inclusive as do JasperReports, so
includas no download principal).
Criando o projeto
No NetBeans, v em File|New Project,
selecione Web Application e clique em Next.
Digite ControleProjetos para o nome do
projeto, clique em Next e na ltima tela
clique em Finalize.
Clique com o boto direito sobre o n
do projeto e selecione Properties. Na janela
que aparece, escolha Libraries, esquerda.
Rev_Java53_cromo.pdf 44 Rev_Java53_cromo.pdf 44 20/12/2007 16:40:17 20/12/2007 16:40:17
Edio 53 Java Magazine 45
totalizaes
Reports e JPA
Usando o editor de
relatrios iReport e a API
open source JasperReports,
alm da Java Persistence
API e o NetBeans 6.0,
para criar relatrios com
produtividade
ANA ABRANTES
Clique em Add Library, selecione TopLink
Essentials e confirme clicando no outro
boto Add Library.
Depois clique em Add JAR/Folder e colo-
que os arquivos JAR que esto na pasta lib
do iReport, conforme se v na Figura 4. Na
parte esquerda desta janela, selecione Run
e coloque /index.jsp no item Relative URL.
Finalize a configurao clicando em OK.
Unidade de Persistncia
O prximo passo criar a unidade de
persistncia JPA. V em File|New File e no
quadro Categories selecione Persistence. Em
File Types escolha Persistence Unit e clique
em Next. Na janela seguinte, j aparecer
o nome ControleProjetosPU, que no
precisa ser alterado.
Mude Persistence Library para TopLink (o
Figura 1. Resultado final do relatrio
Figura 2. Diagrama de classes (para as entidades)
Figura 3. Tabelas do banco de dados
default) e em Database Connection selecione
a URL de conexo para o banco de dados
que ser usado no projeto (voc precisar,
claro, ter criado o banco de dados indicado
no incio do artigo). Caso no exista uma
conexo, crie uma nova selecionando New
Database Connection. No item Table Generation
Strategy selecione None e clique em Finish.
Entidades
Vamos criar as classes
das entidades Projeto,
Funcionario e Lancamento,
usando recursos do Net-
Beans e depois customi-
zando o cdigo gerado.
Selecione File|New File
e selecione a categoria
Persistence. Escolha En-
tity Classes from Database e clique em Next.
Na janela que aparecer, selecione a nossa
conexo e mova as tabelas FUNCIONA-
RIOS, PROJETOS e LANCAMENTOS
para o quadro Selected Tables usando Add;
depois clique em Next. Na tela seguinte,
mude o nome das classes tirando a letra
s do final. Tambm digite um nome de
pacote em Package. Ao clicar em Finish, as
Rev_Java53_cromo.pdf 45 Rev_Java53_cromo.pdf 45 20/12/2007 16:40:17 20/12/2007 16:40:17
Relatrios com Jasper Reports e JPA
46 Java Magazine Edio 53
classes sero criadas. Veja uma seleo
de telas na Figura 5. Esses passos geram
para voc a maior parte do persistence.xml
(Listagem 1) o arquivo de configuraes do
JPA. Este arquivo pode ser encontrado no
nConfiguration Files do projeto. Devem ser
criadas algumas propriedades adicionais
para a conexo ao banco de dados, como
se v na listagem.
Ser necessrio tambm alterar o cdigo das
classes, porque alguns detalhes o NetBeans
no consegue deduzir sozinho a partir
do nosso modelo de dados. O tipo de al-
guns atributos pode no vir corretamente
(Object em vez de inteiro, por exemplo).
Tambm precisamos adicionar a anotao
@GeneratedValue no atributo id das trs clas-
ses usando strategy=GenerationType.IDENTITY,
pois as tabelas utilizam auto-incremento.
No precisamos da anotao @Lob nem
@NamedQueries, ento vamos apag-las. Ou-
tra coisa necessria definir um relacio-
namento muitos-para-muitos entre Projeto
e Funcionario. Confira o cdigo alterado das
entidades nas Listagens 2, 3 e 4.
Servlet
Crie um servlet indo em New|Servlet e
configure-o conforme a Figura 6. Depois
abra o arquivo gerado para acrescentarmos
cdigo Java.
O servlet, que usado para executar o
relatrio (que criaremos em seguida), vai
precisar do arquivo .jasper, de alguns par-
metros que devero estar em um Map e
do EntityManager (que gerencia a persistn-
cia no JPA). Veja na Listagem 5 o cdigo
completo do servlet GeraRelatorio. Nele so
realizados os seguintes passos:
1. Carregamos o arquivo .jasper num
objeto JasperReport usando o caminho
real do arquivo, atravs do contexto da
aplicao.
2. Criamos um Map para os parmetros
do relatrio.
3. Obtemos um objeto EntityManager e o
acrescentamos como um parmetro.
4. Executamos o relatrio usando o mto-
do runReportToPdf(), da classe JasperRunManager,
gerando a sada em PDF. Passamos o objeto
JasperReport e o Map de parmetros, e recebe-
mos seu retorno num array de bytes.
5. No final, jogamos este array de bytes
no OutputStream do objeto response para que
Listagem 1. persistence.xml
<?xml version=1.0 encoding=UTF-8?>
<persistence version=1.0
xmlns=http://java.sun.com/xml/ns/persistence
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation=http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd>
<persistence-unit name=ControleProjetosPU transaction-type=RESOURCE_LOCAL>
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<class>br.com.globalcode.model.Lancamento</class>
<class>br.com.globalcode.model.Funcionario</class>
<class>br.com.globalcode.model.Projeto</class>
<properties>
<property name=toplink.jdbc.url value=jdbc:mysql://localhost:3306/jm/>
<property name=toplink.jdbc.user value=jm/>
<property name=toplink.jdbc.driver value=com.mysql.jdbc.Driver/>
<property name=toplink.jdbc.password value=jm/>
</properties>
</persistence-unit>
</persistence>
Listagem 2. Entidade Projeto
package br.com.globalcode.model;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.*;
@Entity @Table(name=projetos)
public class Projeto implements Serializable {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = id, nullable = false)
private Integer id;
@Column(name = descricao, nullable = false)
private String descricao;
@Column(name = inicio, nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date inicio;
@Column(name = termino_previsto, nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date terminoPrevisto;
@Column(name = termino_efetivo)
@Temporal(TemporalType.TIMESTAMP)
private Date terminoEfetivo;
@OneToMany(cascade = CascadeType.ALL, mappedBy = projeto)
private Collection<Lancamento> lancamentoCollection;
@ManyToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE})
@JoinTable(name=projetos_funcionarios,
joinColumns={@JoinColumn(name=id_projeto,
referencedColumnName=id)},
inverseJoinColumns={
@JoinColumn(name=id_funcionario,
referencedColumnName=id)
}
)
private Collection<Funcionario> funcionarioCollection;
public Projeto() {
super();
}
//... mtodos get/set, equals() etc. omitidos
}
Rev_Java53_cromo.pdf 46 Rev_Java53_cromo.pdf 46 20/12/2007 16:40:17 20/12/2007 16:40:17
Edio 53 Java Magazine 47
o relatrio seja visualizado diretamente
dentro do navegador web, que vai executar
o aplicativo visualizador correspondente,
como por exemplo o Adobe Reader.
O ltimo passo de preparao: compilar
o projeto, para que as classes de entida-
des se tornem acessveis posteriormente
dentro do iReport, quando formos criar
o template do relatrio. Faa isso com F11
ou Build|Build Main Project.
Sobre a persistncia
Antes de continuar o tutorial, vamos
rever alguns conceitos de JPA usados no
exemplo.
Conforme pode ser visto no diagrama
de classes j mostrado na Figura 2 e nas
tabelas (Figura 3), o projeto possui dois
tipos de relacionamento: um-para-muitos
e muitos-para-muitos. Estes so especifica-
dos atravs de anotaes JPA, como vimos
nas listagens das entidades.
O relacionamento um-para-muitos
representado pela anotao @OneToMany.
O atributo lancamentoCollection das classes
Projeto e Funcionario usa o parmetro mappedBy
desta anotao para indicar qual atributo
da classe Lancamento mantm a associao.
J na classe Lancamento, usamos @ManyToOne
para representar o inverso, juntamente
com a anotao @JoinColumn.
@JoinColumn usada para indicar qual
campo de cada tabela usado na ligao.
O parmetro name indica o campo que est
na prpria tabela e referencedColumnName
indica o campo da tabela que est sendo
referenciado.
Com @ManyToMany, como indica o nome,
fazemos o mapeamento do relacionamento
muitos-para-muitos, neste caso entre as
classes Projeto e Funcionario. A classe que
domina esse relacionamento Projeto,
por isso nela so colocadas anotaes
@ManyToMany e @JoinTable, com os parme-
tros para fazer a ligao entre as tabelas
PROJETOS e FUNCIONARIOS, atravs
da tabela intermediria PROJETOS_FUN-
CIONARIOS.
Na anotao @JoinTable, o parmetro name
define a tabela intermediria; joinColumns,
as colunas de ligao entre a tabela inter-
mediria e a tabela proprietria da asso-
ciao, usando name e referencedColumnName
Figura 4. Configurando as bibliotecas de relatrios
Figura 5. Criao das classes de entidades
Rev_Java53_cromo.pdf 47 Rev_Java53_cromo.pdf 47 20/12/2007 16:40:17 20/12/2007 16:40:17
48 Java Magazine Edio 53
Relatrios com Jasper Reports e JPA
de @Joi nCol umn, respect ivament e. E
inverseJoinColumns define as colunas de jun-
o entre a tabela intermediria e a tabela
no-proprietria da associao, usando
@JoinColumn da mesma forma.
Agora vamos ao prximo grande passo:
Listagem3. Entidade Funcionario
package br.com.globalcode.model;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.*;
@Entity @Table(name=funcionarios)
public class Funcionario implements Serializable {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = id, nullable = false)
private Integer id;
@Column(name = nome, nullable = false)
private String nome;
@Column(name = matricula, nullable = false)
private int matricula;
@Column(name = admissao, nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date admissao;
@OneToMany(cascade = CascadeType.ALL, mappedBy = funcionario)
private Collection<Lancamento> lancamentoCollection;
@ManyToMany(mappedBy=funcionarioCollection)
private Collection<Projeto> projetoCollection;
public Funcionario() {
}
//... mtodos get/set, equals() etc. omitidos
}
Figura 6. tr|+c1e ae .er.|et ae Net|e+a.
Figura 7. Configurao do classpath no iReport Figura 8. Passos para configurao de uma conexo
a criao do relatrio em si.
Criando o layout do relatrio
Abra o iReport e crie um novo relatrio
escolhendo File|New document, ou clican-
do no boto da barra de ferramentas.
Na janela que aparece, defina o nome do
relatrio como Consolidacao; altere a
codificao XML para ISO-8859-1 (na aba
i18n) e clique em OK.
Vamos usar apenas as bandas page
Header e detail; ento vamos eliminar
todas as outras bandas. Execute o co-
mando View|Bands (ou clique no boto
), coloque zero no campo Band height
de cada banda e clique em Apply. (Uma
opo mais direta para definir a altura
de cada banda arrastar verticalmente
uma linha que separa as bandas at que a
banda correspondente desaparea.)
Definindo a fonte de dados
Para que o iReport reconhea as entida-
des, a implementao do JPA e a unidade
de persistncia que estamos usando no
projeto, ser necessrio incluir as classes
correspondentes no seu classpath.
Selecione Options|Classpath e clique no bo-
to Add Folder. Selecione a pasta que contm
as classes de entidade compiladas (WEB-
INF\classes) e clique em Open. Acrescente
tambm a implementao JPA usada no pro-
Rev_Java53_cromo.pdf 48 Rev_Java53_cromo.pdf 48 20/12/2007 16:40:18 20/12/2007 16:40:18
Edio 53 Java Magazine 49
Listagem4. Entidade Lancamento
package br.com.globalcode.model;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;
@Entity @Table(name=lancamentos)
public class Lancamento implements Serializable {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = id, nullable = false)
private Integer id;
@Column(name = inicio, nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date inicio;
@Column(name = termino, nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date termino;
@Column(name = intervalo, nullable = false)
private int intervalo;
@Column(name = conteudo, nullable = false)
private String conteudo;
@JoinColumn(name = id_funcionario, referencedColumnName = id)
@ManyToOne
private Funcionario funcionario;
@JoinColumn(name = id_projeto, referencedColumnName = id)
@ManyToOne
private Projeto projeto;
public Lancamento() {
}
//... mtodos get/set, equals() etc. omitidos
}
Figura 9. Fonte de dados
Expression $F{inicio} $F{termino} $F{intervalo} $V{horasLancamento}
Expression Class java.util.Date java.util.Date java.lang.Integer java.lang.Double
Evaluation Time Now Now Now Now
Pattern dd/MM/yy HH:mm dd/MM/yy HH:mm #,##0.00;#,##0.00-
Tabela 1. Configurao dos campos da aba detail
jeto: clique em Add JAR, selecione o arquivo
toplink-essentials.jar e clique em Open. Depois
clique em Save classpath. Veja a Figura 7.
Devemos configurar tambm a cone-
xo de dados para usar a unidade de
persistncia criada no projeto. V em
Data|Connections/Data Sources. Clique no
boto New, selecione EJBQL connection
e clique em Next. Faa Name=ctrl-proj e
Persistence Unit Name=ControleProjetosPU.
Clique em Test para verificar se est tudo
bem e depois em Save. Configure ainda a
conexo como a default, clicando no boto
Set as Default. Confira na Figura 8.
Vamos definir a query JPA que usare-
mos para recuperar os objetos da fonte
de dados. Com ela vamos obter os fields
a serem usados no layout do relatrio.
Execute o comando Data|Report Query, e
na aba Report Query selecione EJBQL na
caixa Query Language. No quadro da parte
de baixo digite:
select la from Lancamento la
order by la.projeto.id, la.funcionario.id, la.inicio
Em seguida, clique no boto Read Fields:
todos os atributos da classe aparecero no
quadro inferior. Para finalizar clique em
OK (veja a Figura 9).
Criando o cabealho do relatrio
Adicione um Static Text na banda pageHea-
der e d um duplo-clique sobre ele para editar
seu texto. D ao relatrio o nome Relatrio
de Consolidao de Horas por Projeto.
Lanamentos
Na banda detail, adicione quatro Text
Fields e faa as configuraes mostradas
na Tabela 1, na aba Text Field das proprie-
dades de cada um deles.
Note que, para as horas do lanamento,
usamos uma varivel que calcula este va-
lor, mas que somente depois vamos fazer
a sua configurao.
A propriedade Pattern usada para for-
matar o contedo do field. E Evaluation Time
indica em que momento o field deve ser
avaliado pelo JasperReports. Veja que em
todos os fields da banda detail, foi colocado
Now. Isso faz com que o contedo seja ava-
liado a cada Lanamento, ou seja, a cada
objeto da fonte de dados do relatrio.
Nas sees a seguir vamos adicionar
Rev_Java53_cromo.pdf 49 Rev_Java53_cromo.pdf 49 20/12/2007 16:40:18 20/12/2007 16:40:18
50 Java Magazine Edio 53
Relatrios com Jasper Reports e JPA
Figura 10. Template do relatrio
Figura 11. Configurao dos grupos projeto e funcionario
Figura 12. Configurao da varivel horasLancamento
vrios novos elementos ao relatrio. Voc
poder tirar dvidas quanto ao posicio-
namento desses elementos conferindo o
layout final na Figura 10.
Agrupando os lanamentos
No nosso relatrio queremos que apa-
ream para cada projeto os lanamentos
feitos por cada funcionrio que traba-
lhou nele. Para fazer quebras no relatrio
e no repetir informaes, utilizamos
o recurso de grupos do JasperReports.
Vamos agrupar os lanamentos por
projeto e por funcionrio, para impri-
mir somente uma vez os dados de cada
um deles. Para isso precisamos definir
um grupo para cada quebra. Neste caso
teremos dois grupos, um para Projeto e
outro para Funcionario.
Lembrando: quando um grupo criado
no JasperReports, so criadas duas novas
bandas groupFooter e groupHeader. Co-
locamos nestas bandas as informaes
associadas ao grupo (j os dados de cada
item dentro do grupo ficam na banda
detail). Para que os grupos sejam apre-
sentados da maneira esperada, a fonte
de dados deve estar ordenada correta-
mente, pelos campos que determinam o
agrupamento (da a longa clusula order
by na consulta JPA criada anteriormente).
Alm disso, independentemente de como
os dados forem recuperados, deve-se usar
a mesma expresso definida para o grupo
ao fazer a ordenao.
Pode-se ter vrios grupos aninhados,
que o nosso caso: o grupo projeto engloba
os funcionrios que participam de um
projeto, e dentro deste o grupo funcionario
contm os lanamentos do funcionrio.
Quando o grupo projeto, que mais exter-
no, for reinicializado, o grupo funcionario
contido nele tambm o ser.
Grupo de projetos
Para criar o grupo de projetos, escolha
View|Report Groups ou clique no cone
de grupos ( ) na barra de ferramentas;
depois clique em New. Na janela que apa-
rece, configure o grupo conforme se v na
primeira tela da Figura 11.
Na banda projetoHeader, que acabou de
ser criada, vamos colocar dados sobre o
projeto, como descrio, data de incio e
Rev_Java53_cromo.pdf 50 Rev_Java53_cromo.pdf 50 20/12/2007 16:40:18 20/12/2007 16:40:18
Edio 53 Java Magazine 51
Listagem5. GeraRelatorio, servlet que executa o relatrio
package br.com.globalcode.servlet;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.*;
import javax.servlet.*;
import javax.servlet.http.*;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.query.JRJpaQueryExecuterFactory;
public class GeraRelatorio extends HttpServlet {
protected void processRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
ServletContext context = this.getServletConfig().getServletContext();
// obtm o arquivo compilado .jasper
File relatorioJasper = new
File(context.getRealPath(/WEB-INF/reports/Consolidacao.jasper));
// parmetros, se houver
Map parametros = new HashMap();
// Busca dados usando JPA e direciona a sada do relatrio para um stream
byte[] bytes = null;
EntityManagerFactory emf =
Persistence.createEntityManagerFactory(ControleProjetosPU);
EntityManager em = emf.createEntityManager();
try {
parametros.put(JRJpaQueryExecuterFactory.PARAMETER_JPA_ENTITY_MANAGER, em);
bytes =
JasperRunManager.runReportToPdf(relatorioJasper.getPath(),parametros);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (em.isOpen()) em.close();
if (emf.isOpen()) emf.close();
}
if (bytes != null && bytes.length > 0) {
// Envia o relatrio em formato PDF para o browser
response.setContentType(application/pdf);
response.setContentLength(bytes.length);
ServletOutputStream ouputStream = response.getOutputStream();
ouputStream.write(bytes, 0, bytes.length);
ouputStream.flush();
ouputStream.close();
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
}
}
Listagem6. index.jsp, pgina com link para o servlet que executa o relatrio
<%@page contentType=text/html%>
<%@page pageEncoding=ISO-8859-1%>
<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN
http://www.w3.org/TR/html4/loose.dtd>
<html>
<head>
<meta http-equiv=Content-Type content=text/html; charset=ISO-8859-1>
<title>Relatrio de Consolidao de Horas</title>
</head>
<body>
<h2>
Clique <a href=pdf>aqui</a> para executar o relatrio em PDF
</h2>
</body>
</html>
data de trmino. Adicione nesta banda um
Text Field e altere sua Text Field Expression
para Projeto: +$F{projeto}.getDescricao().
Ao lado deste campo, coloque dois Static
Fields e mais dois Text Fields intercalados
para as datas. O primeiro Static Field deve
ter o texto Incio em e o outro, Trmi-
no em. E ambos os Text Fields tero Text
Field Expression Class igual a java.util.Date e
Pattern igual a dd/MM/yyyy.
Finalmente, na Text Field Expression do
primeiro Text Field coloque $F{projeto}.
getInicio(), e na do segundo, fornea
$F{projeto}.getTermino().
Grupo de funcionrios
Crie agora o grupo de funcionrios, que
deve ser configurado como na segunda
tela da Figura 11. Na banda funcionarioHe-
ader criada, coloque um Text Field com Text
Field Expression=Funcionrio: +$F{funcionario}.
getNome(). Abaixo, adicione quatro Static
Fields, que serviro de cabealho para os
dados a serem impressos na banda detail.
No texto destes campos digite respecti-
vamente: Incio, Trmino, Intervalo
(min) e Horas.
Configurando variveis de clculos
Variveis no iReport/JasperReports so
objetos especiais usados em expresses.
Elas simplificam o design do relatrio,
permitindo declarar uma nica vez uma
expresso que usada com muita freqn-
cia ou ento para fazer clculos.
Neste relatrio, precisamos calcular
quantas horas tem cada lanamento e
tambm totalizar horas por funcionrio e
por projeto. Criaremos uma varivel para
cada um dos trs clculos. Para criar uma
varivel, escolha View|Variables e clique
no boto New.
A propriedade Variable expression define
a expresso usada para calcular a vari-
vel; Variable class Type determina o tipo
de retorno desta expresso, e Initial Value
Expression define o valor de inicializao
da expresso.
Em Calculation Type definimos o tipo de
clculo usado. Quando usamos Nothing
para esta opo, isso significa que uti-
lizaremos uma frmula prpria; j Sum
indica que queremos somar o resultado
da expresso de clculo a cada objeto da
Rev_Java53_cromo.pdf 51 Rev_Java53_cromo.pdf 51 20/12/2007 16:40:18 20/12/2007 16:40:18
52 Java Magazine Edio 53
Relatrios com Jasper Reports e JPA
fonte de dados encontrado (Lancamento, no
exemplo). ResetType define quando a vari-
vel ser reinicializada; None indica que
nunca ser reinicializada; e Group faz com
que seja reinicializada sempre que mudar
o grupo definido em ResetGroup.
Clculo de horas de cada lanamento
Vistos os conceitos necessrios, vamos
criar uma varivel para fazer o clculo das
horas para cada lanamento. Configure a
varivel conforme a Figura 12. Repare na
expresso usada para o clculo:
new Double(
(((int) ($F{termino}.getTime()/60000))
- ((int) ($F{inicio}.getTime()/60000))
- $F{intervalo}.intValue() ) / 60)
Essa varivel (horasLancamento) usada
no Text Field colocado na banda detail.
Tambm ser usada nas outras variveis
que vamos criar a seguir para fazer tota-
lizaes.
Total por funcionrio
Queremos exibir o total de horas de cada
funcionrio, ou seja, a soma das horas de
todos os seus lanamentos. Para isso, crie
outra varivel conforme a Figura 13 (pri-
meira tela). Feito isso, vamos mostrar o to-
tal obtido nesta varivel, aps listar todos
os lanamentos do funcionrio, adicionan-
do um Text Field banda funcionarioFooter
com as seguintes propriedades:
Figura 13. Configurao de mais duas variveis
jasperforge.org/sf/projects/jasperreports
Site da biblioteca JasperReports, onde se pode
encontrar a pgina para download do software,
bem como documentao, fruns etc.
jasperforge.org/sf/projects/ireport
Site da ferramenta iReport, tambm com downloads,
novidades e outras informaes.
Ana Aparecida Abrantes da Silva
(ana.abrantes@globalcode.com.br)
desenvolvedora Java na Glo-
balcode, co-autora do curso de
JasperReports/iReport e possui algumas
certificaes em Java (SCJA, SCJP e SCWCD). formada
pela Faculdade de Tecnologia de So Paulo (FATEC) e
atua na rea de informtica h 20 anos. Atualmente
pesquisa e testa tecnologias Java para desenvolvimento
de aplicaes web com interfaces ricas, tais como JSF,
RichFaces, Facelets, Seam, entre outras.
Expression $V{horasLancamento Funcionario}
Expression Class java.lang.Double
Evaluation Time Group
Evaluation Group Funcionario
Pattern #,##0.00;#,##0.00-
Fazendo Evaluation time igual a Group,
indicamos que o valor do Text Field deve
ser avaliado sempre que houver quebra do
grupo definido em Evaluation Group.
Total por projeto
Precisamos ainda apresentar o total dos
lanamentos por projeto. Crie para isso
mais uma varivel, como indicado na Fi-
gura 13 (segunda tela). Em seguida, vamos
mostrar o total obtido nesta varivel, aps
listar todos os lanamentos de todos os
funcionrios envolvidos do projeto. Para
isso, coloque um Text Field na banda proje-
toFooter com as seguintes propriedades:
Expression $V{ horasLancamentoProjeto }
Expression Class java.lang.Double
Evaluation Time Group
Evaluation Group Projeto
Pattern #,##0.00;#,##0.00-
Executando o relatrio
Aps criar o layout do relatrio, salve
o arquivo na pasta WEB-INF/reports do
projeto, indo em File|Save (ou pressionan-
do CTRL+S).
Precisamos compilar o relatrio para
que seja possvel us-lo em nosso proje-
to. O arquivo compilado (.jasper) dever
ser gravado na mesma pasta do arquivo
fonte do relatrio (.jrxml). Portanto, v em
Options|Settings|Compiler e certifique-se
de que o item Use Reports Directory to
Compile esteja selecionado. Depois execute
Build|Compile ou clique no boto . Se
no houver erros, o arquivo Consolidacao.
jasper ser gerado.
Para executar o relatrio, voltamos ao
NetBeans. Primeiro vamos re-gerar o ar-
quivo ControleProjetos.war fazendo o build
do projeto (F11). Depois execute o projeto
(com F6). Isso inicia o Tomcat, faz o deploy
do projeto e executa o exemplo no browser
(veja a pgina de ndice na Listagem 6).
Terminamos: clique no link que aparece na
tela do browser, e o relatrio ser gerado.
Concluses
Neste artigo, apresentamos um passo-a-
passo para a criao de um relatrio com
quebras e totalizaes, fazendo o acesso
a dados com JPA. Tambm mostramos
como usar recursos do NetBeans 6.0 para
facilitar o desenvolvimento do projeto,
alm de discutir conceitos importantes do
JasperReports e iReport.
Rev_Java53_cromo.pdf 52 Rev_Java53_cromo.pdf 52 20/12/2007 16:40:18 20/12/2007 16:40:18
Rev_Java53_cromo.pdf 53 Rev_Java53_cromo.pdf 53 20/12/2007 16:40:18 20/12/2007 16:40:18
54 Java Magazine Edio 53
Computao distribuda de forma transparente
Spring Remoting
O
Spring suporta acesso a servios
remotos no modelo RPC (chama-
da remota de procedimentos). O
suporte do framework a servios remotos
abrange os mecanismos mais comuns de
transporte usados em RPC como RMI,
HTTP (utilizando serializao de objetos),
EJBs e web services.
O Spring faz o acesso aos servios re-
motos atravs de um proxy dinmico que
implementa uma interface de negcio. O
mecanismo similar ao uso da tecnologia
JAX-RPC para acessar Web Services. Com
JAX-RPC, criada uma interface service
endpoint pela qual o servio acessado,
remoto com RMI, HTTP e EJB. O acesso
via outros mecanismos bastante simi-
lar: seguem a mesma estrutura, variando
somente classes e algumas propriedades.
O suporte a EJBs particularmente inte-
ressante. Por utilizar um proxy dinmico,
o Spring encapsula e isola o tipo de EJB da
aplicao. Com isso possvel acessar um
EJB local ou remoto da mesma forma
atravs de sua interface de negcio.
Primeiro exemplo
Nosso primeiro exemplo ser uma apli-
cao contendo um componente simples
disponibilizado no servidor, que retorna
a data e a hora do servidor atravs de uma
chamada remota. A aplicao ser imple-
mentada utilizando RMI.
Implementando o exemplo
O primeiro passo a codificao da nossa
interface de negcio, br.com.jm.remoting.
rmi.service.TimerService (veja a Listagem 1).
Esta interface possui apenas um mtodo
que retorna a data e a hora do servidor. A
classe de implementao a TimerServiceImpl
(no mesmo pacote) e mostrada na Lis-
e a transformao dos objetos/valores em
XML ocorre transparentemente.
A grande vantagem do Spring per-
mitir que voc exponha como um ser-
vio remoto a interface de negcio, sem
alteraes. Ou seja, no necessrio
especializar interfaces especficas ou
lanar excees que no fazem parte
do negcio em seus mtodos. J ao usar
JAX-RPC (ou RMI ou EJB), temos que
i ndicar que nossos mtodos lanam
java.rmi.RemoteException. Com o Spri ng
Remoting, todas as excees se tornam
excees de runtime (subclasses de java.
lang.RuntimeException). Assim, claro, o de-
senvolvedor no ser obrigado a trat-las
ou relan-las de forma explcita.
A Figura 1 ilustra a estrutura do acesso
a um servio remoto com o Spring. Re-
pare que o cliente interage somente com
a interface de negcio e que um proxy
(substituto/intermedirio) que se comu-
nica remotamente com o servio.
Quando disponibilizamos um servio
para que seja acessado de forma remota,
o Spring tambm nos auxilia. H o con-
ceito de Exporter, um objeto capacitado a
tornar um bean disponvel remotamente.
A Figura 2 ilustra como funciona a ex-
portao de um bean (nomeado Servi-
o no diagrama).
Veremos neste artigo como fazer o acesso
Rev_Java53_cromo.pdf 54 Rev_Java53_cromo.pdf 54 20/12/2007 16:40:19 20/12/2007 16:40:19
Edio 53 Java Magazine 55
Como usar o suporte fornecido
pelo Spring a mecanismos de
acesso remoto, que abstrai as
complexidades da comunicao
remota para o desenvolvedor
DANIEL CICERO AMADEI
tagem 2. Repare que o mtodo getTime()
retorna apenas um objeto java.util.Date
convertido para String.
Com esses dois itens, j temos um servio
que pode ser disponibilizado no Spring.
Se o configurssemos como um bean no
Spring, j poderamos utiliz-lo na mesma
aplicao. Mas isso no o que desejamos:
precisamos exportar o servio para que se
torne disponvel remotamente.
Exportando um servio
Para exportar um servio, registramos
um novo bean no Spri ng, chamado
Exporter. Depois referenciamos, numa
propriedade do novo bean, o bean que ser
exportado. O cdigo a seguir ilustra essa
exportao no arquivo de configurao
do Spring:
<bean class=org.springframework.remoting.rmi.
RmiServiceExporter>
<property name=service ref=timerService />
<areaert a+me'.er.|ceN+me' .+|ae'I|mer:er.|ce' />
<property name=serviceInterface
value=br.com.jm.remoting.rmi.service.TimerService />
</bean>
Vemos na primeira linha a declarao
do bean. Como o bean no ter que ser
referenciado na mesma aplicao, ele no
precisa ter um nome; por isso o atributo id
omitido. A primeira propriedade, service,
indica qual servio estamos expondo. No
exemplo, exportamos o bean timerService,
que foi definido em algum outro ponto
como um bean comum.
O nome do servio o que ser publi-
cado no registro do RMI e a propriedade
serviceInterface indica a interface de negcio
que o servio remoto implementa.
Acessando um servio remoto
O acesso a um servio RMI via Spring
tambm muito simples. O trecho de XML
a seguir ilustra como acessar o componen-
te que exportamos na seo anterior:
<bean id=timerServiceProxy
class=org.springframework.remoting.rmi.
RmiProxyFactoryBean>
<property name=serviceUrl
value=rmi://localhost/TimerService />
<property name=serviceInterface
value=br.com.jm.remoting.rmi.service.TimerService />
</bean>
Observe que declaramos um bean da
classe RmiProxyFactoryBean e que o bean pos-
sui duas propriedades. A primeira define
a URL pela qual o bean deve ser acessado
pelo registro do RMI (RMI Registry); a se-
gunda especifica a interface que o proxy
gerado pelo Spring ir implementar.
Ao obter esse bean a partir do Spring,
podemos realizar um cast para a interface
TimerService e trabalhar com a referncia
como se fosse local. Porm, todas as invo-
caes sero efetuadas no objeto disponi-
bilizado em rmi://localhost/TimerService.
Finalizando a implementao do exemplo
O XML completo da declarao do Spring
est disponvel na Listagem 3. Repare que
definimos o bean exportado e o proxy na
mesma aplicao, o que vlido apenas para
Figura 1. Arquitetura de Proxy do Spring
Figura 2. Arquitetura de Exporter do Spring
Rev_Java53_cromo.pdf 55 Rev_Java53_cromo.pdf 55 20/12/2007 16:40:19 20/12/2007 16:40:19
56 Java Magazine Edio 53
Spring Remoting
testes em uma aplicao real o Exporter es-
taria em uma aplicao e o Proxy em outra.
A Listagem 4 apresenta o cdigo de um
cliente responsvel por acessar o servio
remoto via Spring. O que o cliente faz
apenas obter o objeto a partir do contexto
do Spring e invocar operaes como se
fosse um objeto local. O cliente imprime no
console o objeto do servio, a classe desse
objeto e o retorno de uma invocao ao
mtodo getTime(). Ao execut-lo, um texto
de trs linhas impresso (com quebras
adicionadas para diagramao):
Objeto representando o servio:
RMI invoker proxy for service URL [rmi://localhost/
TimerService]
Classe retornada pelo Spring:
class $Proxy0
Data e hora no servidor:
Fri Jun 22 18:36:43 GMT-03:00 2007
A primeira linha resultante do mtodo
toString() do proxy, indicando que ele real-
mente um intermedirio/substituto para
um objeto RMI disponibilizado em rmi://lo-
calhost/TimerService. A segunda linha indica
a classe que representa o objeto. Veja que se
trata de um proxy dinmico, representado
por $Proxy0 (o nome exato da classe pode
variar). Por fim, imprimimos o retorno da
execuo do mtodo de negcio, o que mos-
tra a data e a hora obtidas no servidor.
Alm disso, se voc executar o exemplo
sem alterar as configuraes de logging do
Spring, ver que informaes interessantes
sobre a exposio do objeto como um obje-
to remoto so escritas no log. Veja algumas
dessas informaes a seguir:
|N|0. |ee||aa ler |M| rea|.tr +t aert ''
|N|0. tea|a aet aetect |M| rea|.tr - cre+t|aa aew eae
|N|0. ||aa|aa .er.|ce 'I|mer:er.|ce' te |M| rea|.tr.
RegistryImpl_Stub[UnicastRef
[liveRef: [endpoint:[127.0.0.1:1099](remote),objID:[0:0:0,
0]]]]
Vemos primeiramente que o Spring tenta
localizar o registro RMI na porta 1099. pos-
svel customizar vrias opes sobre como
o Spring lida com esse registro. Vemos, por
exemplo o endereo IP e o nmero da porta
onde obter ou disponibilizar o registro, bem
como o socket; indicado tambm se um
registro novo deve sempre ser criado, entre
vrias outras informaes. Como no nosso
caso o Spring no encontra o registro na m-
quina local, na porta 1099, criado um novo
Listagem 1. Interface de negcio
package br.com.jm.remoting.rmi.service;
public interface TimerService {
public String getTime();
}
Listagem 2. Implementao da interface de negcio
package br.com.jm.remoting.rmi.service;
import java.util.Date;
public class TimerServiceImpl implements TimerService {
public String getTime() {
return new Date().toString();
}
}
Listagem 3. Configurao do Spring
<?xml version=1.0 encoding=UTF-8?>
<beans ...>
<bean id=timerService
class=br.com.jm.remoting.rmi.service.TimerServiceImpl />
<bean class=org.springframework.remoting.rmi.RmiServiceExporter>
<property name=service ref=timerService />
<property name=serviceName value=TimerService />
<property name=serviceInterface value=br.com.jm.remoting.rmi.service.TimerService />
</bean>
<bean id=timerServiceProxy
class=org.springframework.remoting.rmi.RmiProxyFactoryBean>
<property name=serviceUrl value=rmi://localhost/TimerService />
<property name=serviceInterface value=br.com.jm.remoting.rmi.service.TimerService />
</bean>
</beans>
Listagem 4. Cliente responsvel por acessar o servio remoto
package br.com.jm.remoting.rmi.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import br.com.jm.remoting.rmi.service.TimerService;
public class Client {
private static final ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(applicationContext.xml);
public static void main(String[] args) throws Exception {
TimerService service = (TimerService) applicationContext.getBean(timerServiceProxy);
System.out.println(Objeto representando o servio: + service + );
System.out.println(Classe retornada pelo Spring:
+ service.getClass() + );
System.out.println(Data e hora no servidor:
+ service.getTime() + );
}
}
Listagem 5. Classe Papel, que representa uma ao.
package br.com.jm.spring.remoting.papel;
//imports...
public class Papel implements Serializable {
private String simbolo;
private String variacao;
private String vlAtual;
private String fechAnterior;
// getters e setters...
Rev_Java53_cromo.pdf 56 Rev_Java53_cromo.pdf 56 20/12/2007 16:40:19 20/12/2007 16:40:19
Edio 53 Java Magazine 57
registro. Depois, o servio registrado sob o
nome de TimerService, o que indicado pela
ltima mensagem de log apresentada.
Enterprise JavaBeans
O Spring permite declarar EJBs direta-
mente em sua configurao, como fazemos
com quaisquer outros beans. Fazendo isso,
os EJBs podem ser obtidos a partir da con-
figurao do Spring, sem a complexidade
de lidar com JNDI ou outras peculiarida-
des do modelo de componentes do Java EE.
EJBs podem tambm ser injetados como
propriedades em outros beans.
O Spring permite tratar EJBs remotos
e locais de maneira uniforme. A uni-
formidade no tratamento dos dois tipos
distintos de EJBs resultado do uso de um
proxy dinmico. Ao utilizar essa tcnica,
o Spring prov acesso simplificado ao EJB
e trata as possveis excees lanadas, que
teriam que ser manipuladas pelo desen-
volvedor caso utilizasse o componente EJB
diretamente. Por exemplo, voc no pre-
cisar tratar RemoteExceptions. Ao utilizar o
Spring, esta exceo convertida para org.
springframework.remoting.RemoteAccessException,
uma exceo de runtime.
O cdigo a seguir ilustra como declarar
um EJB local no Spring:
<bean id=ejbPapelService
class=org.springframework.ejb.access.
LocalStatelessSessionProxyFactoryBean
lazy-init=true>
<areaerta+me'|aa|N+me'.+|ae'|+ae|:er.|ce|ec+|'/>
<property name=businessInterface
value=br.com.jm.spring.remoting.papel.service.
PapelService />
</bean>
No exemplo completo criado adiante,
voc ver como declarar um EJB remoto
utilizando a nova sintaxe presente na
verso 2.0 do Spring, que tem o mesmo
efeito, mas muito mais simples.
Outros mecanismos de acesso
O Spring tambm permite declarar web
services em sua configurao. Obtemos
as mesmas vantagens presentes no uso
com EJBs: acesso via interface de negcio,
abstrao de complexidades e converso
de excees checadas para excees de
runtime. possvel utilizar o mecanismo
padro para localizao do cliente reco-
mendado pela especificao Java EE (ou
seja, o cliente fica disponvel para obten-
o a partir da rvore JNDI) ou ento
configurar o proxy de modo que tudo o
necessrio para a criao e execuo do
cliente seja configurado pelo Spring. Alm
de consumi-los, o Spring permite dispo-
nibilizar os objetos que ele gerencia como
web services de forma tambm simples.
So suportados ainda os protocolos para
acesso remoto Hessian e Burlap, desenvol-
vidos pela Caucho (criadora do container
web Resin). A exportao e o consumo dos
servios utilizando um desses dois proto-
colos seguem o mesmo padro; assim, ser
simples para voc conseguir utiliz-los
caso necessrio.
Finalmente, o Spring em suas verses
mais recentes, suporta a exportao e o
acesso a servios remotamente via JMS.
Esse mecanismo nasceu com o framework
LINGO e agora suportado pelo Spring.
Um exemplo avanado
Veremos agora um exemplo mais avan-
ado. Criaremos uma aplicao cliente que
ir emular um home broker (uma aplicao
que permite acompanhar e negociar aes
e outros papis na bolsa de valores). A apli-
cao ter foco nas operaes de compra e
venda e ir se comunicar com o servidor
utilizando as facilidades do Spring Remo-
ting. Ser possvel obter a lista de aes e
emitir as ordens de compra atravs de um
EJB remoto ou de uma chamada HTTP,
utilizando as facilidades para exposio e
invocao de servios via HTTP.
Instalando o exemplo
Os projetos de exemplo esto disponveis
para download no site da Java Magazine.
Utilizaremos o Eclipse com WTP (Web Tools
Platform Project) e o servidor de aplicaes
JBoss. No Eclipse importe os projetos usan-
do File|Import>General>Existing Projects Into
Workspace. So cinco projetos; a estrutura
criada dever ser similar da Figura 3.
Podem ocorrer problemas com a verso do
cdigo-fonte utilizada no projeto, se mais de uma
verso do Java SE estiver configurada no Eclipse.
Para corrigir esse problema, clique com o boto di-
reito sobre o n do projeto,escolha Properties>Java
Compiler e mude Compiler compliance level para
5.0. Pode haver problemas tambm se o Facet
1
instalado para a verso do Java no for o da verso
5. Neste caso, clique com o boto direito sobre o
projeto e escolha Properties>Project Facet e clique
em Add/Remove Project Facets.
Entendendo o exemplo
A parte do exemplo executada no servi-
dor composta por um EAR, representa-
do pelo projeto HBEAR (lembrando que
HB vem de home broker). Associados
a este EAR, ficam trs projetos: um de
EJBs (HBEJB), seu projeto cliente (HBE-
JBClient) e um projeto web (HBWAR). O
cliente ser Java EE e representado pelo
projeto HBCLIENT.
Entre os projetos da parte executada no
1 Os Facets so extenses do ncleo comum do WTP
que do suporte especco a alguma especicao ou API,
ex.: Java SE 5 ou Servlet 2.5. A escolha dos Facets faz o WTP
adaptar vrios comportamentos, por exemplo, validando
arquivos de congurao com o XSD/DTD da verso exata
pedida por um release especco da API utilizada.
Figura 3. Estrutura do projeto.
Rev_Java53_cromo.pdf 57 Rev_Java53_cromo.pdf 57 20/12/2007 16:40:19 20/12/2007 16:40:19
58 Java Magazine Edio 53
Spring Remoting
Listagem 6. Classe PapelServiceImpl, responsvel por implementar os mtodos de negcio, no nosso caso, hard-coded.
package br.com.jm.spring.remoting.papel.service;
import java.util.ArrayList;
import java.util.List;
import br.com.jm.spring.remoting.papel.Papel;
public class PapelServiceImpl implements PapelService {
public boolean emitirOrdem(String papel, Number valor) {
System.out.println(Recebeu chamada para emitir ordem. Papel:
+ papel + no valor: + valor);
return true;
}
public List listarPapeis() {
List<Papel> papeis = new ArrayList<Papel>();
papeis.add(new Papel(PETR4, 0,50%, 50,25, 50,00));
papeis.add(new Papel(VALE5, -0,50%, 73,13, 75,00));
papeis.add(new Papel(TNLP4, 2,50%, 38,95, 38,00));

return papeis;
}
}
Listagem 7. Classe PapelServiceEJB, EJB que ser exposto de forma remota.
package br.com.jm.spring.remoting.papel.service.ejb;
//imports...
/**
* <!-- begin-xdoclet-definition -->
* @ejb.bean name=PapelService description=An EJB named PapelService
* display-name=PapelService jndi-name=PapelService
* type=Stateless transaction-type=Container
* <!-- end-xdoclet-definition -->
* @generated
*/
public abstract class PapelServiceEJB implements javax.ejb.SessionBean, PapelService
{
private SessionContext sessionContext;
private PapelService papelService;
/**
* <!-- begin-xdoclet-definition -->
* @ejb.create-method view-type=remote
* <!-- end-xdoclet-definition -->
* @generated
*/
public void ejbCreate() {
ApplicationContext context = new ClassPathXmlApplicationContext(
br/com/jm/spring/remoting/papel/service/ejb/applicationContext.xml);
papelService = (PapelService)context.getBean(papelService);
}
/**
* <!-- begin-xdoclet-definition -->
* @ejb.interface-method view-type=remote
* <!-- end-xdoclet-definition -->
* @generated
*/
public List listarPapeis() {
return papelService.listarPapeis();
}
/**
* <!-- begin-xdoclet-definition -->
* @ejb.interface-method view-type=remote
* <!-- end-xdoclet-definition -->
* @generated
*/
public boolean emitirOrdem(String papel, Number valor) {
return papelService.emitirOrdem(papel, valor);
}
//outros mtodos...
}
servidor, o projeto HBEJBClient quem
concentra os objetos de domnio. Assim
os outros projetos tero acesso mais facil-
mente a esses objetos, estabelecendo uma
dependncia com o projeto HBEJBClient.
Entre as classes e pacotes que compem
este projeto, merecem destaque:
%br.com.jm.spring.remoting.papel: Pacote que
armazena a classe Papel, que representa
uma ao dentro do sistema (estamos
usando o termo mais genrico papel para
evitar confuso com aes de frameworks).
A Listagem 5 apresenta essa classe.
%br.com.jm.spring.remoting.papel.service: Pa-
cote que armazena a interface e a classe
de servio (PapelService e PapelServiceImpl,
respectivamente). A Listagem 6 apresenta
a classe PapelServiceImpl.
%br.com.jm.spring.remoting.papel.service.ejb:
Pacote presente nos dois projetos da ca-
mada EJB. No projeto da camada cliente
contm as classes e interfaces necessrias
aos clientes para acesso aos EJBs.
O projeto HBEJB armazena as classes que
compem a parte servidora do mdulo EJB
da aplicao. Esse projeto contm apenas
um pacote, o br.com.jm.spring.remoting.papel.
service.ejb, onde est a classe de imple-
mentao do EJB. Esta classe anotada
via XDoclet, o que permite gerar todas as
outras classes desse pacote e do projeto
HBEJBClient.
AListagem 7 apresenta a classe. Repare
que a classe PapelServiceEJB obtm uma re-
ferncia para uma instncia de PapelService
e delega as requisies que recebe para
esse objeto. A instncia de PapelService
obtida a partir do Spring, que por sua
vez configurado por um XML presen-
te neste mesmo pacote, apresentado na
Listagem 8.
J o projeto HBWAR armazena apenas a
definio do arquivo de configurao. Como
esse projeto s expe um servio para ser
invocado via HTTP e os objetos que sero
disponibilizados como servios esto pre-
sentes no projeto HBEJBClient, referenciado
por este projeto, no necessrio incluir ne-
nhuma classe. preciso apenas configurar o
servlet do Spring no web.xml (veja a Listagem
9) e criar um arquivo de configurao cujo
nome segue o padro nomeDoServletNoWeb.
xml-servlet.xml, conforme o que est apre-
Rev_Java53_cromo.pdf 58 Rev_Java53_cromo.pdf 58 20/12/2007 16:40:19 20/12/2007 16:40:19
Edio 53 Java Magazine 59
sentado na Listagem 10.
Analisando, por fim, o projeto HB-
CLIENT, ele contm apenas o pacote br.com.
jm.spring.remoting.papel.client, com a classe
Main. Esta classe usa o Spring para iniciar a
aplicao cliente, solicitando a classe prin-
cipal. A classe MainPanel, que a principal
da camada cliente, representa a janela da
aplicao em execuo. A Listagem 11
apresenta a classe Main e a Listagem 12, a
classe MainPanel.
A classe Main recorre ao uso do Spring,
que configurado via um arquivo XML
presente na raiz do projeto, denominado
applicationContext.xml e disponvel para
anlise na Listagem 13. Esse XML uma
das partes mais importantes de nosso
artigo e o analisaremos detalhadamente
nas prximas sees.
Executando o exemplo
Para executar o exemplo, basta realizar
deploy das aplicaes e iniciar o JBoss a
partir do Eclipse. Aps isso, executamos
a classe Main do projeto HBCLIENT. A
aplicao dever abrir a janela principal,
similar apresentada na Figura 4.
A aplicao obtm a lista de papis a
partir de um objeto que implementa a
interface PapelService. Injetamos esse objeto
atravs do Spring para que a aplicao no
tenha que obt-lo. Na primeira execuo,
esse objeto um EJB remoto, como pode
ser visto na Listagem 13. O bean mainPanel
recebe a referncia para o bean que imple-
menta a interface PapelService no construtor.
No nosso caso, essa referncia o bean
ejbPapelService.
Acessando um EJB remoto
Recorrendo novamente Listagem 13,
vemos o seguinte trecho de cdigo XML:
<jee:remote-slsb id=ejbPapelService
business-interface=br.com.jm.spring.remoting.papel.service.
PapelService
jndi-name=PapelService />
Isso declara que o Spring deve criar um
proxy para o EJB remoto, disponibilizado
via JNDI no endereo PapelService (atri-
buto jndi-name). Atravs do atributo business-
interface, indicamos qual interface o proxy
deve implementar. O objeto retornado pelo
Spring ser sempre manipulado a partir
Listagem 8. Configurao do Spring utilizada no EJB.
<?xml version=1.0 encoding=UTF-8?>
<beans ...>
<bean id=papelService
class=br.com.jm.spring.remoting.papel.service.PapelServiceImpl>
</bean>
</beans>
Listagem 9. Configurao do servlet para exportao do servio para acesso via HTTP.
<?xml version=1.0 encoding=UTF-8?>
<web-app ...>
<display-name>HBWAR</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.service</url-pattern>
</servlet-mapping>
</web-app>
Listagem 10. Configurao do Spring para exportao do servio para acesso via HTTP.
<?xml version=1.0 encoding=UTF-8?>
<beans ...>
<bean id=papelService
class=br.com.jm.spring.remoting.papel.service.PapelServiceImpl>
</bean>
<bean name=/httpPapelService.service
class=org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter>
<property name=service ref=papelService />
<property name=serviceInterface
value=br.com.jm.spring.remoting.papel.service.PapelService />
</bean>
</beans>
Listagem 11. Classe Main do projeto.
package br.com.jm.spring.remoting.papel.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
applicationContext.xml);
MainPanel panel = (MainPanel) context.getBean(mainPanel);
panel.init();
}
}
dessa interface, sem a necessidade de se
saber que um EJB.
Essa abordagem do Spring isola o clien-
te das complexidades do EJB e permite
remover duas camadas da aplicao, ge-
ralmente implementadas seguindo os
patterns Service Locator e Business Dele-
gate. A primeira pode ser removida, pois
no mais necessrio localizar servios
programaticamente. E o Business Delegate
deixa de ser necessrio, pois no existem
mais peculiaridades geradas pelo fato de
estarmos trabalhando com EJBs.
Exportando um servio para acesso via HTTP
A exportao de um servio via HTTP
muito similar exportao via RMI.
Veja na Listagem 10, j mostrada, como
Rev_Java53_cromo.pdf 59 Rev_Java53_cromo.pdf 59 20/12/2007 16:40:19 20/12/2007 16:40:19
60 Java Magazine Edio 53
Spring Remoting
exportamos um servio atravs de HTTP.
L vemos que um Exporter utilizado para
exportar o servio atribudo sua proprie-
dade service. A URL do servio passa a ser
seu nome, indicando no atributo name, com
o sufixo .service. No exemplo, a URL do
servio ser /httpPapelService.service.
Consumindo um servio via HTTP
Voltando Listagem 13 e analisan-
do o cdigo para consumo do bean
httpPapelService, vemos com configurado o
consumo do servio HTTP. H, inclusive, a
indicao de uma interface de negcio que
ser implementada pelo proxy.
Benefcios obtidos
Vimos como simples acessar servios
remotos utilizando os utilitrios do Spring.
Revisitaremos agora, com mais detalhes,
alguns dos benefcios j comentados e
como eles se aplicam ao nosso exemplo.
Converso de excees
Devido ao fato do Spring converter as
excees que indicam problemas na comu-
nicao remota em excees de runtime,
no temos que encher nosso cdigo com
blocos try/catch. Alm disso, por serem exce-
es de runtime, a interface de negcio no
precisa indicar o lanamento de excees
de infra-estrutura.
Transparncia no acesso remoto
O Spring nos permite acessar servios
atravs da interface de negcio. Isso torna
totalmente transparente o fato de o servio
ser remoto, permitindo a substituio da
tecnologia empregada por outra, facilmen-
te. Possibilita tambm a substituio do
servio remoto por um local, sem alterao
no cdigo do cliente.
O exemplo, da forma que foi apresen-
tado, depende do EJB remoto para obter
os dados e solicitar a abertura das ordens
de compra e venda. Isso ocorre porque
injetamos o bean ejbPapelService no bean
mainPanel. Mas como utilizamos o servio
via interface, podemos injetar qualquer
outro objeto que implemente a interface
de negcio; ou seja, podemos facilmente
injetar o objeto que consome o servio via
HTTP, por exemplo.
Vejamos isso na prtica. Ao execu-
Listagem 12. Classe principal do projeto, responsvel por apresentar a tela e invocar os mtodos remotos no servidor.
package br.com.jm.spring.remoting.papel.client;
//imports...
public class MainPanel extends JFrame implements Observer {
//propriedades
private PapelService papelService;
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
boolean sucesso = papelService.emitirOrdem(
txtSimbolo.getText(), nf.parse(txtPreco.getText()));
DefaultListModel model = ((DefaultListModel) list.getModel());
String msg = txtSimbolo.getText() + + txtPreco.getText()
s + sdf.format(new Date());
if (sucesso) {
model.addElement([SUCESSO] + msg);
} else {
model.addElement([ERRO] + msg);
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex.getMessage(), Erro,
JOptionPane.ERROR_MESSAGE);
}
}
};
public MainPanel(PapelService papelService) {
this.papelService = papelService;
System.out.println(Proxy: + papelService);
}
public void init() {
initTable();
initPanel();
initWindow();
}
public void update(Observable observable, Object o) {
//...
}
public void initWindow() {
//...
}
public void initPanel() {
//...
}
public void initTable() {
this.table = new JTable(getTableData(), nomesColunas);
//...
}
public Object[][] getTableData() {
List<Papel> papeis = papelService.listarPapeis();
Object[][] linhas = new Object[papeis.size()][4];
for (int i = 0; i < papeis.size(); i++) {
Papel papel = papeis.get(i);
linhas[i][0] = papel.getSimbolo();
linhas[i][1] = papel.getVariacao();
linhas[i][2] = papel.getVlAtual();
linhas[i][3] = papel.getFechAnterior();
}
return linhas;
}
}
class SelectionListener extends Observable implements ListSelectionListener {
SelectionListener(Observer observer) {
addObserver(observer);
}
public void valueChanged(ListSelectionEvent e) {
DefaultListSelectionModel model = (DefaultListSelectionModel) e.getSource();
setChanged();
notifyObservers(model.getLeadSelectionIndex());
}
}
Rev_Java53_cromo.pdf 60 Rev_Java53_cromo.pdf 60 20/12/2007 16:40:19 20/12/2007 16:40:19
Edio 53 Java Magazine 61
t ar a apl i cao, a st r i ng Proxy:
PapelService:Stateless impressa no
console. Isso indica que o servio est
sendo acessado via um proxy para um
EJB stateless. Se mudarmos o componente
que injetado no XML de configurao,
teremos, claro, outro objeto impresso no
console. Para mudar para o objeto que con-
some o servio via HTTP, alteramos o XML
de configurao do projeto HBCLIENT.
O trecho da declarao do bean mainPanel
deve ficar assim:
<bean id=mainPanel
class=br.com.jm.spring.remoting.papel.client.MainPanel
lazy-init=true>
<constructor-arg ref=httpPapelService />
</bean>
Nenhuma outra alterao necessria.
Ao executar a aplicao, o comporta-
mento ser o mesmo, mudando apenas
a mensagem impressa no console para a
apresentada a seguir:
Proxy: HTTP invoker proxy for service URL
[http://localhost:8080/hb/httpPapelService.service]
A nova mensagem indica que estamos
trabalhando agora com um proxy para um
HTTP Invoker. Este um componente do
Spring que possibilita o acesso a servios
via HTTP, utilizando objetos serializados
atravs do mecanismo de serializao
padro do Java.
Vimos, portanto, como simples mudar
o mecanismo de acesso remoto quando
utilizamos o framework Spring.
Concluses
O suporte que o Spring prov para acesso a
servios remotos robusto e ao mesmo tem-
po simples. Usando o Spring para acessar
Listagem 13. Classe principal do projeto, responsvel por apresentar a tela e invocar os mtodos remotos no servidor.
<?xml version=1.0 encoding=UTF-8?>
<beans ...>
<bean id=httpPapelService
class=org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean>
<property name=serviceUrl
value=http://localhost:8080/hb/httpPapelService.service />
<property name=serviceInterface
value=br.com.jm.spring.remoting.papel.service.PapelService />
</bean>
<jee:remote-slsb id=ejbPapelService
business-interface=br.com.jm.spring.remoting.papel.service.PapelService
jndi-name=PapelService />
<bean id=mainPanel
class=br.com.jm.spring.remoting.papel.client.MainPanel
lazy-init=true>
<constructor-arg ref=ejbPapelService />
</bean>
</beans>
Figura 4. Tela do projeto em funcionamento.
Daniel Cicero Amadei
(daniel.amadei@gmail.com)
Bacharel em Sistemas de Informa-
o pela Universidade Presbiteriana
Mackenzie e ps-graduado em Gesto de
Projetos pela Fundao Vanzolini.Trabalha com Java desde
1999 e possui as certificaes SCJP, SCWCD, SCBCD e SCEA,
atuando como Arquiteto de Sistemas Java SE e Java EE.
servios remotos, tiramos do desenvolvedor
as complexidades envolvidas com esse tipo
de tarefa, aumentando a produtividade e
a qualidade do desenvolvimento. O uso
do Spring Remoting tambm permite eli-
minar algumas camadas de sua aplicao,
sendo delegadas ao Spring tarefas de infra-
estrutura como a localizao dos objetos e a
converso de excees.
Rev_Java53_cromo.pdf 61 Rev_Java53_cromo.pdf 61 20/12/2007 16:40:20 20/12/2007 16:40:20
62 Java Magazine Edio 53
Turbinando o acesso a dados em suas aplica
Informaes Rpidas com
O
ehcache uma soluo genrica
de cache de objetos, sendo muito
utilizado em ferramentas que pre-
cisam manter algum tipo de cache, como o
Hibernate e o Spring e muitas outras. Mas
o projeto tambm pode ser utilizado dire-
tamente por aplicaes com necessidades
de caching especficas. Por exemplo, uma
aplicao web poder agilizar a apresen-
tao de dados para os usurios atravs do
uso do ehcache.
Sobre o ehcache
O ehcache um projeto open source
distribudo sobre a Apache 2.0 License,
uma licena permissiva que possibilita
o uso do cdigo tanto em produtos open
source como proprietrios. O tamanho do
JAR principal do ehcache bem pequeno,
somente 100 kb.
A classe pri ncipal do ehcache a
CacheManager, que controla todos os caches.
Uma das formas para se criar o CacheManager
com seu mtodo esttico getInstance(). Este
mtodo retorna um objeto Cache, por meio
do qual ser possvel adicionar e obter
elementos (Element) para cada cache.
O ehcache suporta vrias polticas quan-
to limpeza dos objetos em memria.
Quando a quantidade de objetos passar
do limite estipulado para um cache, sero
removidos objetos para dar lugar a outros
inseridos, de acordo com a poltica confi-
gurada. As trs polticas de limpeza de
cache suportadas so:
%LRU (Last Recently Used) Uma data/
hora gravada quando um elemento
inserido no cache, e tambm toda vez que
acessado. Com essa configurao, o objeto
que estiver com a data mais antiga ser re-
movido do cache (esta a opo default).
%LFU (Least Frequently Used) A quan-
tidade de vezes que um objeto acessado
do cache fica gravada. Com essa confi-
gurao, ser removido o objeto que foi
menos utilizado (ou seja, usado com menor
freqncia).
%FIFO (First In First Out) Essa opo
segue a clssica estrutura de dados de fila:
o primeiro que entra o primeiro que sai.
Entendendo o ehcache.xml
O ehcache configurado declarativamen-
te no arquivo ehcache.xml. Uma configura-
o mnima est detalhada na Listagem 1.
O elemento <defaultCache/> obrigatrio,
pois utilizado quando criamos um cache
programaticamente. Na lista de dados b-
sicos para que um cache seja configurado
(elemento <cache/>), devero constar:
%name Identificao nica para o cache
(no ehcache.xml podem ser definidos vrios
caches atravs de elementos <cache/>);
%maxElementsInMemory Quantidade mxi-
ma de elementos que sero armazenados
na memria.
%maxElementsOnDisk Quantidade mxima
Rev_Java53_cromo.pdf 62 Rev_Java53_cromo.pdf 62 20/12/2007 16:40:20 20/12/2007 16:40:20
Edio 53 Java Magazine 63
es web
ehcache
Com o ehcache, voc pode
melhorar a performance do seus
sites dinmicos, fazendo com que
os dados sejam armazenados em
cache e recuperados de forma
rpida tudo atravs de uma API
poderosa e simples de usar
ANDR DE SANTI OLIVEIRA
de elementos a serem armazenados no disco
(se for atribudo o valor zero, no haver
limite alm do espao livre no HD);
%eternal Sendo true, os objetos armazena-
dos no cache no expiraro; sendo false, iro
expirar de acordo com os valores dos atri-
butos timeToIdleSeconds e timeToLiveSeconds;
%overflowToDisk Se for atribudo true,
quando o nmero mximo de objetos em
memria chegar ao seu limite, o ehcache
comear a armazenar os prximos objetos
no disco.
Vrios caches podem ser configurados
sem que uma configurao interfira na
outra.
Exemplo prtico
A verso 1.4 do ehcache, no momento em
que escrevo, ainda est em beta. Assim,
usaremos neste artigo a verso estvel
1.3. Como exemplo, montaremos um site
que busca informaes de fornecedores de
duas categorias (A e B).
Para comparao, primeiro o site ser
criado sem a utilizao da biblioteca;
depois, incluiremos o ehcache. Voc ver
como isso envolve poucas alteraes. O
exemplo tambm mostra que o ehcache
pode envenenar sistemas legados sem
grandes dificuldades.
Criando o projeto
No seu IDE favorito, crie um projeto web
(utilizaremos somente servlets e JSP com
tags JSTL). A aplicao (veja a configurao
na Listagem 2) iniciar pela pgina index.
jsp (Listagem3) e ter dois links, um para
cada categoria de fornecedores. Estes links
direcionam para o servlet FornecedorControl
(Listagem 4), passando a categoria como
parmetro. O servlet, atuando como
controlador, chamar a classe Fornecedor
(Listagem 5), que contm as regras de
negcio. Esta classe, por sua vez, buscar
Listagem1. ehcache.xml: exemplo de configurao simples
<ehcache xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:noNamespaceSchemaLocation=ehcache.xsd>
<defaultCache
maxElementsInMemory=1000
maxElementsOnDisk=0
eternal=true
overflowToDisk=false />
<cache
name=nomedocache
maxElementsInMemory=100
maxElementsOnDisk=100
eternal=true
overflowToDisk=false />
</ehcache>
Listagem2. Parte principal do mapeamento no web.xml
...
<servlet>
<servlet-name>fornecedores</servlet-name>
<servlet-class>br.com.jm.controller.FornecedorControl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>fornecedores</servlet-name>
<url-pattern>*.jm</url-pattern>
</servlet-mapping>
...
Listagem3. Index.jsp, mostrando apenas o <body/>
<body>
<h1>Fornecedores</h1><p>
<a href=fornecedores.jm?categoria=A>Fornecedores Categoria A</a><p>
<a href=fornecedores.jm?categoria=B>Fornecedores Categoria B</a>
</body>
Listagem4. FornecedorControl.java: Servlet para busca de fornecedores
package br.com.jm.controller;
//... imports
public class FornecedorControl extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws Exception
{
String categoria = request.getParameter(categoria);
Fornecedor fornecedor = new Fornecedor();
List<Fornecedor> fornecedores = fornecedor.listarTodos(categoria);
request.setAttribute(fornecedores, fornecedores);
request.getRequestDispatcher(lista_fornecedores.jsp).forward(request, response);
}
}
Rev_Java53_cromo.pdf 63 Rev_Java53_cromo.pdf 63 20/12/2007 16:40:20 20/12/2007 16:40:20
64 Java Magazine Edio 53
Informaes Rpidas com ehcache
os dados no FornecedorDAO (Listagem6). Ao
final, a lista de fornecedores solicitada
ser exibida em uma tabela HTML simples
(Listagem7).
No FornecedorDAO, preenchemos os dados
de forma simulada (mock), ao invs de con-
sultar um banco de dados. (Por isso, toda
vez que for citado banco de dados, o texto
estar se referindo a esse trecho de cdigo.)
Assim evitamos sair do foco do artigo e
simplificamos o cdigo; tambm enfatiza-
mos a utilizao posterior do ehcache.
Com isso, temos uma primeira verso
da aplicao funcionando. Mas toda vez
que um link for clicado para mostrar uma
lista de fornecedores, as informaes sero
trazidas novamente do banco de dados.
Identificamos, portanto, a oportunidade
de fazer o caching dessas informaes.
Bibliotecas e coniguraes
Primeiro preciso baixar e adicionar no
Listagem5. Fornecedor.java
package br.com.jm.model;
//... imports
public class Fornecedor {
private String nome;
private String comentario;
public List<Fornecedor> listarTodos(String categoria) {
FornecedorDAO fornecedorDAO = new FornecedorDAO();
if (categoria.equals(A)) {
return fornecedorDAO.listarTodosCategoriaA();
} else {
return fornecedorDAO.listarTodosCategoriaB();
}
}
//... construtor, setters e getters
}
Listagem6. FornecedorDAO.java: simulando a busca de informaes no banco de dados
package br.com.jm.dao;
//... imports
public class FornecedorDAO {
public List<Fornecedor> listarTodosCategoriaA() {
List<Fornecedor> fornecedores = new ArrayList<Fornecedor>();
for (int i = 1; i <= 100; i++) {
String nome = Nome Fornecedor_ + i;
String comentario = Fornecedor_ + i + (Categoria A);
Fornecedor fornecedor = new Fornecedor(nome, comentario);
fornecedores.add(fornecedor);
}
return fornecedores;
}
public List<Fornecedor> listarTodosCategoriaB() {
List<Fornecedor> fornecedores = new ArrayList<Fornecedor>();
for (int i = 1; i <= 50; i++) {
String nome = Nome Fornecedor_ + i;
String comentario = Fornecedor_ + i + (Categoria B);
Fornecedor fornecedor = new Fornecedor(nome, comentario);
fornecedores.add(fornecedor);
}
return fornecedores;
}
}
Listagem7. Lista_fornecedores.jsp (mostrando apenas o <body/>)
<body>
<h1>Lista de Fornecedores</h1><p>
<table>
<tr>
<th width=200>NOME</th>
<th width=200>COMENTRIO</th>
</tr>
<c:forEach var=fornecedor items=${fornecedores}>
<tr>
<td>${fornecedor.nome}</td>
<td>${fornecedor.comentario}</td>
</tr>
</c:forEach>
<tr align=center>
<td colspan=2>
<input type=button value=Voltar
onclick=javascript:history.go(-1)>
</td>
</tr>
</table>
</body>
Figura 1. Estrutura do projeto de exemplo
Rev_Java53_cromo.pdf 64 Rev_Java53_cromo.pdf 64 20/12/2007 16:40:20 20/12/2007 16:40:20
Edio 53 Java Magazine 65
Listagem8. ehcache.xml: Configurao para o exemplo
<ehcache xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:noNamespaceSchemaLocation=ehcache.xsd>
<defaultCache
maxElementsInMemory=1000
maxElementsOnDisk=0
eternal=true
overflowToDisk=false />
<cache
name=fornecedores
maxElementsInMemory=10
maxElementsOnDisk=0
eternal=false
overflowToDisk=false
timeToIdleSeconds=3600
timeToLiveSeconds=3600 />
</ehcache>
projeto alguns JARs: ehcache-1.3.0.jar, backport-
util-concurrent.jar, e commons-logging-1.1.jar
(veja links). Feito isso, o arquivo ehcache.xml
(Listagem8) deve ser criado na pasta src (a
raiz do classpath da aplicao). Dessa forma,
o ehcache poder localizar a configurao
como resource, sem que seja preciso informar
seu caminho via cdigo. Ao final, o projeto
dever estar igual ao da Figura 1.
No ehcache.xml, observe que o maxElements
InMemory est com o valor 10, o que significa
que armazenar at dez objetos em mem-
ria. O cache tambm configurado para
que expire depois de uma hora. Passado
este tempo, quando a prxima requisio
for executada, as informaes sero busca-
das novamente do banco de dados e arma-
zenadas no cache. Se durante esse processo,
for inserido um novo fornecedor, o sistema
dever fazer a atualizao do cache.
Para o exemplo demonstrado aqui, o ar-
quivo configurado com o cache default e
mais um cache, chamado de fornecedores.
Uso do cache no cdigo Java
No cdigo Java, somente a classe
FornecedorDAO ser alterada, para que o site
busque os dados do cache da segunda
chamada ao mtodo em diante. Veja a
Listagem 9. O cache fornecedores obtido
atravs do comando getCache(). Buscamos
ento um objeto (Element), atravs de uma
chave nica, e verificamos se o objeto
nulo. Se for nulo, isso significa que o ob-
jeto ainda no foi inserido no cache. Neste
caso, o sistema busca as informaes do
Rev_Java53_cromo.pdf 65 Rev_Java53_cromo.pdf 65 20/12/2007 16:40:20 20/12/2007 16:40:20
66 Java Magazine Edio 53
Informaes Rpidas com ehcache
Listagem 9. FornecedorDAO.java: agora usando ehcache
package br.com.jm.dao;
//imports...
public class FornecedorDAO {
private Logger logger = Logger.getLogger(FornecedorDAO.class);
private CacheManager cacheManager = CacheManager.getInstance();
public List<Fornecedor> listarTodosCategoriaA() {
List<Fornecedor> fornecedores = new ArrayList<Fornecedor>();
Cache cache = cacheManager.getCache(fornecedores);
Element element = cache.get(categoriaA);
if (element == null) {
logger.info(Buscou do banco de dados!);
for (int i = 1; i <= 100; i++) {
String nome = Nome Forncedor_ + i;
String comentario = Forncedor_ + i + (Categoria A);
Fornecedor fornecedor = new Fornecedor(nome, comentario);
fornecedores.add(fornecedor);
}
element = new Element(categoriaA, fornecedores);
cache.put(element);
} else {
logger.info(Buscou do cache!);
fornecedores = (List<Fornecedor>) element.getObjectValue();
}
return fornecedores;
}
public List<Fornecedor> listarTodosCategoriaB() {
List<Fornecedor> fornecedores = new ArrayList<Fornecedor>();
Cache cache = cacheManager.getCache(fornecedores);
Element element = cache.get(categoriaB);
if (element == null) {
logger.info(Buscou do banco de dados!);
for (int i = 1; i <= 50; i++) {
String nome = Nome Fornecedor_ + i;
String comentario = Fornecedor_ + i + (Categoria B);
Fornecedor fornecedor = new Fornecedor(nome, comentario);
fornecedores.add(fornecedor);
}
element = new Element(categoriaB, fornecedores);
cache.put(element);
} else {
logger.info(Buscou do cache!);
fornecedores = (List<Fornecedor>) element.getObjectValue();
}
return fornecedores;
}
}
ehcache.sf.net
Pgina do ehcache, com documentao extensa.
backport-jsr166.sf.net
Pgina da API Backport Concurrent, utilizada pelo
ehcache para sua parte de concorrncia.
commons.apache.org/logging
Pgina do Apache Commons Logging, biblioteca
utilizada pelo ehcache.
logging.apache.org/log4j
Pgina do log4j, API de logging muito completa que
usamos no cdigo deste artigo.
Andr de Santi Oliveira
(asobrasil@gmail.com)
trabalha com desenvolvimento de
software h nove anos. ps-graduado em Engenharia
de Sistemas e viciado em livros e blogs tcnicos.
banco de dados como antes, mas tambm
armazena essas informaes no cache,
encapsulando-as num Element e executando
um put(). Repare que as duas listas, com os
dados dos fornecedores em ambas as cate-
gorias, esto no mesmo cache. A diferena
entre as duas a chave, definida ao inserir
a List no cache.
A biblioteca log4j foi adicionada e
configurada para que seja mostrado no
console se as informaes retornaram do
banco de dados ou se eles vm do cache.
Ao executar o cdigo vrias vezes, ser
possvel observar que somente na primeira
as informaes sero buscadas do banco
de dados nas demais vezes, elas viro
todas do cache.
Em um projeto real, o cdigo da Lis-
tagem 9 ficaria melhor se passasse por
uma refatorao, separando a verificao
das informaes no cache da busca das
informaes no banco de dados. O cache
poderia tambm ser colocado em outra
camada, que no a do DAO. Lembre-se
que quanto mais prximo sua camada
da view estiver o cache, mais rpido suas
informaes retornaro e menos proces-
samento ser realizado.
No aconselhvel colocar no cache to-
das as informaes de sua aplicao (listas,
objetos simples). Um melhor aproveita-
mento do ehcache ser obtido se forem
gravadas informaes que no mudam
constantemente e cujo custo de consulta
ou produo alto.
Outra dica ao usar tcnicas de caching:
fique atento memria do servidor e
faa uma anlise para identificar melhor
o que colocar no cache e a quantidade
de informaes a ser mantida em cache
no servidor. O ehcache permite que
sejam obtidas estatsticas de cada cache
indicando, por exemplo, quantas vezes
os objetos foram usados da memria,
quantas vezes os obj etos no foram
encontrados porque expiraram, dentre
outras opes. Com isso, possvel fazer
uma otimizao do cache para que o
consumo de memria do servidor seja o
mnimo necessrio.
Concluses
A utilizao do ehcache simples, tanto
em sistemas que esto sendo desenvolvidos,
como em sistemas legados, resultando em
pouco impacto para ser adotado. O ehcache
possui ainda vrios recursos como liste-
ners, JMX, replicao, entre outros que no
cobri aqui. A documentao do ehcache
bem completa e vale a consulta.
Rev_Java53_cromo.pdf 66 Rev_Java53_cromo.pdf 66 20/12/2007 16:40:20 20/12/2007 16:40:20
Isso que parceria: a LocaWeb entra com
a segurana, o monitoramento e a estabilidade
e voc gerencia a revenda como achar melhor.
MAIS DE 2.000
REVENDAS
HOSPEDADAS.
Servidor Expresso
BO GB
I GB RAM
GOO GB de transferenca
ou 4 Mbps de banda
Revenda Windows I
Cspaco em dsco. 4OO MB
Transferenca mensa|. IO GB
Base M5OL. 5
Base 5OL 5erver. E
Dominos e e-ma|s |mtados
Servidor Virtual I
EO GB
E5G MB RAM
3OO GB de transferenca
ou 2 Mbps de banda
| .|
..
A partir de
Ms
| '|
..
A partir de
Ms
| '||
..
A partir de
Ms
| ||
..
A partir de
Ms
Revenda Linux I
Cspaco em dsco. 4OO MB
Transferenca mensa|. IO GB
Base M5OL. 5
Dominos e e-ma|s |mtados
www.locaweb.com.br info@locaweb.com.br
A MAIOR E MELHOR EMPRESA DE HOSPEDAGEM DA AMRICA LATINA.
ELEITA A MELHOR EMPRESA DE SERVIOS DE INTERNET PELA INFO 200.
Rev_Java53_cromo.pdf 67 Rev_Java53_cromo.pdf 67 20/12/2007 16:40:21 20/12/2007 16:40:21
Rev_Java53_cromo.pdf 68 Rev_Java53_cromo.pdf 68 20/12/2007 16:40:22 20/12/2007 16:40:22

Potrebbero piacerti anche