Professional Documents
Culture Documents
Curso J150
Curso J150
J2EE Java 2 platform Enterprise Edition
EJB
IDHP Instituto de Desenvolvimento Humano e Pesquisa LTDA.
Stio WEB: http://www.psique.org/cursos
24/04/04 01:42:30
jp@psique.org http://www.psique.org/cursos
Curso J150
Curso J150
Curso J150
J2EE Java 2 platform Enterprise Edition
EJB
Verso
Verso 1.0
Data
Autor
24/04/04 01:42:32
jp@psique.org http://www.psique.org/cursos
Alterao
Primeira Verso
Curso J150
Curso J150
ndice
Curso J150..........................................................................................1
J2EE Java 2 platform Enterprise Edition..............................1
EJB..........................................................................................1
Curso J150......................................................................................2
J2EE Java 2 platform Enterprise Edition..............................2
EJB..........................................................................................2
J2EE Viso Geral............................................................................14
Conceito........................................................................................14
J2EE Principais Tecnologias...................................................14
Objetivo de J2EE.......................................................................15
Mltiplas camadas................................................................16
Os componentes J2EE...............................................................16
Clientes J2EE........................................................................17
Arquitetura de componentes JavaBeans...............................18
Comunicao com o Servidor...............................................18
Componentes Web....................................................................18
Componentes de Negcios.......................................................19
Enterprise Information System Tier.........................................20
Continers J2EE...........................................................................20
Servios do Continer...............................................................21
Servios do continer Montagem...........................................21
Servios J2EE...........................................................................21
Tipos de continer....................................................................22
Empacotamento........................................................................22
Mdulo J2EE.............................................................................23
Mdulos tipos.........................................................................23
Mdulos tipos.........................................................................23
Web Services............................................................................24
Web Services Transporte.......................................................24
Papis de desenvolvimento.......................................................24
J2EE Product Provider..........................................................24
J2EE Tool Provider................................................................25
J2EE Application Component Provider.................................25
Enterprise Bean Developer...................................................25
Web Component Developer...................................................25
J2EE Application Client Developer.......................................26
Application Assembler..........................................................26
24/04/04 01:42:34
jp@psique.org http://www.psique.org/cursos
Curso J150
Curso J150
Curso J150
Curso J150
Namespace...............................................................................42
Combinando Nomes e Servios de Diretrio...........................43
Aplicaes Java e Diretrios.....................................................43
O diretrio como um armazm de objetos................................43
JNDI Viso Geral....................................................................43
Benefcios de JNDI....................................................................43
Arquitetura...............................................................................44
Utilizao..................................................................................44
A API JNDI
..................................................................................................45
Context.....................................................................................45
Names.......................................................................................46
Composite.............................................................................47
Compound.............................................................................47
Bindings....................................................................................47
Reference..............................................................................48
A classe javax.naming.InitialContext........................................48
Ambiente - ENC........................................................................51
Criao de uma cpia do beans................................................53
Exceptions................................................................................54
Pacote: javax.naming.directory................................................54
O contexto do diretrio.............................................................54
Buscas.......................................................................................55
Laboratrio 20_01.....................................................................55
Laboratrio 20_02.....................................................................55
Laboratrio 20_03.....................................................................56
ANT Noes bsicas de utilizao.................................................57
ANT O que ...........................................................................57
ANT Projeto Apache...............................................................57
ANT Documentao................................................................57
ANT Execuo........................................................................57
ANT Execuo de tarefa.........................................................58
ANT - Instalao Ambiente
..................................................................................................58
ANT Laboratrio 22_01
..................................................................................................58
Laboratrio 22_02.....................................................................59
Tag <project>..............................................................................60
Tag <target> alvos.......................................................................60
Tarefas......................................................................................61
24/04/04 01:42:38
jp@psique.org http://www.psique.org/cursos
Curso J150
Curso J150
Propriedades................................................................................61
Laboratrio 22_03.....................................................................62
Propriedades externas..............................................................62
Laboratrio 22_04.....................................................................63
Propriedades no so redefinidas.........................................63
Laboratrio 22_05.....................................................................63
Laboratrio 22_06.....................................................................64
Outras pr-definidas.................................................................65
Laboratrio 22_07.....................................................................65
Laboratrio 22_08.....................................................................65
Java RMI...........................................................................................67
Invocao Remota de Mtodos.....................................................67
Marshalling e Unmarshalling...................................................67
Convenes de passagem de parmetros.................................68
Instabilidades de rede..............................................................68
A interface remota....................................................................68
A implementao do objeto remoto..........................................70
Stubs e Skeletons.....................................................................72
Bootstrapping e registro RMI...................................................74
URLs de RMI................................................................................75
Procurando um objeto remoto (lookup)........................................76
RMIC O compilador RMI............................................................77
Serializao de Objetos e passagem de parmetros....................77
Passagem por Valor..................................................................78
Serializao de Objetos............................................................78
Como os objetos so serializados.............................................78
Regras para serializao..........................................................79
O que deve ser Transient?........................................................79
Usos de serializao de objetos................................................80
Simulao de passagem por referncia com RMI....................81
Exportando Objetos Remotos...................................................82
Laboratrio 24_01....................................................................83
RMI, Corba e EJB.............................................................................84
RMI ou CORBA.........................................................................84
RMI e EJB.................................................................................84
Objetos EJB...............................................................................87
Objetos Home...........................................................................88
EJB Enterprise Java Beans.............................................................89
Tipos de Enterprise Bean.............................................................89
Como escrever um bean...............................................................89
24/04/04 01:42:40
jp@psique.org http://www.psique.org/cursos
Curso J150
Curso J150
Curso J150
Curso J150
O servlet DetalhesDoLivroServlet.......................................143
O servlet adicionarNoCarrinhoServlet...............................146
A distribuio do aplicativo cliente........................................151
Entity Beans...................................................................................154
Armazenagem de dados..............................................................154
O que um Entity Bean?............................................................155
Qual a diferena de Entity Bean x Session Bean?...............156
A interface remote..................................................................157
A interface HOME...................................................................158
Mtodo create.....................................................................159
Mtodos finder....................................................................159
Mtodos Remove.................................................................161
A classe da chave primria.................................................161
Um entity bean....................................................................161
A interface javax.ejb.EntityBean.........................................162
Activation e Passivation......................................................164
Mtodos create Criando um entity...................................165
Encontrando um Entity...........................................................168
Removendo um Entity.............................................................168
Outros mtodos...................................................................170
A interface javax.ejb.EntityContext....................................171
Dois tipos de entity beans...................................................172
Entity Bean - BMP.........................................................................173
A interface remote..............................................................175
A interface Home................................................................176
A classe primary key...........................................................177
O entity bean..........................................................................178
Descritor de distribuio........................................................193
Aplicativo Cliente.......................................................................195
Entity Bean CMP...........................................................................199
Entity Beans CMP so subclasses...........................................200
Entity Beans CMP no tem campos declarados.....................200
Entity Beans CMP tem mtodos Get/Set Abstratos................200
Entity Beans tm um Schema abstrato de persistncia.........200
Entity Beans podem tem uma linguagem para queries.........201
Entity Beans podem ter mtodos ejbSelect()........................202
Diferenas entre CMP e BMP.....................................................203
A interface remote......................................................................203
A interface home.....................................................................204
A classe entity bean....................................................................205
24/04/04 01:42:44
jp@psique.org http://www.psique.org/cursos
Curso J150
Curso J150
O deployment descriptor........................................................209
Exemplo de aplicativo cliente.................................................211
Utilizando uma classe para a chave primria customizada....214
A linguagem de consulta EJB EJB-QL..........................................215
A sintaxe EJB -QL.......................................................................217
A clusula SELECT.................................................................217
A clusula FROM....................................................................219
A clusula WHERE.....................................................................221
Literal.....................................................................................223
Identificao varivel.............................................................223
Expresso de caminho............................................................223
Parmetros de entrada...........................................................223
Composio de expresso condicional...................................224
Operadores e precedncia de operador.................................224
Expresses between...............................................................225
Expresses in..........................................................................225
Expresses like.......................................................................225
Expresses de comparao null..............................................225
Expresses de comparao de coleo empty........................226
Expresses de membro de coleo.........................................226
Expresses funcionais............................................................226
EJB QL BNF............................................................................227
Servio de mensagem em Java.......................................................232
Por que usar MDB..................................................................232
Performance........................................................................232
Disponibilidade...................................................................232
Suporte para mltiplos transmissores e receptores...........233
Performance........................................................................233
Confiabilidade.....................................................................234
Suporte para mltiplos transmissores e receptores ..........234
Introduo ao envio de mensagem.........................................234
A API JMS................................................................................235
Os domnios de envio de mensagem API JMS.........................236
Publish/Subscribe (pub/sub)...................................................237
Point-to-Point (PTP)................................................................237
O objeto modelo JMS..............................................................238
ConnectionFactory..................................................................241
Destination..............................................................................242
Connections............................................................................243
Session....................................................................................244
24/04/04 01:42:46
jp@psique.org http://www.psique.org/cursos
Curso J150
Curso J150
MessageProducer...................................................................246
MessageConsumer..................................................................247
Message..................................................................................248
Como escrever um cliente JMS...............................................250
Exemplo de pub/sub................................................................256
JBoss Camadas de Invocao...............................................264
RMI IL.................................................................................264
OIL IL..................................................................................264
UIL IL..................................................................................265
UIL2 IL................................................................................265
JVM IL.................................................................................265
HTTP IL...............................................................................266
Configurao da IL.............................................................266
Beans Direcionados para Mensagem (MDB).................................267
O que um bean direcionado para mensagem .........................267
MDB no tem interfaces home ou remote..........................268
MDB tem um nico mtodo de negcio..................................268
MDB no tem nenhum valor de retorno.................................268
MDB no enviam exceptions de volta ao cliente....................268
MDBs so stateless.................................................................269
MDBs podem ser assinantes durveis ou no durveis..........269
A Application Programming Interface (API)...............................269
A interface javax.jms.MessageListener..................................270
A interface javax.ejb.MessageDrivenBean.............................270
A interface javax.ejb.MessageDrivenBean.............................270
Como acessar um message-driven bean.................................271
Como escrever um mensagem direcionada por bean ............272
A classe bean direcionado para mensagem............................272
O deployment descriptor............................................................277
Configurao do arquivo jboss.xml.........................................278
Empacotamento do MDB....................................................278
JCA Java Connector Architecture................................................280
Chamando Beans de outros Beans................................................284
Lookups JNDIs default............................................................284
Referncias EJB......................................................................285
Segurana......................................................................................289
Autenticao...............................................................................289
O que JAAS...........................................................................290
As principais classes de JAAS.............................................290
Subject e Principal..............................................................291
24/04/04 01:42:48
jp@psique.org http://www.psique.org/cursos
10
Curso J150
Curso J150
Autenticao de um Subject...............................................292
Autorizao.................................................................................296
Basic authentication. .........................................................297
Form-based authentication.................................................297
Digest authentication..........................................................298
Certificate authentication...................................................298
De forma programtica..........................................................298
De forma declarativa..............................................................298
Viso geral segurana declarativa.........................................298
Referncias de segurana.......................................................301
Identidade de Segurana........................................................303
Papis de segurana (Security roles).....................................304
Permisso para execuo de mtodos EJB.............................305
Segurana na WEB.................................................................309
Habilitando a Segurana Declarativa no JBoss......................311
Transaes.....................................................................................315
Definio de Transao..............................................................315
Atomicidade............................................................................315
Consistncia............................................................................315
Isolamento..............................................................................316
Durabilidade...........................................................................316
Locking pessimista e otimista.................................................317
Componentes de uma transao distribuda..........................318
O protocolo two-phase XA.......................................................319
Excees heursticas...............................................................319
Identificadores de transaes e ramificaes (branches)......320
Suporte a transaes de usurio............................................321
Controle explcito de transaes............................................321
Exemplo com JDBC:............................................................322
Exemplo com JTA:...............................................................322
Suporte a UserTransaction.................................................323
Mtodos de javax.transaction.UserTransaction:....................324
begin().................................................................................324
commit()..............................................................................324
getStatus()..........................................................................324
rollback().............................................................................324
setRollbackOnly()................................................................324
setTransactionTimeout(int).................................................324
Constantes..............................................................................325
STATUS_ACTIVE.................................................................325
24/04/04 01:42:49
jp@psique.org http://www.psique.org/cursos
11
Curso J150
Curso J150
STATUS_NO_TRANSACTION..............................................325
STATUS_MARKED_ROLLBACK...........................................325
STATUS_PREPARING.........................................................325
STATUS_PREPARED...........................................................325
STATUS_COMMITING........................................................325
STATUS_COMMITED..........................................................326
STATUS_ROLLING_BACK...................................................326
STATUS_ROLLEDBACK......................................................326
STATUS_UNKNOWN..........................................................326
Controle implcito de transaes............................................326
Required.............................................................................328
Supports..............................................................................328
RequiresNew.......................................................................328
NotSupported.....................................................................328
Mandatory...........................................................................328
Never..................................................................................329
Excees.................................................................................329
Session Synchronization.........................................................330
Anexo 1 Cluster no JBoss.............................................................332
O que um cluster?................................................................332
Caractersticas do Clustering JBoss.......................................332
Parties.................................................................................333
...............................................................................................333
Proxies espertos (Smart proxies)............................................334
Descoberta de ns 'Automgica'............................................335
Configurando o JBoss..............................................................335
HA-JNDI Servio de nomes e o JBoss clustering..............335
Configurao do HA-JNDI no JBoss........................................337
Anexo 2 Criando um session bean no WSAD da IBM...................339
Anexo 3 - Acesso a dados via DAO..................................................348
BusinessObject.......................................................................348
DataAccessObject...................................................................349
DataSource.............................................................................349
ValueObject ou TransferObject...............................................349
Estratgias..................................................................................350
Automatic DAO Code Generation Strategy.............................350
Factory for Data Objects Strategy..........................................350
Conseqncias............................................................................352
Possibilita Transparncia.......................................................352
Facilita Migrao....................................................................352
24/04/04 01:42:51
jp@psique.org http://www.psique.org/cursos
12
Curso J150
Curso J150
24/04/04 01:42:53
jp@psique.org http://www.psique.org/cursos
13
Curso J150
J2EE
Principais Tecnologias
24/04/04 01:42:55
jp@psique.org http://www.psique.org/cursos
14
Curso J150
Objetivo de J2EE
Principalmente:
Segurana
24/04/04 01:42:57
jp@psique.org http://www.psique.org/cursos
15
Curso J150
J2 EE
J2 EE
Aplicao 1 Aplicao 2
Aplicao
clie nte
Pg inas
dinm icas
JSP
EJB
EJB
ban co
ban co
Ca m a d a d o
clien t e
Ca m a d a d a
Web
Ca m a d a d e
Neg cio
Mq u in a d o
clien te
Con t in er WEB
Con t in er J2EE
EIS - Geren ciad or es d e
Ban co d e Dad os / ERP/ Legad o
Mltiplas camadas
Os componentes J2EE
24/04/04 01:42:59
jp@psique.org http://www.psique.org/cursos
16
Curso J150
Clientes J2EE
Clientes J2EE podem ser Web ou aplicaes (applets ou no).
Clientes Web J2EE
24/04/04 01:43:06
jp@psique.org http://www.psique.org/cursos
17
Curso J150
Ca m ad a
WEB
Ca m a d a
de
Neg cio s
Componentes Web
Os componentes WEB de J2EE podem ser servlet ou JSP. Servlets
so Classes em Java que dinamicamente processam requisies e
constroem respostas (normalmente em XML e HTML). Pginas JSP
so como servlets mas admitem uma forma mais natural de criar
contedo esttico.
Pginas estticas (HTML) e applets so empacotadas com os
componentes WEB durante a montagem, mas no so consideradas
como componentes WEB pela especificao J2EE. Classes utilitrias
24/04/04 01:43:07
jp@psique.org http://www.psique.org/cursos
18
Curso J150
Componentes de Negcios
Regras de negcio so controladas por enterprise beans sendo
executadas na camada de negcio.
Sem J2EE a figura a seguinte:
24/04/04 01:43:10
jp@psique.org http://www.psique.org/cursos
19
Curso J150
Continers J2EE
Por que utilizar um continer?
Normalmente, aplicaes clientes magras, so difceis de escrever
porque envolvem muitas linhas de cdigo para controlar transaes
e o estado, mltiplas threads, pools de recursos e outros detalhes
complexos de baixo nvel. Os componentes baseados na arquitetura
J2EE tornam as aplicaes J2EE fceis de escrever porque a lgica
24/04/04 01:43:11
jp@psique.org http://www.psique.org/cursos
20
Curso J150
Servios do Continer
Continers so a interface entre um componente as funcionalidades
de baixo nvel especficas a uma plataforma que suportam os
componentes. Antes que um componente J2EE possa ser executado,
ele precisa ser montado (assembled) em uma aplicao J2EE e ser
implantado (deployed) no continer.
Servios J2EE
Os continers J2EE disponibilizam um conjunto de servios para
facilitar a utilizao, so servios que sob a responsabilidade do
continer simplificam para o Desenvolvedor.
Modelo de segurana Quem pode acessar
Modelo de transaes Relaes entre mtodos que compem um
transao (para que sejam tratados como uma nica transao).
JNDI lookup Interface unificada para servios de nomes e
diretrios.
Modelo de Conectividade Remota - gerencia a comunicao de
baixo nvel entre clientes e EJBs. Depois que um EJB criado, um
cliente invoca um mtodo nele como se ele estivessem na mesma
24/04/04 01:43:13
jp@psique.org http://www.psique.org/cursos
21
Curso J150
mquina virtual.
Tipos de continer
O processo de deployment instala os componentes da aplicao
J2EE nos continers.
Empacotamento
Uma aplicao J2EE empacotada em um Enterprise Archive
(EAR). Um EAR um JAR com a extenso .ear. Um arquivo EAR
contem os mdulos J2EE. O uso de arquivos EAR e mdulos torna
possvel montar uma quantidade diferente de aplicaes J2EE
reutilizando componentes.
EAR
JAR
24/04/04 01:43:15
jp@psique.org http://www.psique.org/cursos
WAR
22
Curso J150
Mdulo J2EE
Um mdulo J2EE consiste em um ou mais componentes J2EE para o
mesmo tipo de continer e um descritor de implantao
(componente deployement descriptor).
O deployment descriptor um documento XML com a extenso .xml
que descreve as configuraes dos componentes. Um descritor de
um EJB declara os atributos de transaes e de segurana.
A vantagem utilizando a forma declarativa, que as configuraes
podem ser alteradas sem modificao do cdigo. Em tempo de
execuo o servidor J2EE l o descritor e reage de acordo com as
configuraes.
Mdulos tipos
Mdulos EJBs contm os arquivos .class dos EJBs e o EJB
deployment descriptor. So empacotados em arquivos com a
extenso .jar.
Mdulos WEB contm arquivos JSP, .class dos servlets, imagens e
HTMLs, alm do Web deployment descriptor. Os mdulos WEB so
empacotados em arquivos JAR com a extenso .war (Web Archive).
Mdulos tipos
Resource adapter modules, contm todas as interfaces Java, classes,
bibliotecas nativas e outras documentaes, implementa a
24/04/04 01:43:20
jp@psique.org http://www.psique.org/cursos
23
Curso J150
Web Services
So servios baseados em Web que utilizam protocolos abertos e
baseados em XML. So fceis de escrever Web services e Clientes
com as APIs de XML de J2EE.
Tudo que se precisa passar os parmetros para chamadas de
mtodo e processar os dados retornados. Para web service do tipo
(document-oriented), enviar documentos contendo dado de um
servio. Nenhum tipo de programao de baixo nvel necessria.
Papis de desenvolvimento
A utilizao de mdulos reusveis tornam possvel dividir o
desenvolvimento da aplicao e o processo de implantao em
papis distintos.
24
Curso J150
24/04/04 01:43:24
jp@psique.org http://www.psique.org/cursos
25
Curso J150
Application Assembler
o Montador de aplicaes, a empresa ou pessoa que recebe os
componentes JAR da aplicao do Component Provider e os monta
em um arquivo EAR. O assembler ou deploy pode editar o
deployment descriptor diretamente ou usar usar ferramentas que
manuseiam as TAGs XML dos descritores.
26
Curso J150
24/04/04 01:43:28
jp@psique.org http://www.psique.org/cursos
27
Curso J150
Servidor de Aplicaes
Para utilizar-mos J2EE, necessitamos de um continer J2EE. Para
este curso utilizaremos o JBOSS, por ser um dos mais utilizados no
mundo e por ter cdigo livre.
JBOSS
Utilizaremos o JBOSS verso 3.2.3, este software pode ser
encontrado no site:
http://www.jboss.org
JBoss caractersticas
Design modular totalmente baseado em JMX (Java Management
eXtensions)
Tem hot-deploy
Suporta completamente J2EE 1.3 (EJB, JCA, JSP, JMX, HTTP etc)
Implementao completa de segurana e integrao com JAAS.
Executa clustering de qualquer objeto java (EJB, HTTP, POJO).
Infraestrutura para programao orientada a aspectos (AOP).
JBoss Instalao
Faa o download do pacote binrio do stio do JBoss
(http://www.jboss.org)
24/04/04 01:43:29
jp@psique.org http://www.psique.org/cursos
28
Servidor de Aplicaes
Curso J150
JBoss Ativao
Para ativar o JBoss, execute o script run.bat (windows) ou run.sh
(linux). Estes scripts esto no diretrio bin.
24/04/04 01:43:31
jp@psique.org http://www.psique.org/cursos
29
Servidor de Aplicaes
Curso J150
linux
cd \j150
setambiente.bat
run
cd ~/j150
. ./setambiente.sh
run.sh
run -c all
ou
linux
run.sh -c all
24/04/04 01:43:33
jp@psique.org http://www.psique.org/cursos
30
Servidor de Aplicaes
Curso J150
conf/jbossmq-state.xml
O arquivo jbossmq-state.xml o arquivo de configurao para o
JBossMQ, nele so informados os mapeamentos de usurios e
arquivos.
conf/jndi.properties
O arquivo jndi.properties especifica as propriedades do Contexto
Inicial JNDI que ser utilizado pelo servidor JBoss quando for criado
um InitialContext sem especificao de argumentos no construtor.
conf/log4j.xml
O arquivo log4j.xml configura o framework log4j da Apache usado
pelo servidor.
conf/login-config.xml
O arquivo login-config.xml contm um exemplo de configurao
para autenticao do lado do servidor que utilizada utilizando
segurana baseada em JAAS.
conf/server.policy
o arquivo onde esto configuradas as permisses de Java2
security. O arquivo default simplesmente d todos os acessos a
todos os codebases.
conf/standardjaws.xml
Prov a configurao default para acesso ao antigo JBossCMP EJB
1.1 . A camada cmp foi reescrita no JBoss 3.0 para suportar EJB 2.0.
conf/standardjbosscmp-jdbc.xml
Este arquivo tem a configurao bsica para o JBoss 3.2 EJB 2.0
JBoss CMP.
24/04/04 01:43:35
jp@psique.org http://www.psique.org/cursos
31
Servidor de Aplicaes
Curso J150
conf/standardjboss.xml
O arquivo standardjboss.xml prov as configuraes default do
container.
deploy/http-invoker.sar
O arquivo http-invoker.sar contm o invoker que suporta RMI/HTTP.
E tambm configura os prxies de RMI/HTTP para os servios de
nome JNDI que permitem que o servio JNDI seja acessado por http.
deploy/jbossweb-jetty.sar
O diretrio jboss-web-jetty.sar um MBean desempacotado para a
configurao do engine de servlet Jetty. O SAR desempacotado
para facilitar a ediao dos descritores ( jbossweb-jetty.sar/METAINF/jboss-service.xml)
deploy/jmx-console.war
O diretorio jmx-console.war um aplicao web desempacotada
que prov adaptadores HTML para o JMX MBeanServer. O war
desempacotado para facilitar o acesso aos descritores jmxconsole.war/WEB-INF/*.xml.
deploy/management/console-mgr.sar , web-console.war
console-mgr.sar e web-console.war so uma aplicao web
experimental que prov um viso mais rica do gerenciamento do
servidor JMX. Voc pode acess-la pela URL
http://localhost:8080/web-console/.
24/04/04 01:43:37
jp@psique.org http://www.psique.org/cursos
32
Servidor de Aplicaes
Curso J150
deploy/hsqldb-ds.xml
o arquivo de configurao do banco de dados Hypersnic 1.7.1.
Serve para configurar o banco de dados utilizado e as fbricas de
conexo. Utiliza o formato de DataSource JCA.
deploy/transaction-service.xml
O arquivo transaction-service.xml configura os servios
relacionados com JTA
JBoss deploy
Como o servidor JBoss suport Hot-Deploy, basta copiar o arquivo
EAR para o diretrio:
${JBOSS_HOME}/server/default/deploy
A aplicao ser automaticamente instalada se o
JBoss Tomcat
Esta verso do JBoss j vem integrada ao TOMCAT. Tomcat um
software de cdigo livre do projeto Apache, e o continer WEB
mais utilizado no mundo, alm de ser a implementao de
referncia para JSP e Servlets.
JBoss JMX-Console
Como j dito, o JBoss baseado em JMX. JMX um padro para
manuteno e monitoramento de componentes de hardware e
software de java. Um MBean, um objeto java que implementa o
padro de interface MBean e segue os patterns associados.
24/04/04 01:43:39
jp@psique.org http://www.psique.org/cursos
33
Servidor de Aplicaes
Curso J150
34
Servidor de Aplicaes
Curso J150
Laboratrio 15_01
Inicializar o JBoss, abra um console e digite:
windows
linux
cd \j150<enter>
setambiente<enter>
run<enter>
cd ~/j150<enter>
. ./setambiente.sh<enter>
run.sh<enter>
linux
cd \j150 <enter>
setambiente <enter>
cd laboratorio\15_01 <enter>
cd ~/j150 <enter>
setambiente.sh <enter>
cd laboratorio/15_01 <enter>
24/04/04 01:43:43
jp@psique.org http://www.psique.org/cursos
35
Servidor de Aplicaes
Curso J150
Na tela do servidor:
16:25:07,667 INFO
16:25:07,725 INFO
24/04/04 01:43:44
jp@psique.org http://www.psique.org/cursos
36
JNDI
Curso J150
JNDI
Java Naming and Directory Interface
Os servidores de nomes
Seu servidor J2EE deve ter implementaes de RMI-IIOP e de JNDI.
Normalmente no bom misturar estas implementaes (utilizar o
pacote RMI-IIOP da sun com a implementao de JNDI da BEA).
Para evitar problemas e facilitar a implementao melhor utilizar
uma nica soluo.
O acesso a um enterprise bean feito atravs de JNDI. Portanto,
importante entender a sua API.
JNDI significa Java Naming and Directory Interface, e uma API
para localizao de recursos em uma REDE por nome,
possibilitando a independncia da localizao fsica.
JNDI Objetivo
JNDI um servio de localizao. Serve para localizar servios na
rede.
O objetivo de um servio de nomes possibilitar a associao de um
nome a um recurso.
Objetiva principalmente:
Mapear um nome a um objeto. Isto chamado de binding.
Localizar um recurso a partir do nome. Esta a operao de
24/04/04 01:43:46
jp@psique.org http://www.psique.org/cursos
37
JNDI
Curso J150
lookup.
Um servio de nomes parecido com o de uma telefonista. Quando
voc quer pedir uma ligao para algum pelo telefone, e voc no
sabe o nmero do telefone da pessoa. Voc liga para o servio de
informaes de sua empresa telefnica, pede que o operador
procure (faa um lookup) a pessoa com a qual voc quer falar. Voc
diz telefonista o nome da pessoa, a telefonista procura o nmero
do telefone da pessoa que voc quer falar e pode discar o nmero
desta pessoa e conect-lo pessoa desejada. Com isto voc no
precisa saber o nmero do telefone, apenas com o nome voc
conseguiu a conexo desejada.
Vrios exemplos de servios de nomes so facilmente encontrados:
O DNS (Internet Domain Name System), mapeia um nome de
mquina (www.psique.org) a um endereo IP (200.155.13.13).
No file system de uma mquina, um nome de arquivo
(c:/bin/autoexec.bat) mapeado para um file handle que um
programa pode usar para acessar o contedo do arquivo.
Em geral, um servio de nomes pode ser utilizado para encontrar
qualquer tipo de objeto genrico, tais como, um handle para um
arquivo no seu hd ou uma impressora na rede.
Para procura um objeto em um sistema de nomes, voc tem que
fornecer o nome do objeto. O sistema de nomes determina a sintaxe
que o nome deve seguir. Este sintaxe algumas vezes chamado de
naming convention (conveno de nomes).
24/04/04 01:43:48
jp@psique.org http://www.psique.org/cursos
38
JNDI
Curso J150
Objetos de Diretrios
Existe um tipo de objeto localizvel via JNDI que particularmente
importante: um objeto diretrio (ou uma entrada de diretrio).
Um objeto diretrio diferente dos demais objetos pois pode
armazenar atributos com os objetos do diretrio. Estes atributos
podem ser utilizados para uma quantidade muito grande de
propsitos.
Um servio de diretrio uma extenso de um servio de nomeao
para a manipulao de atributos. Um servio de diretrio associa
nomes com objetos e tambm permite queles objetos terem
atributos que descrevam os objetos. Esses objetos permite que voc
busque por um objeto sem conhecer o seu nome. Um exemplo de um
servio de diretrio o Lightweight Directory Access Protocol
(LDAP). Os servios de diretrio no so usados para acessar
24/04/04 01:43:50
jp@psique.org http://www.psique.org/cursos
39
JNDI
Curso J150
enterprise beans.
Com o que se parece um diretrio? O contedo do diretrio o
conjunto de objetos de diretrio conectados normalmente
representado por uma estrutura hierrquica de rvore. Por que
isto? Suponha que o root (n raiz) de sua rvore de diretrio
represente a empresa, um galho do raiz pode representar pessoas
da empresa, outro galho pode representar servios de rede. Cada
ramificao pode ter sub-rvores que decrescem em granularidade
mais e mais, at que se tenha um objeto nico (uma impressora,
uma pessoa).
Osdetalhesdecomoodiretrioestorganizadoconstamemmeta
dados.Osmetadadosdodiretriodefinemaestruturadeseu
diretrio.Osmetadadosdefinemoesquemaqueseusdadosesto
organizados.
Umdiretrionomuitodiferentedeumbancodedados.Umbanco
dedadospodearmazenardados,comodiretrios,Bancodedados
temfuncionalidadesparaalocalizaodedados,damesmaforma
quediretrios.Vocpodepensaremumdiretriocomoumbancode
dadoshierrquicosimplificado.Defato,muitosdiretriosso
implementadoscomumbancodedados.
Atributos
Um objeto de diretrio pode ter atributos. Por exemplo, uma
impressora pode ser representada por um objeto diretrio que tem
como atributos sua velocidade, sua resoluo, quantidade de cores,
etc. Um usurio pode ser representado por um objeto de diretrio
que tem um atributo, EMail, nmeros de telefone, endereo, etc.
Atributo-identificador
Um atributo tem um identificador de atributo e um conjunto de
valores de atributo. Um identificador de atributo identifica um
atributo independentemente de seu valor. Por exemplo, duas
diferentes contas em um computador podem ter um atributo
'EMAIL' . O atributo 'EMAIL' pode ser utilizado como identificador.
24/04/04 01:43:52
jp@psique.org http://www.psique.org/cursos
40
JNDI
Curso J150
Buscas e Filtros
Vocpodebuscar(lookup)umobjetodeumdiretrioinformadoo
nomedoservio.Alternativamente,muitosdiretrios,comoos
baseadosemLDAP,suportambuscasbaseadasemumaexpresso
lgicanaqualvocespecificaosatributosqueoobjetoouqueos
objetosdevempossuir.Arequisiochamadasearchfilter.Este
estilodebuscatambmchamadodebuscareversa(reverselookup)
oubuscabaseadaemcontedo(contentbasedsearching).
Binding
A associao de um nome com um objeto chamada BINDING. Por
exemplo, um nome de arquivo atribudo ao arquivo. A entrada
DNS contm uma atribuio mquina que contm o endereo IP.
Um nome LDAP atribudo entrada LDAP do servidor.
Resumindo, a ligao:
NOME
RECURSO
Referncias e Endereos
Dependendo do servio de nomes, alguns objetos no podem ser
armazenados diretamente, isto , uma cpia do objeto no pode ser
colocada no servio de nomes. No lugar disto, uma referncia
24/04/04 01:43:54
jp@psique.org http://www.psique.org/cursos
41
JNDI
Curso J150
Contexto
Um contexto um conjunto de atribuies (bindings) nome-objetos.
Cada contexto segue uma conveno de nomes). Um contexto
disponibiliza uma forma de resoluo (lookup) para obter um objeto
que prov operaes sobre como acessar os nomes e objetos,
atribuir um objeto a um nome (bind) e retirar a atribuio (unbind),
alm de possibilitar a listagem dos nomes e recursos. Um nome em
um contexto pode conter a ligao a outro contexto (chamado sub
contexto) que tem a mesma conveno de nomes.
Exemplo:
Um diretrio: ~/j150 contm um subdiretrio ambiente. O
subdiretrio ambiente um sub contexto do contexto ~/j150
Sistema de Nomes
Um sistema de nomes um conjunto de contextos que so
interligados e seguem as mesmas convenes.
Por exemplo, um sistema que implementa o sistema de nomes DNS,
um sistema que se comunica usando um sistema de nomes LDAP
Namespace
Um namespace (espao de nomes) um conjunto de nomes em um
sistema de nomes. Por exemplo, o file system do UNIX tem um namespace
consistindo de todos os nomes de arquivos e diretrios no file system. O
namespace do DNS contm nomes de domnio DNS e entradas. O
namespace de LDAP contem entradas de LDAP.
Em um file system do WINDOWS: Se os contextos e sub contextos so os
24/04/04 01:43:55
jp@psique.org http://www.psique.org/cursos
42
JNDI
Curso J150
Benefcios de JNDI
24/04/04 01:43:57
jp@psique.org http://www.psique.org/cursos
43
JNDI
Curso J150
Voc pode ligar diferentes tipos de diretrios (LDAP com NDS por
exemplo) visualizar esta combinao como se fosse um nico
diretrio. (NDS = Novell Directory Services).
Arquitetura
Utilizao
Para utilizar JNDI, voc precisa ter as classes JNDI e um ou mais
provedores de servio. O Java 2SDK v1.3 inclui trs provedores de
servio:
LDAP
CORBA (Common Object Request Broker Architecture) Common
Object Services (COS) name service
24/04/04 01:43:59
jp@psique.org http://www.psique.org/cursos
44
JNDI
Curso J150
A API JNDI
A API JNDI dividida em 5 pacotes
javax.naming
javax.naming.directory
javax.naming.event
javax.naming.ldap
javax.naming.spi
javax.naming.Context
Context
A interface Context representa um contexto de nomeao,
24/04/04 01:44:01
jp@psique.org http://www.psique.org/cursos
45
JNDI
Curso J150
Exemplo:
Printer printer = (Printer)ctx.lookup(impressoraDois):
printer.print(report);
Names
A noo de um nome fundamental para JNDI. O sistema de nomes
24/04/04 01:44:03
jp@psique.org http://www.psique.org/cursos
46
JNDI
Curso J150
Composite
So os nomes cujas partes na realidade so compostas por mais de
um namespace. Exemplo, um recurso de scp:
psique.org:/home/psique
(psique.org um namespace que identifica um host e /home/psique
outro namespace que identifica um diretrio de um file system).
Compound
So os nomes derivados de um namespace hierrquico. Exemplo
pode ser um caminho: \tmp\arquivo.txt
Bindings
Um bind a ligao de um nome a um recurso, podem ser
mostrados pelos mtodos:
listBindings() retorna um object enumeration de ligaes nomeobjeto. Cada ligao representada por um instncia da classe
javax.naming.Binding. Uma ligao uma tupla contendo o nome
do objeto atribudo, o nome da classe do objeto e o objeto.
24/04/04 01:44:05
jp@psique.org http://www.psique.org/cursos
47
JNDI
Curso J150
Reference
A classe javax.naming.Reference, utilizada para representar a
referncia a um objeto.
A classe javax.naming.InitialContext
Em JNDI, todas as operaes com nomes e diretrios so
executadas em relao a um contexto. No existe um contexto raiz
absoluto. Existe uma classe InitialContext que prov um ponto
inicial para as operaes de nomes e diretrios. Uma vez que se
obtenha um contexto inicial, ele ser utilizado para busca de outros
contextos e objetos.
Para um contexto, voc precisa definir uma srie de propriedades
para o ambiente do contexto. Por exemplo, uma resoluo de
nomeao pode ser restrita s a usurios autorizados. Neste caso,
voc cria um objeto java.util.Properties e usa o mtodo put para
acrescentar pares chave/valor, representando quaisquer
propriedades de nomes e valores necessrios.
Todas as operaes com nomes so feitas com uma implementao
da interface Context. Para obter uma instncia de context, existe a
classe concreta javax.naming.InitialContext (que implementa a
interface Context). Quando se cria um InitialContext, ele
inicializado com propriedades de ambiente. Considerar: a
ocorrncia de property passado como parmetro para o construtor,
parmetros para applet e propriedades do sistema. Em seguida
todos os arquivos jndi.properties encontrados no classpath.
24/04/04 01:44:07
jp@psique.org http://www.psique.org/cursos
48
JNDI
Curso J150
24/04/04 01:44:09
jp@psique.org http://www.psique.org/cursos
49
JNDI
Curso J150
import java.util.Properties;
import javax.naming.*;
...
//Cria um objeto properties
Properties properties = new Properties();
// Adiciona duas propriedades
properties.put(Context.INITIAL_CONTEXT_FACTORY ,
org.jnp.interfaces.NamingContextFactory);
properties.put(Context.PROVIDER_URL, localhost:1099);
try {
javax.naming.InitialContext jndiContext = new
javax.naming.InitialContext(properties);
// Pegar a referencia ao objeto:
Object ref = jndiContext.lookup(Somador);
}
24/04/04 01:44:10
jp@psique.org http://www.psique.org/cursos
50
JNDI
Curso J150
Ambiente - ENC
JNDI um aspecto fundamental da especificao J2EE. Um dos
principais usos o isolamento do cdigo dos componentes com o
ambiente onde o cdigo ser instalado (continer). O ambiente dos
componentes da aplicao algumas vezes chamado de Enterprise
Naming Context (ENC). responsabilidade do continer tornar o
ENC disponvel para o componente do continer na forma de um
contexto de JNDI. O ENC utilizado pelos participantes envolvidos
no ciclo de vida dos componentes J2EE das seguinte forma:
1. A lgica de negcio dos componentes deve ser codificada para
acessar informaes do ENC. O Component Provider usa os
descritores padres do componente para especificar as entradas
ENC necessrias. As entradas so declaraes das informaes e
recursos que o componente ir precisar no momento de execuo
2. O continer disponibiliza ferramentas que permitem mapear as
referncias ENC feitas pelo component developer para o
ambiente do continer.
3. O component deployer usa ferramentas para preparar o
componente para a instalao final.
4. O continer usa as informaes do pacote de deployment para
completar o ENC a runtime.
Exemplo de acesso ao ENC
51
JNDI
Curso J150
Exemplo de um WEB.XML
<web>
...
<servlet>
...
</servlet>
...
<!-- JDBC DataSource (java:comp/env/jdbc) -->
<resource-ref>
<description> Default DS </description>
<res-ref-name>jdbc/DefaultDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
...
</web>
Exemplo de acesso:
52
JNDI
Curso J150
(java:comp/env/jdbc/DefaultDS);
24/04/04 01:44:16
jp@psique.org http://www.psique.org/cursos
53
JNDI
Curso J150
Exceptions
A API JNDI define um hierarquia de exceptions que podem ser
lanadas nas operaes com nomes e diretrios. A classe raz
javax.naming.NamingException.
Pacote: javax.naming.directory
Estende o pacote javax.naming, adicionando funcionalidades para
acessar os servios de diretrios. Este pacote deixa aplicaes
recuperarem atributos associados com objetos armazenados em
diretrios e a buscar objetos usando atributos.
O contexto do diretrio
A interface javax.naming.directory.DirContext representa o
contexto de um diretrio. E define mtodos para examinar e
alterar atributos associados a um objeto diretrio.
Utilize: getAttributes() para recuperar os atributos e
modifyAttributes() para modific-los.
Cada contexto de diretrio um contexto. Um objeto diretrio de
uma pessoa podem conter atributos sobre a pessoa bem como
prover um contexto de nomes objetos da pessoa, tais como, as
impressoras e arquivos da pessoa, parentes da pessoa,
subordinados pessoa, etc...
24/04/04 01:44:18
jp@psique.org http://www.psique.org/cursos
54
JNDI
Curso J150
Buscas
Os contexto de diretrio contm mtodos para efetuar buscas
baseadas no contexto, atravs do mtodo search().
Para obter uma referncia a um recurso precisamos das seguintes
etapas:
Laboratrio 20_01
Abrir um console e digitar:
windows
linux
cd \j150
setambiente
cd laboratorios\20_01
cd ~/j150
setambiente.sh
cd laboratorios/20_01
Laboratrio 20_02
Abrir um console e digitar:
windows
linux
24/04/04 01:44:20
jp@psique.org http://www.psique.org/cursos
cd \j150\laboratorios\20_02
cd ~/j150/laboratorios/20_02
55
JNDI
Curso J150
Este exemplo utiliza JNDI provido pelo Jboss (jnp = JBoss Naming
Provider).
Laboratrio 20_03
Abrir um console e digitar:
windows
linux
cd \j150\laboratorios\20_03
cd ~/j150/laboratorios/20_03
24/04/04 01:44:21
jp@psique.org http://www.psique.org/cursos
56
Curso J150
ANT Documentao
A documentao do ANT muito bem feita e completa, est
instalada no sub-diretrio docs do ANT_HOME (local onde o ANT foi
instalado).
ANT Execuo
Para executar o ANT:
Se a instalao estiver de acordo, basta digitar:
ant <enter>
24/04/04 01:44:23
jp@psique.org http://www.psique.org/cursos
57
Curso J150
windows: PATH=%PATH%;%ANT_HOME%\bin
linux: PATH=${PATH};${ANT_HOME}/bin
cd \j150 <enter>
cd ~/j150 <enter>
24/04/04 01:44:25
jp@psique.org http://www.psique.org/cursos
58
Curso J150
Configure o ambiente:
windows:
linux:
setambiente <enter>
. ./setambiente.sh <enter>
cd laboratorios\22_01 <enter>
cd laboratorios/22_01 <enter>
Execute
ant
<enter>
ant
alternativo
Analise o resultado
Execute outro alvo
<enter>
Veja o build.xml
windows
linux
Foi constatado:
Cada alvo uma TAG <target name=alvo> no build.xml.
A tag padro informada como o atributo default da tag project.
Este atributo indica qual o alvo que ser executado quando no
informado alvo ao se executar o ant.
Laboratrio 22_02
V para o diretrio do laboratrio:
windows:
cd ..\22_02 <enter>
24/04/04 01:44:27
jp@psique.org http://www.psique.org/cursos
59
linux:
Curso J150
cd ../22_02 <enter>
Execute:
ant <enter>
ant alternativo <enter>
Tag <project>
A tag <project> tem trs atributos e o elemento principal de um
build.xml.
Os atributos so:
name=alvoa/>
name=alvob depends=alvoa/>
name=alvoc depends=alvob/>
name=alvod depends=alvoc,alvob,alvoa/>
24/04/04 01:44:29
jp@psique.org http://www.psique.org/cursos
60
Curso J150
Tarefas
As tarefas so includas no corpo da tag TARGET, e sero aes
executadas quando o corpo for executada. Nos laboratrios
anteriores, existia apenas uma tarefa em cada alvo. A tarefa <echo
message=valor/> simplesmente imprime a mensagem informada
no atributo message na sada.
Tarefas podem ter mltiplos atributos. O valor de um atributo pode
conter referncias a uma propriedade. Estas referncias sero
resolvidas antes que a tarefa seja executada.
<nome atributo1=valor1 atributo2=${propriedade} ... />
Propriedades
Um projeto pode ter um conjunto de propriedades. As propriedades
podem ser configuradas no prprio build.xml atravs da tarefa
<property>, ou podem ser configuradas fora do ANT por arquivos
de properties.
Uma propriedade pode ser usada no valor de um atributo de uma
24/04/04 01:44:31
jp@psique.org http://www.psique.org/cursos
61
Curso J150
tarefa:
<property name=msg value=Oi mundo/>
<echo message=${msg}/>
Laboratrio 22_03
V para o diretrio do laboratrio:
windows:
linux:
Execute:
cd ..\22_03 <enter>
cd ../22_03 <enter>
ant <enter>
Propriedades externas
possvel incluir um arquivo de propriedades (properties), em um
build.
O arquivo conter pares nome=valor :
propriedade1=valor
propriedade2=valor
O arquivo de propriedades includo atravs do atributo file da tag
<properties>.
<properties file=nomedoarquivo.properties/>
No arquivo de propriedades, podem existir comentrios,
utilizando-se o smbolo # (sustenido, velho ou escopa)
24/04/04 01:44:33
jp@psique.org http://www.psique.org/cursos
62
Curso J150
Laboratrio 22_04
V para o diretrio do laboratrio:
windows:
linux:
Execute:
cd ..\22_04 <enter>
cd ../22_04 <enter>
ant <enter>
Propriedades no so redefinidas
Laboratrio 22_05
V para o diretrio do laboratrio:
windows:
linux:
cd ..\22_05 <enter>
cd ../22_05 <enter>
Execute:
ant <enter>
24/04/04 01:44:35
jp@psique.org http://www.psique.org/cursos
63
Curso J150
Laboratrio 22_06
V para o diretrio do laboratrio:
windows:
linux:
cd ..\22_06 <enter>
cd ../22_06 <enter>
Execute:
ant <enter>
Verso Java
${java.class.path}
Classpath
${os.name}
Nome Sist.Operacional
${os.arch}
Arquitetura Sist.Operacional
${file.separator}
$path.separator
$line.separator
(\n no linux)
$user.name
$user.home
$user.dir
24/04/04 01:44:36
jp@psique.org http://www.psique.org/cursos
64
Curso J150
Outras pr-definidas
O ant, adiciona algumas propriedades alm das de
System.getProperties():
${basedir}
${ant.file}
${ant.version}
A verso do Ant
${ant.project.name}
${ant.java.version}
Laboratrio 22_07
V para o diretrio do laboratrio:
windows:
linux:
cd ..\22_07 <enter>
cd ../22_07 <enter>
Execute:
ant <enter>
windows:
linux :
type build.xml
cat build.xml
Laboratrio 22_08
24/04/04 01:44:38
jp@psique.org http://www.psique.org/cursos
65
Curso J150
cd ..\22_08 <enter>
cd ../22_08 <enter>
Execute:
windows:
linux :
help_ant <enter>
help_ant.sh <enter>
24/04/04 01:44:40
jp@psique.org http://www.psique.org/cursos
66
Java RMI
Curso J150
Java RMI
Java RMI sobre IIOP (Java Remote Method invocation sobre
InternetInter-ORB Protocol) o protocolo utilizado em J2EE para
executar de forma simples acessos via rede. RMI-IIOP admite que
voc distribua objetos em Java, habilitando objetos a se
comunicarem em Mquinas Virtuais distintas e em dispositivos
fsicos distintos.
RMI-IIOP no a nica possibilidade para executar mtodos
remotamente em Java. Pode-se utilizar tambm RMI. RMI a forma
original para execuo remota em java. RMI do J2SE e encontrase no pacote java.rmi. RMI-IIOP uma verso especial de RMI que
compatvel com CORBA e usa os pacotes java.rmi e javax.rmi.
RMI tem algumas caractersticas bem interessantes no disponveis
em RMI-IIOP, tais como garbage collection distribuda, ativao de
objetos e download de class files. Mas EJB e J2EE prevem a
utilizao de RMI-IIOP.
Marshalling e Unmarshalling
RMIs (bem como RPCs em geral) permitem a passagem de
parmetros, que podem ser os tipos primitivos e objetos Java, sobre
a rede. Mas e se a mquina destino tiver uma representao de
24/04/04 01:44:42
jp@psique.org http://www.psique.org/cursos
67
Java RMI
Curso J150
Instabilidades de rede
Quando estamos dentro de uma mesma JVM, se a JVM quebrar toda
a aplicao quebra junto, ou seja, todos os processos quebram. Em
aplicaes distribudas, se uma JVM estiver trabalhando com outra
e somente uma quebrar poderemos ter problemas. Qualquer cdigo
executado remotamente deve ter formas de ser notificado caso
ocorram problemas de rede, na mquina de destino ou na JVM de
destino. RMI-IIOP cuida destes detalhes.
A interface remota
Ao trabalharmos com RMI-IIOP utilizamos uma prtica muito
24/04/04 01:44:44
jp@psique.org http://www.psique.org/cursos
68
Java RMI
Curso J150
import java.rmi.Remote;
import java.rmi.RemoteException;
24/04/04 01:44:45
jp@psique.org http://www.psique.org/cursos
69
Java RMI
Curso J150
24/04/04 01:44:47
jp@psique.org http://www.psique.org/cursos
70
Java RMI
Curso J150
import java.rmi.RemoteException;
import javax.rmi.PortableRemoteObject;
public class GeradorDeChave extends PortableRemoteObject
implements iGeradorDeChave {
public GeradorDeChave throws Exception , RemoteException {
// Como esta classe estende PortableRemoteObject,
// O construtor da super classe faz o que precisamos
// que a chamada ao objeto remoto.
super();
}
public synchronized long gerador() throws RemoteException {
return i++;
}
private static long i = System.currenttimeMillis();
}
24/04/04 01:44:49
jp@psique.org http://www.psique.org/cursos
71
Java RMI
Curso J150
Stubs e Skeletons
Agora que ns vimos o cdigo do servidor, vamos dar uma olhada na
arquitetura de rede por trs de RMI-IIOP. Utilizando RMI-IIOP
temos a iluso de acessar o mtodo de forma transparente atravs
da rede. Voc pode invocar mtodos de um objeto remoto como
invocaria qualquer outro de qualquer objeto Java. De fato, RMI-IIOP
mascara completamente onde est o objeto que est sendo
invocado. Isto chamado transparncia local/remota.
Mas a transparncia local/remota no uma coisa to simples como
parece. Para mascarar o fato de que voc est invocando um objeto
residente em outra mquina, RMI precisa simular um objeto local
que voc ir invocar. Este objeto local chamado de stub e
responsvel por aceitar chamados a mtodos locais e delegar a
chamadas a mtodos para as implementaes reais, que podem
estar localizadas em qualquer lugar da rede. Voc pode pensar em
um stub como se fosse um local para se colocar um objeto que sabe
como procurar pela rede o objeto real. Porque voc invoca um
mtodo na mquina local (o stub), todas tarefas complicadas ficam
ocultas do cliente.
Stubs so apenas metade do cenrio. Ns desejamos que os objetos
remotos os objetos que esto sendo invocados na mquina remota
tambm no se preocupem com os detalhes de comunicao via
rede. Assim como o cliente invoca um STUB que local ao cliente,
o objeto remoto precisam aceitar chamadas de um SKELETON que
um objeto local ao objeto remoto (fica na mesma JVM que o objeto
remoto). Skeletons so responsveis por receber chamadas pela
rede e delegar estas chamadas para a implementao de um objeto
remoto.
24/04/04 01:44:51
jp@psique.org http://www.psique.org/cursos
72
Java RMI
Curso J150
Cliente
Objeto Remoto
Remote
Interface
Stub
Skeleton
REDE
Mquina do Servidor
Mquina do Cliente
24/04/04 01:44:53
jp@psique.org http://www.psique.org/cursos
73
Java RMI
Curso J150
24/04/04 01:44:55
jp@psique.org http://www.psique.org/cursos
74
Java RMI
Curso J150
URLs de RMI
Um URL (Unified Ressource Locator) uma string em Java que
utilizada para localizar um objeto remoto em outra Mquina Virtual.
Parece com as URLs que acessamos para acessar um stio na
internet (http://java.sun.com). A conveno para a URL :
1. A URL precisa comear com o texto rmi://
2. Voc precisa ento especificar qual a mquina de destino onde
a JVM est localizada por exemplo:
rmi://paizao.limberger.2y.net. Se voc no especificar a mquina
de destino o default ser localhost.
3. No final, o nome do objeto remoto do qual voc quer a referncia
remota. Por exemplo, se o objeto remoto foi chamado de
meuObjeto, voc pode referenci-lo de qualquer mquina no
mundo com a URL:
rmi://paizao.limberger.2y.net/meuObjeto
24/04/04 01:44:56
jp@psique.org http://www.psique.org/cursos
75
Java RMI
Curso J150
Cliente
Cliente
Localizao
via RMI
Stub
Quando o
cliente
conseguir o
STUB
Rede
Registro
RMI
Objetos
Remotos
Rede
Skeleton
Objeto
Remoto
76
Java RMI
Curso J150
24/04/04 01:45:01
jp@psique.org http://www.psique.org/cursos
77
Java RMI
Curso J150
Serializao de Objetos
Java introduziu um conceito de serializao de objetos para
contornar este problema. Serializao a converso de um objeto
java em uma representao binria do objeto. Uma vez que o objeto
foi transformado para a forma binria (um pacote de bytes), este
pacote pode ser gravado no disco, transmitido pela rede. Quando
voc quiser transformar o pacote de bytes de volta forma de
objeto, voc ter que executar a desserializao do pacote.
A linguagem Java cuida dos detalhes de baixo nvel para a
serializao de desserializao do objeto. Na maioria dos casos, no
precisamos nos preocupar com isto. Para dizermos ao java que um
objeto pode ser serializado, basta implementarmos uma interface
chamada java.lang.Serializable. Esta interface no define nenhum
mtodo, somente marca o objeto como serializvel.
78
Java RMI
Curso J150
79
Java RMI
Curso J150
24/04/04 01:45:07
jp@psique.org http://www.psique.org/cursos
80
Java RMI
Curso J150
81
Java RMI
Curso J150
24/04/04 01:45:11
jp@psique.org http://www.psique.org/cursos
82
Java RMI
Curso J150
No estender java.rmi.server.UnicastRemoteObject.
Laboratrio 24_01
Exemplo RMI
para Compilar:
set classpath=.
javac org/psique/SampleServer.java
javac org/psique/SampleServerImpl.java
rmic org.psique.SampleServerImpl
javac org/psique/SampleClient.java
Para Executar:
Executar o servidor:
rmiregistry &
java
-Djava.security.policy=policy.all org.psique.SampleServerImpl
24/04/04 01:45:13
jp@psique.org http://www.psique.org/cursos
83
Curso J150
RMI ou CORBA
Historicamente, desenvolvedores tem decidido entre utilizar RMI
ou CORBA para implementar distribuio de servios.
Quando se combina RMI com alguma outra API os benefcios do
Corba no so to expressivos. Usar JNDI no lugar do naming
system de Corba. A API Java Transaction e Java Transaction Service
pode ser utilizada para controle de transaes, e faz o mesmo
trabalho que o Object Transaction Service de Corba. possvel
alguma interao entre linguagens combinando RMI com JNDI.
Tambm possvel executar operaes com banco de dados
relacionais com chamadas RMI/JDBC.
Corba por outro lado, est ficando mais fcil de ser utilizado.
CORBA prov um conjunto de funcionalidades, que no passado eram
muito difceis de aprender. Definition Language (IDL). Agora
existem ferramentas para automaticamente gerar a IDL para voc.
Existe um produto da sun para ler a definio de uma interface
remota e gerar a idl automaticamente. E com a proposta dos novos
componentes de CORBA, vai ser possvel prover inmeros servios
de CORBA automaticamente, sendo disponibilizada um arquitetura
bastante variada de componentes no servidor.
Por estas raes, a Sun avaliza as duas solues RMI e CORBA. No
existe nenhuma tecnologia vencedora. Como ambas so tecnologias
maduras, voc ver muitos servios CORBA refletidos na plataforma
J2EE. A vantagem que J2EE a tecnologia do momento.
RMI e EJB
RMI uma parte essencial de EJB. Em EJB, muitos objetos
distribudos utilizam RMI como a API standard para networking.
24/04/04 01:45:15
jp@psique.org http://www.psique.org/cursos
84
24/04/04 01:45:17
jp@psique.org http://www.psique.org/cursos
Curso J150
85
Curso J150
24/04/04 01:45:18
jp@psique.org http://www.psique.org/cursos
86
Curso J150
Objetos EJB
Em EJB, seus enterprise beans precisam ser disponibilizados a
clientes remotos. Isto pode ser feito utilizando Java RMI.
Note que enterprise beans no so objetos remotos de fato. Isto
seus beans no estendem UnicastRemoteObject. No lugar, seus
beans so empacotados em uma concha que fala RMI chamado de
EJB object. Um EJB object um objeto remoto que o cliente pode
invocar. Quando um cliente chama um EJB object, este objeto
delega a chamada remoto para o bean.
Para desenvolver um bean, voc precisa escrever a interface de seu
EJB object. Esta interface chamada de interface remota, e utiliza
exatamente o mesmo conceito das interfaces remotas que vnhamos
vendo at agora. Esta interface remota duplica a assinatura de cada
mtodo que o bean tem.
Sobre as interfaces remotas de EJB:
87
Curso J150
Objetos Home
Em EJB, um objeto home uma fbrica (factory) para criar EJB
objects. Voc procura pelo HomeObject usando JNDI, Uma vez
tendo o home object, voc o chama utilizando RMI.
A interface home do objeto (chamada home interface) tambm
uma interface remota, e segue as regras de Java RMI. Ela precisa
lanar remote exceptions, implementar java.rmi.Remote e aceita
parmetros serializveis. Como com EJB objects, um home object
proprietrio de cada continer. A implementao concreta do objeto
home gerada pelo continer EJB.
Clientes dos home objects sempre utilizam a interface home para
interagir com estes objetos proprietrios, da mesma forma que
clientes de EJB objects sempre negociam com as interfaces remote.
E como nos EJB objects uma referencia para um home object pode
ser o atual home object ou um RemoteStub para o home object real
localizado em alguma outra localidade na rede.
24/04/04 01:45:22
jp@psique.org http://www.psique.org/cursos
88
Curso J150
89
Curso J150
90
Curso J150
eles sero:
SomadorHome.java
Somador.java
SomadorBean.java
SomadorHome e Somador so as interfaces home e remota do ejb.
SomadorBean o EJB.
A interface SomadorHome
package org.psique.ejb;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface SomadorHome extends EJBHome {
Somador create() throws RemoteException, CreateException;
}
A interface Somador:
package org.psique.ejb;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Somador extends EJBObject {
public int soma(int a, int b) throws RemoteException;
}
24/04/04 01:45:28
jp@psique.org http://www.psique.org/cursos
91
Curso J150
A classe SomadorBean:
package org.psique.ejb;
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class SomadorBean implements SessionBean {
public int soma(int a, int b) {
System.out.println(Somador somando a + b = +
a + + + b + = + (a+b));
return (a+b);
}
public void ejbCreate() {
}
public void ejbRemove() {
}
public void ejbActivate() {
}
public void ejbPassivate() {
}
public void setSessionContext(SessionContext sc) {
}
}
O descritor de distribuio
Deployment Descriptor
Um aplicativo EJB precisa ter um deployment descriptor que
descreva cada enterprise bean naquele aplicativo. O arquivo
descritor de distribuio chamado ejx-jar.xml. neste arquivo
que os componentes so colocados juntos.
Deployment Descriptor
<?xml version=1.0 encoding=ISO-8859-1?>
24/04/04 01:45:30
jp@psique.org http://www.psique.org/cursos
92
Curso J150
Criao de um arquivo de
distribuio
Depois de terminar de desenvolver o seu enterprise bean, voc
precisa empacotar todos os arquivos de classe em um arquivo .jar.
os arquivos de classe so dados na estrutura de diretrio exibida na
figura 28.3. o diretrio ejb contm trs arquivos: Somador.class,
SomadorHome.class e SomadorBean.class. O diretrio META-INF
deve conter o arquivo ejb-jar.xml. o descritor de distribuio.
1. Mude o diretrio para o diretrio superior ao META-INF.
2. Digite o comando:
jar cfv somador.jar org/psique/ejb/* META-INF/ejb-jar.xml
Distribuio
Copie e arquivo somador.jar no diretrio de distribuio do jboss:
24/04/04 01:45:32
jp@psique.org http://www.psique.org/cursos
93
Curso J150
${JBOSS_HOME}/server/default/deploy
O console do JBOSS deve reagir informando nos displays que a
aplicao foi bem instalada.
Para utilizar o EJB precisamos de um cliente.
Partes do EJB
O EJB no uma nica classe, na realidade, existem sempre duas
interfaces que acompanham o BEAN. Essas duas interfaces so
chamadas de interface home e interface remote. Elas existem para
permitir a comunicao entre um cliente e um enterprise bean. O
enterprise bean contm a implementao das regras de negcio.
Claro que um enterprise bean tambm pode ter outras classes. As
duas interfaces e uma classe concreta o mnimo que pode existir.
A interface home e a interface remote so importantes pois elas so
a porta para um enterprise bean em um aplicativo cliente.
A especificao EJB declara que um enterprise bean e seus
componentes de apoio so escritos, implementando ou ampliando
membros do pacote javax.ejb.
A interface home
A interface home realiza as operaes de ciclo de vida: criando,
encontrando e removendo o enterprise bean. Uma interface home
precisa estender a interface EJBHome no pacote javax.ejb. A
interface javax.ejb.EJBHome dada como a seguir:
package javax.ejb;
public interface EJBHome extends java.rmi.Remote {
EJBMetaData getEJBMetaData()
24/04/04 01:45:34
jp@psique.org http://www.psique.org/cursos
94
Curso J150
throws java.rmi.RemoteException;
HomeHandle getHomeHandle()
throws java.rmi.RemoteException;
void remove(Handle handle)
throws java.rmi.RemoteException,
javax.ejb.RemoveException;
void remove(Object primaryKey)
throws java.rmi.RemoteException,
java.ejb.RemoveException;
}
24/04/04 01:45:36
jp@psique.org http://www.psique.org/cursos
95
Curso J150
package org.psique.ejb;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface SomadorHome extends EJBHome {
Somador create() throws RemoteException, CreateException;
}
A interface remote
A interface remote duplica todos os mtodos de negcio do EJB que
esto disponveis ao cliente. Isto ocorre porque o cliente no pode
acessar diretamente o bean.
Uma interface remote precisa estender a interface EJBObject no
pacote javax.ejb. javax.ejb.EJBObject assim definida:
package javax.ejb;
public interface EJBObject extends java.rmi.Remote
public abstract EJBHome getEJBHome()
throws java.rmi.RemoteException;
24/04/04 01:45:38
jp@psique.org http://www.psique.org/cursos
96
Curso J150
24/04/04 01:45:40
jp@psique.org http://www.psique.org/cursos
97
Curso J150
package org.psique.ejb;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Somador extends EJBObject {
public int soma(int a, int b) throws RemoteException;
}
O descritor de distribuio
Um aplicativo EJB precisa de um descritor de distribuio que
especifique meta informaes ao continer EJB. O deployment
descriptor um arquivo XML chamado ejb-jar.xml e precisa estar
localizado no diretrio META-INF, sob o diretrio principal do
24/04/04 01:45:42
jp@psique.org http://www.psique.org/cursos
98
Curso J150
aplicativo.
Algumas informaes especificas do descritor de distribuio:
O tipo do bean
24/04/04 01:45:43
jp@psique.org http://www.psique.org/cursos
99
Curso J150
Um aplicativo cliente
Java
A seguir, juntando tudo que foi visto anteriormente, uma classe
chamada BeanCliente que executa o servio do EJB.
import
import
import
import
import
javax.naming.*;
javax.rmi.PortableRemoteObject;
java.util.Properties;
org.psique.ejb.Somador;
org.psique.ejb.SomadorHome;
100
Curso J150
ejb.jar
jboss-client.jar
jnp-client.jar
ejb.jar
jboss-client.jar
24/04/04 01:45:47
jp@psique.org http://www.psique.org/cursos
101
Curso J150
jnp-client.jar
102
Curso J150
System.out.println(e.toString());
}
%>
24/04/04 01:45:51
jp@psique.org http://www.psique.org/cursos
103
Curso J150
Mastering EJB 2
24/04/04 01:45:53
jp@psique.org http://www.psique.org/cursos
104
Curso J150
105
Curso J150
24/04/04 01:45:56
jp@psique.org http://www.psique.org/cursos
106
Curso J150
24/04/04 01:45:58
jp@psique.org http://www.psique.org/cursos
107
Curso J150
24/04/04 01:46:00
jp@psique.org http://www.psique.org/cursos
108
Curso J150
vrios EJBs.
A interface home
A interface remote
109
Curso J150
A interface javax.ejb.SessionBean
Um session bean precisa estender a interface
javax.ejb.SessionBean. Essa interface estende a interface
javax.ejb.EnterpriseBean e oferece quatro mtodos que so
chamados pelo continer EJB.
Estes mtodos so:
24/04/04 01:46:03
jp@psique.org http://www.psique.org/cursos
110
Curso J150
111
Curso J150
import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class MeuSessionBean implements SessionBean {
public void ejbCreate() {
}
public void ejbRemove() {
}
public void ejbActivate() {
}
public void ejbPassivate() {
}
public void setSessionContext(SessionContext sc) {
}
// implemente aqui os mtodos de negcio
}
A interface javax.ejb.SessionContext e a
interface javax.ejb.EJBContext
Conforme mencionado anteriormente, o continer EJB passa um
objeto javax.ejb.SessionContext ao mtodo setSessionContext da
interface javax.ejb.SessionBean. A interface SessionContext estende
a interface javax.ejb.EJBContext, que oferece mtodos teis para
obter informaes sobre o aplicativo cliente chamador, o objeto
home bean, o ambiente e outras coisas interessantes.
A definio da interface javax.ejb.EJBContext :
112
Curso J150
throws java.rmi.RemoteException;
public java.lang.Object getPrimaryKey()
throws java.rmi.RemoteException;
public void remove()
throws java.rmi.RemoteException,
javax.ejb.RemoveException;
public javax.ejb.Handle getHandle()
throws java.rmi.RemoteException;
public Boolena isIdentical(javax.ejb.EJBObject objetct)
throws java.rmi.RemoteException;
}
113
Curso J150
O deployment descriptor
Cada aplicativo EJB precisa de um deployment descriptor, que um
documento XML de nome ejb-jar.xml O elemento raiz do descritor
<ejb-jar> e ele contm um n chamado <enterprise-beans>. Cada
session bean , ento, registrado sob esse elemento e chamado de
um elemento <session>. Portanto um elemento <session> descreve
um session bean.
Definio de session na DTD (http://java.sun.com/dtd/ejbjar_2_0.dtd):
24/04/04 01:46:10
jp@psique.org http://www.psique.org/cursos
114
Curso J150
24/04/04 01:46:12
jp@psique.org http://www.psique.org/cursos
115
Curso J150
24/04/04 01:46:14
jp@psique.org http://www.psique.org/cursos
116
Curso J150
24/04/04 01:46:15
jp@psique.org http://www.psique.org/cursos
117
Curso J150
Exemplo - Livraria
O aplicativo a seguir, chamado livraria. um aplicativo somente
para demonstrao.
O aplicativo usa quatro servlets na interface com o usurio. Os
quatro servlets representam as quatro pginas da interface de
usurio: uma pgina de Busca, uma pgina de detalhes do Livro,
uma pgina de adicionar cesta e uma pgina de verificar cesta.
Funcionalidades do projeto
A pgina search
24/04/04 01:46:17
jp@psique.org http://www.psique.org/cursos
118
Detalhes do livros
24/04/04 01:46:19
jp@psique.org http://www.psique.org/cursos
Curso J150
119
Curso J150
24/04/04 01:46:21
jp@psique.org http://www.psique.org/cursos
120
Curso J150
O banco de dados
A tabela a ser utilizada ter o seguinte formato:
create table livros (
codLivro int primary key,
titulo varchar(50),
autor varchar(50),
editora varchar(50),
preco double);
24/04/04 01:46:23
jp@psique.org http://www.psique.org/cursos
121
Curso J150
/*
* Created on 08/04/2004
*
* Para este codigo funcionar, o HSQLDB deve estar no modo
TCP/IP
*
* Alterar arquivo: ${JBOSS_HOME}/
server/default/deploy/hsqldb-ds.xml
*
*/
package bd;
import
import
import
import
import
java.sql.Connection;
java.sql.DriverManager;
java.sql.ResultSet;
java.sql.SQLException;
java.sql.Statement;
/**
* @author F4955639
*
* To change the template for this generated type comment go
to
* Window>Preferences>Java>Code Generation>Code
and Comments
*/
public class BancoDeDados {
public static void main(String [] s) {
try {
try {
// Dentro do continer poderia ser:
// DataSource datasource = (DataSource) ctx.lookup
("java:/DefaultDS");
//
Connection conexao = datasource.getConnection();
Class.forName("org.hsqldb.jdbcDriver");
Connection conexao =
DriverManager.getConnection
("jdbc:hsqldb:hsql://localhost:1701","sa","");
Statement st = conexao.createStatement();
122
Curso J150
123
Curso J150
rs.getString(5));
}
conexao.close();
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch(Throwable t) {
t.printStackTrace();
}
}
}
package org.psique.livraria.ejb;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
24/04/04 01:46:28
jp@psique.org http://www.psique.org/cursos
124
Curso J150
A interface Remote:
package org.psique.livraria.ejb;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
import java.util.ArrayList;
public interface Busca extends EJBObject {
public ArrayList search(String palavra) throws
RemoteException;
}
package org.psique.livraria.ejb;
import
import
import
import
java.sql.Connection;
java.sql.ResultSet;
java.sql.SQLException;
java.sql.Statement;
import java.util.ArrayList;
24/04/04 01:46:30
jp@psique.org http://www.psique.org/cursos
125
import
import
import
import
Curso J150
javax.ejb.SessionBean;
javax.ejb.SessionContext;
javax.naming.InitialContext;
javax.sql.DataSource;
126
Curso J150
}
}
return retval;
}
public void ejbCreate() {
}
public void ejbRemove() {
}
public void ejbActivate() {
}
public void ejbPassivate() {
}
public void setSessionContext(SessionContext sc) {
}
}
24/04/04 01:46:33
jp@psique.org http://www.psique.org/cursos
127
Curso J150
package
org.psique.livraria.ejb;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface DetalhesDoLivroHome extends EJBHome {
DetalhesDoLivro create() throws RemoteException,
CreateException;
}
org.psique.livraria.ejb;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface DetalhesDoLivro extends EJBObject {
public String[] getDetalhesDoLivro(String codLivro) throws
RemoteException;
}
128
Curso J150
package
org.psique.livraria.ejb;
import
import
import
import
java.sql.Connection;
java.sql.ResultSet;
java.sql.SQLException;
java.sql.Statement;
import
import
import
import
javax.ejb.SessionBean;
javax.ejb.SessionContext;
javax.naming.InitialContext;
javax.sql.DataSource;
129
Curso J150
preco" +
" FROM Livros" +
" WHERE CodLivro=" + codLivro;
System.out.println("Exec query" + codLivro);
ResultSet rs = statement.executeQuery(sql);
if (rs.next()) {
System.out.println("Localizei");
row = new String[5];
row[0] = rs.getString("codLivro");
row[1] = rs.getString("titulo");
row[2] = rs.getString("autor");
row[3] = rs.getString("editora");
row[4] = rs.getString("preco");
}
rs.close();
statement.close();
con.close();
}
catch (Exception e) {
e.printStackTrace();
if(con!=null)
try {
con.close();
} catch (SQLException e1) {}
}
return row;
}
public void ejbCreate() {
}
public void ejbRemove() {
}
public void ejbActivate() {
}
public void ejbPassivate() {
}
public void setSessionContext(SessionContext sc) {
}
}
24/04/04 01:46:39
jp@psique.org http://www.psique.org/cursos
130
Curso J150
24/04/04 01:46:40
jp@psique.org http://www.psique.org/cursos
131
Curso J150
try {
Context context = new InitialContext();
System.out.println("Peguei o contexto");
Object ref = context.lookup("Busca");
System.out.println("Tenho a referencia");
24/04/04 01:46:42
jp@psique.org http://www.psique.org/cursos
132
Curso J150
24/04/04 01:46:44
jp@psique.org http://www.psique.org/cursos
133
Curso J150
package
org.psique.livraria.ejb;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface CarrinhoHome extends EJBHome {
Carrinho create() throws RemoteException, CreateException;
}
package
org.psique.livraria.ejb;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
import java.util.List;
public interface Carrinho extends EJBObject {
public List getCarrinho() throws RemoteException;
public void addCarrinho(String codLivro, String quantidade)
24/04/04 01:46:46
jp@psique.org http://www.psique.org/cursos
134
Curso J150
throws RemoteException;
}
package org.psique.livraria.ejb;
import java.util.ArrayList;
import java.util.List;
import
import
import
import
javax.ejb.SessionBean;
javax.ejb.SessionContext;
javax.naming.Context;
javax.naming.InitialContext;
/**
* @author jp
*
* 11/04/2004 16:25:12
*
*
*/
public class CarrinhoBean implements SessionBean {
24/04/04 01:46:47
jp@psique.org http://www.psique.org/cursos
135
Curso J150
136
Curso J150
}
public void ejbRemove() {
}
public void ejbActivate() {
}
public void ejbPassivate() {
}
public void setSessionContext(SessionContext sc) {
}
}
24/04/04 01:46:51
jp@psique.org http://www.psique.org/cursos
137
Curso J150
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
<session >
<description><![CDATA[DetalhesDoLivro]]
></description>
<display-name>Detalhes</display-name>
<ejb-name>Detalhes</ejb-name>
<home>org.psique.livraria.ejb.DetalhesDoLivroHome</ho
me>
<remote>org.psique.livraria.ejb.DetalhesDoLivro</remo
te>
<ejbclass>org.psique.livraria.ejb.DetalhesDoLivroBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
<session>
<ejb-name>Carrinho</ejb-name>
<home>org.psique.livraria.ejb.CarrinhoHome</home>
<remote>org.psique.livraria.ejb.Carrinho</remote>
<ejb-class>org.psique.livraria.ejb.CarrinhoBean</ejbclass>
<session-type>Stateful</session-type>
<transaction-type>Bean</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
138
Curso J150
Distribuio no JBoss
Para distribuir no JBoss, basta copiar no diretrio de deploy.
O servlet BuscaServlet
O BuscaServlet exibe a pgina de busca. A pgina de busca a
pgina principal, assim como a primeira pgina que o usurio ver.
A pgina dividida em trs partes:
Formulrio de busca
java.io.IOException;
java.io.PrintWriter;
java.util.List;
java.util.Properties;
import
import
import
import
import
javax.naming.Context;
javax.naming.InitialContext;
javax.rmi.PortableRemoteObject;
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
24/04/04 01:46:54
jp@psique.org http://www.psique.org/cursos
139
Curso J150
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.psique.livraria.ejb.Busca;
import org.psique.livraria.ejb.BuscaHome;
public class BuscaServlet extends HttpServlet {
private String palavra;
/**Processando a requisio HTTP */
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
displayPage(request, response);
}
/**Processando a requisio Post HTTP */
public void doPost(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
palavra = request.getParameter("palavra");
displayPage(request, response);
}
private void displayPage(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
/* Alm do cabealho e do rodap, ,
existem 4 partes nesta pgina:
1. O Ttulo
2. O formulrio de busca
3. A tabela de resultados
4. O link para o Verificar o Carrinho
*/
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// header
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE>Bem-vindo livraria</TITLE>");
24/04/04 01:46:56
jp@psique.org http://www.psique.org/cursos
140
Curso J150
out.println("</HEAD>");
out.println("<BODY>");
out.println("<CENTER>");
// Ttulo
out.println("<H2>Bem vindo livraria</H2>");
// Formulrio de busca
out.println("<BR>");
out.println("<FORM METHOD=POST>");
out.println("Ttulo: <INPUT TYPE=TEXT
NAME=palavra>");
out.println("<INPUT TYPE=SUBMIT VALUE=Busca");
out.println("</FORM>");
out.println("<HR>");
// Resultado da busca
out.println("<BR>");
out.println("<H3>Resultados da Busca</H3>");
out.println("<BR>");
mostrarResultadoDeBusca(out);
out.println("<HR>");
// Link para verificar o carrinho
out.println("<BR>");
out.println(
"<A HREF=\VerificarCarrinhoServlet\>Verificar o carrinho de
compras</A>");
// rodap
out.println("</CENTER>");
out.println("</BODY>");
out.println("</HTML>");
}
// Mostrando o resultado
private void mostrarResultadoDeBusca(PrintWriter out) {
if (palavra != null && !palavra.trim().equals(""))
{
// palavra correta, mostrando o resultado
aqui.
24/04/04 01:46:58
jp@psique.org http://www.psique.org/cursos
141
Curso J150
Busca
a partir do Home
Busca buscaBean = home.create();
List lista = buscaBean.search(palavra);
int n = lista.size();
out.println("<TABLE BORDER=1>");
out.println("<TR>");
out.println("<TH WIDTH=350>Ttulo</TH>");
out.println("<TH WIDTH=150>Autor</TH>");
out.println("<TH
WIDTH=150>Editora</TH>");
out.println("<TH WIDTH=50> </TH>");
out.println("</TR>");
for (int i = 0; i < n; i++) {
String[] s = (String[]) lista.get
(i);
out.println("<TR>");
out.println("<TD>" + s[1] +
"</TD>");
out.println("<TD>" + s[2] +
"</TD>");
out.println("<TD>" + s[3] +
24/04/04 01:46:59
jp@psique.org http://www.psique.org/cursos
142
Curso J150
"</TD>");
out.println(
"<TD><A HREF=\DetalhesDoLivroServlet?codLivro="
+ s[0]
+
"\>Detalhes</A></TD>");
out.println("</TR>");
}
out.println("</TABLE>");
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
}
O servlet DetalhesDoLivroServlet
O servlet DetalhesDoLivroServlet abaixo:
package org.psique.livraria.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import
import
import
import
import
import
import
javax.naming.Context;
javax.naming.InitialContext;
javax.rmi.PortableRemoteObject;
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
import org.psique.livraria.ejb.DetalhesDoLivro;
import org.psique.livraria.ejb.DetalhesDoLivroHome;
24/04/04 01:47:01
jp@psique.org http://www.psique.org/cursos
143
Curso J150
144
Curso J150
detalhesDoLivroBean.getDetalhesDoLivro(codLivro);
out.println("<H3>Detalhes do Livro</H3>");
out.println("<BR>");
out.println("<TABLE BORDER=0>");
out.println("<TR>");
out.println("<TD><B>Ttulo:</B></TD>");
out.println("<TD>" + row[1] + "</TD>");
out.println("</TR>");
out.println("<TR>");
out.println("<TD><B>Autor:</B></TD>");
out.println("<TD>" + row[2] + "</TD>");
out.println("</TR>");
out.println("<TR>");
out.println("<TD><B>Editora:</B></TD>");
out.println("<TD>" + row[3] + "</TD>");
out.println("</TR>");
out.println("<TR>");
out.println("<TD><B>Preco:</B></TD>");
out.println("<TD>$" + row[4] + "</TD>");
out.println("</TR>");
out.println("</TABLE>");
out.println("<BR>");
out.println("<BR>");
out.println("<HR>");
out.println("<BR>");
out.println("<BR>");
out.println("<B>Colocar este livro no
carrinho</B>");
out.println("<BR>");
out.println(
"<FORM METHOD=POST ACTION=\AdicionarNoCarrinhoServlet\>");
out.println(
"<INPUT TYPE=HIDDEN Name=codLivro VALUE=" +
row[0] + ">");
out.println("Quero adquirir ");
out.println(
24/04/04 01:47:05
jp@psique.org http://www.psique.org/cursos
145
Curso J150
} catch (Exception e) {
System.out.println(e.toString());
}
out.println("</CENTER>");
out.println("</BODY>");
out.println("</HTML>");
}
}
O servlet adicionarNoCarrinhoServlet
O session bean carrinho .
package org.psique.livraria.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import
import
import
import
import
import
import
import
javax.naming.Context;
javax.naming.InitialContext;
javax.rmi.PortableRemoteObject;
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;
import org.psique.livraria.ejb.Carrinho;
import org.psique.livraria.ejb.CarrinhoHome;
public class AdicionarNoCarrinhoServlet extends HttpServlet {
/**Processar a requisio Post http*/
public void doPost(
24/04/04 01:47:06
jp@psique.org http://www.psique.org/cursos
146
Curso J150
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// cabecalho
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE>Adicionar no
Carrinho</TITLE>");
out.println("</HEAD>");
out.println("<BODY>");
out.println("<CENTER>");
String codLivro = request.getParameter("codLivro");
String quantidade = request.getParameter
("quantidade");
if (codLivro != null
&& quantidade != null
&& !codLivro.trim().equals("")
&& !quantidade.trim().equals("")) {
try {
HttpSession session =
request.getSession(true);
Carrinho carrinho =
(Carrinho) session.getAttribute
("carrinho");
if (carrinho == null) { // uma sesso
nova
Properties properties = new
Properties();
properties.put(
Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory"
);
properties.put(Context.PROVIDER_URL,
"localhost:1099");
// Pegando o contexto
Context jndiContext = new InitialContext
(properties);
// Pegar a referencia ao Bean
Object ref = jndiContext.lookup
24/04/04 01:47:08
jp@psique.org http://www.psique.org/cursos
147
Curso J150
("Carrinho");
CarrinhoHome home =
(CarrinhoHome)
PortableRemoteObject.narrow(
ref,
CarrinhoHome.class);
// Criando o bean!!!
carrinho = home.create();
}
carrinho.addCarrinho(codLivro,
quantidade);
session.setAttribute("carrinho",
carrinho);
out.println(
"<B>O livro foi adicionado no carrinho</B>");
} catch (Exception e) {
out.println(e.toString());
}
}
out.println("<BR>");
out.println("<BR>");
out.println(
"<A HREF=\BuscaServlet\>"
+ "Voltar para a pagina de busca</A>");
out.println("</CENTER>");
out.println("</BODY>");
out.println("</HTML>");
}
}
O servlet VerificarCarrinhoServlet
package org.psique.livraria.servlet;
24/04/04 01:47:10
jp@psique.org http://www.psique.org/cursos
148
Curso J150
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import
import
import
import
import
javax.servlet.ServletException;
javax.servlet.http.HttpServlet;
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
javax.servlet.http.HttpSession;
import org.psique.livraria.ejb.Carrinho;
public class VerificarCarrinhoServlet extends HttpServlet {
/**Processar os request GET HTTP
*/
24/04/04 01:47:12
jp@psique.org http://www.psique.org/cursos
149
Curso J150
"<A HREF=\"BuscaServlet\">" +
"Voltar pgina de busca</A>");
out.println("</CENTER>");
out.println("</BODY>");
out.println("</HTML>");
}
}
24/04/04 01:47:14
jp@psique.org http://www.psique.org/cursos
150
Curso J150
24/04/04 01:47:15
jp@psique.org http://www.psique.org/cursos
151
Curso J150
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AdicionarNoCarrinhoServlet</servlet-name>
<url-pattern>/AdicionarNoCarrinhoServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>BuscaServlet</servlet-name>
<url-pattern>/BuscaServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>BuscaServlet</servlet-name>
<url-pattern>/index.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>DetalhesDoLivroServlet</servlet-name>
<url-pattern>/DetalhesDoLivroServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>VerificarCarrinhoServlet</servlet-name>
<url-pattern>/VerificarCarrinhoServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
24/04/04 01:47:17
jp@psique.org http://www.psique.org/cursos
152
Curso J150
"http://java.sun.com/dtd/application_1_3.dtd">
<application id="livraria">
<display-name>Livraria</display-name>
<module>
<ejb>livraria-EJB.jar</ejb>
</module>
<module>
<web>
<web-uri>livraria-WAR.war</web-uri>
<context-root>/livraria</context-root>
</web>
</module>
</application>
24/04/04 01:47:19
jp@psique.org http://www.psique.org/cursos
153
Curso J150
Entity Beans
Armazenagem de dados
Um dos problemas computacionais mais comuns armazenar dados
de forma persistente e recuperar estes dados. A serializao pode
ser uma forma interessante de armazenar objetos java o principal
problema da serializao a recuperao. Imagine que nossa
empresa tem 20.000.000 de clientes, cada cliente um objeto
serializado no disco. Se voc precisar recuperar todos os clientes
que fazem aniversrio no dia, voc ter que ler todos os 20.000.000,
ou seja, desserializ-los criando o objeto e testando se o dia e o ms
da data de nascimento tem o valor que interessa. Como pode notar,
a serializao no interessante quando os volumes de dados so
grandes.
Outra soluo poderia ser a utilizao de um banco de dados que
suporte objetos, utilizando um banco orientado a objetos isto pode
ser feito de maneira mais eficaz, mas a tecnologia de bancos de
dados orientados a objetos ainda no est madura.
A terceira opo utilizar um bom e velho banco de dados
relacional para armazenagem dos dados. Neste caso, precisamos
fazer um mapeamento dos dados que esto em forma de objetos
para a forma tabular utilizada pelo banco de dados relacional. Este
mapeamento objeto-relacional pode ser feito manualmente ou podese utilizar uma forma automtica de fazer isto. Existem vrias
solues de persistncia para isto tais como Hybernate, OJB, JDO, e
a que veremos adiante Entity Bean CMP.
24/04/04 01:47:20
jp@psique.org http://www.psique.org/cursos
154
Entity Beans
Curso J150
155
Entity Beans
Curso J150
156
Entity Beans
Curso J150
A interface remote
A interface home
O Entity Bean
A interface remote
A interface remote de um entity permite a um cliente acessar a
cpia de um entity bean. A interface remota de um entity precisa
estender a interface javax.ejb.EJBObject. Na interface remota, o
desenvolvedor de interface remote define mtodos que podem ser
chamados pelo cliente do bean. Por exemplo, a interface remote de
um entity que representa um produto pode ter dois mtodos,
chamados getPreco e getCategoria, como abaixo:
24/04/04 01:47:25
jp@psique.org http://www.psique.org/cursos
157
Entity Beans
Curso J150
A interface HOME
Um cliente do entity bean obtm o objeto home - isto , uma cpia
da interface home - de um objeto remote do entity bean. O cliente
usa o objeto home para fazer o seguinte:
- Criar um objeto entity
- Remover um objeto entity
- Encontrar um objeto entity
- Obter a interface javax.ejb.EJBMetaData para um entity bean
A interface home permite ao cliente realizar essas tarefas,
fornecendo os mtodos create, finders e remove.
24/04/04 01:47:27
jp@psique.org http://www.psique.org/cursos
158
Entity Beans
Curso J150
Mtodo create
Uma interface home pode ter zero ou mais mtodos create. A
interface home pode ter mais do que um mtodo create, para
possibilitar a criao de objetos entity de diversas formas. Por
exemplo, a seguir est o mtodo create da interface home, de um
entity bean chamado produto. O nome do produto, a descrio e o
preo.
Mtodos finder
Um entity bean representa uma pea de dados e uma das operaes
comuns com dados a recuperao. Para localizar um entity bean,
utilizamos os mtodos finder. mtodos finder so exclusivos de
entity beans, um session bean no tem mtodo finder.
24/04/04 01:47:28
jp@psique.org http://www.psique.org/cursos
159
Entity Beans
Curso J150
24/04/04 01:47:31
jp@psique.org http://www.psique.org/cursos
160
Entity Beans
Curso J150
Mtodos Remove
Um mtodo remove usado para remover um objeto entity. A
interface home de um entity bean derivada da interface
javax.ejb.EJBHome, que define dois mtodos remove. As assinaturas
dos dois mtodos remove so:
Um entity bean
Uma classe de entity bean precisa implementar a interface
javax.ejb.EntityBean. Essa interface define mtodos que
24/04/04 01:47:33
jp@psique.org http://www.psique.org/cursos
161
Entity Beans
Curso J150
A interface javax.ejb.EntityBean
Essa interface estende a interface javax.ejb.EnterpriseBean e
oferece mtodos de retorno de chamada que so convocados pelo
continer EJB. Os mtodos da interface EntityBean so como a
seguir:
ejbActivate: O continer EJB chama esse mtodo quando a cpia do
entity bean recuperada do pool para se tornar associada a um
objeto entity especfico
public void ejbActivate() throws
javax.ejb.EJBException, java.rmi.RemoteException
162
Entity Beans
Curso J150
Nota
O continer EJB mantm a sincronia entre dados em campos de um
entity Bean e o banco de dados usando os mtodos ejbLoad e
ejbStore de javax.ejb.EntityBean.
Graas sincronia durante as chamadas aos mtodos ejbLoad e
ejbStore, se os dados com os quais um entity bean est associado
tiverem mudado diretamente no banco de dados o estado do entity
no ser afetado.
24/04/04 01:47:38
jp@psique.org http://www.psique.org/cursos
163
Entity Beans
Curso J150
Activation e Passivation
Da mesma forma que um session bean com estado, um entity bean
tambm pode realizar os processos de ativao e passivao. Porm,
esses processos so mais envolvidos em um session bean com
estado. Com em um session bean com estado, a ativao inclui a
restaurao do estado anterior a recursos para determinado cliente,
e a passivao exige que o bean libere os recursos que esto sendo
retidos e salve o estado com a posio de conversao de um cliente
em uma armazenagem secundria.
Como o continer decide quais beans ativar e quais beans passivar?
A resposta especfica para cada continer. A maior dos continers
utiliza a estratgia LRU (Least Recently Used), que simplesmente
significa passivar o bean que foi chamado menos recentemente. A
passivao pode ocorrer a qualquer tempo, a exceo regra que
qualquer bean envolvido em uma transao no pode ser passivado
at que a transao se complete.
Em um entity bean, a passivao inclui liberar recursos, assim como
salvar os dados de volta no banco de dados. Para salvar a posio de
um entity bean, o continer EJB chama o mtodo ejbStore do bean,
antes da passivao. A ativao em um entity bean, por outro lado,
inclui a recuperao do estado, para isto o continer chama o
mtodo ejbLoad do entity depois da ativao.
Tudo que considerado parte do estado conversacional do bean
salvo (serializado) na passivao. O estado conversacional refere-se
a:
24/04/04 01:47:39
jp@psique.org http://www.psique.org/cursos
164
Entity Beans
Curso J150
24/04/04 01:47:41
jp@psique.org http://www.psique.org/cursos
165
Entity Beans
Curso J150
package org.psique.produto.ejb;
import java.rmi.RemoteException;
import javax.ejb.EJBException;
import javax.ejb.EntityContext;
import javax.ejb.RemoveException;
public class ProdutoBean implements javax.ejb.EntityBean {
public String codProduto;
public String nomeProduto;
public String descricao;
public double preco;
public String ejbCreate(
int codProduto,
String nomeProduto,
String descricao,
24/04/04 01:47:43
jp@psique.org http://www.psique.org/cursos
166
Entity Beans
Curso J150
double preco)
throws java.rmi.RemoteException,
javax.ejb.CreateException {
this.codProduto = Integer.toString(codProduto);
this.nomeProduto = nomeProduto;
this.descricao = descricao;
this.preco = preco;
return Integer.toString(codProduto);
}
public void ejbActivate() throws EJBException,
RemoteException {
}
public void ejbLoad() throws EJBException,
RemoteException {
}
public void ejbPassivate() throws EJBException,
RemoteException {
}
public void ejbRemove()
throws RemoveException, EJBException,
RemoteException {
}
public void ejbStore() throws EJBException,
RemoteException {
}
public void setEntityContext(EntityContext arg0)
throws EJBException, RemoteException {
}
public void unsetEntityContext() throws EJBException,
RemoteException {
}
}
24/04/04 01:47:45
jp@psique.org http://www.psique.org/cursos
167
Entity Beans
Curso J150
Encontrando um Entity
A classe entity bean precisa ter um mtodo finder correspondente
de todos os mtodos finder na interface home. Exatamente como os
mtodos create, um mtodo finder em uma classe entity bean
prefixado com ejb e tem a mesma lista de argumentos que o mtodo
finder correspondente na interface home.
Por exemplo, uma classe entity bean pode conter dois mtodos
finder: ejbFindByPrimaryKey e ejbfindByNome, como voc v aqui:
Removendo um Entity
Uma classe entity bean deve definir um mtodo ejbRemove().
24/04/04 01:47:47
jp@psique.org http://www.psique.org/cursos
168
Entity Beans
Curso J150
Reforando...
Um entity bean uma vista de uma pea e dados em um banco de
dados. Portanto, chamar os mtodos ejbCreate e ejbRemove causa
efeitos em um entity bean diferentes dos de um session bean.
Quando o continer EJB chama o mtodo ejbCreate de um entity
bean, ele cria alguns dados que corresponde cpia do entity bean
na memria. Quando o continer EJB chama o mtodo ejbRemove
de um entity bean, o continer EJB tambm apaga os dados
associados ao entity bean do banco de dados.
24/04/04 01:47:48
jp@psique.org http://www.psique.org/cursos
169
Entity Beans
Curso J150
Outros mtodos
O entity bean oferece implementaes para mtodos declarados na
interface remote. Os mtodos na classe entity bean precisam ter o
mesmo tipo de retorno e lista de argumentos que o mtodo
correspondente na interface remote. Esses mtodos precisam ser
mtodos pblicos e no podem ser estticos. Por exemplo, considere
a seguinte interface remote:
170
Entity Beans
Curso J150
A interface javax.ejb.EntityContext
Todos os EJBs tem um contexto do objeto, que identifica o ambiente
do bean. Este objeto contm informaes ambientais que o
continer EJB configura. Seus beans podem acessar o contexto para
recuperar estas informaes, tais como informaes sobre
transaes e segurana.
Para os entity beans a interface para os dados do contexto
javax.ejb.EntityContext. A interface EntityContext derivada da
interface javax.ejb.EJBContext. Ela define alguns mtodos, entre
eles: getEJBObject/getEJBLocalObject (da interface
javax.ejb.EJBContext) e getPrimaryKey (da interface
javax.ejb.EntityContext).
O mtodo getEJBObject() ou getEJBLocalObject() retorna uma
referncia ao objeto enterprise associado a essa cpia de entity
bean.
javax.ejb.EJBObject getEJBObject()
throws IllegalStateException
24/04/04 01:47:52
jp@psique.org http://www.psique.org/cursos
171
Entity Beans
Curso J150
Este mtodo recupera a chave primria que est associada com esta
instncia de entity bean. A chave primria identifica unicamente um
bean na camada de persistncia, a chave primria pode ser utilizada
para recuperar um entity bean porque no existiro dois beans com
a mesma chave primria.
Para que utilizar getPrimaryKey? Voc pode chamar este mtodo
sempre que quizer saber com que dados do banco de dados sua
instncia est associada.
24/04/04 01:47:53
jp@psique.org http://www.psique.org/cursos
172
Entity Beans
Curso J150
173
Curso J150
A interface EntityBean:
public interface javax.ejb.EntityBean
extends javax.ejb.EnterpriseBean {
public void setEntityContext(javax.ejb.EntityContext);
public void unsetEntityContext();
public void ejbRemove();
public void ejbActivate();
public void ejbPassivate();
public void ejbLoad();
public void ejbStore();
}
Alm dos mtodos acima que voc deve implementar na sua classe
EntityBean, voc deve ter mtodos create e find.
Eis a lista de coisas que precisamos para criar um Entity BMP:
1 Criao da tabela produto
CREATE TABLE Produto
{
codProduto int primary key,
nomeProduto varchar(50),
descricao varchar(100),
preco double
}
24/04/04 01:47:57
jp@psique.org http://www.psique.org/cursos
174
Curso J150
A interface remote
A primeira classe a explorar a interface remote para o entity bean
Produto com BMP. O arquivo chamado Produto.java:
24/04/04 01:47:58
jp@psique.org http://www.psique.org/cursos
175
Curso J150
Produto.java
package org.psique.produto.ejb;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
/* esta interface remote para o Produto */
public interface Produto extends EJBObject {
public int getCodProduto() throws RemoteException;
public double getPreco() throws RemoteException;
public String getNomeProduto() throws RemoteException;
public String getDescricao() throws RemoteException;
}
A interface Home
A interface home define um mtodo create que aceita quatro
argumentos e dois mtodos finder. O mtodo findByPrimaryKey
aceita um objeto primary key e retorna um objeto remote. O mtodo
findByNome aceita um nome de produto e retorna uma
Enumeration contendo todos os produtos cujos nomes combinam
com o argumento. comum incluir-se na interface home os home
mthods que so mtodos de negcio que no esto relacionados
com nenhuma instncia de Entity em particular.
ProdutoHome.java
24/04/04 01:48:00
jp@psique.org http://www.psique.org/cursos
176
Curso J150
package org.psique.produto.ejb;
import
import
import
import
java.rmi.RemoteException;
javax.ejb.FinderException;
javax.ejb.CreateException;
javax.ejb.EJBHome;
import java.util.Collection;
public interface ProdutoHome extends EJBHome {
public Produto create(int productId, String productName,
String description, double price)
throws RemoteException, CreateException;
public Produto findByPrimaryKey(ProdutoPK key)
throws RemoteException, FinderException;
public Collection findByNome(String name)
throws RemoteException, FinderException;
}
package org.psique.produto.ejb;
import java.io.Serializable;
public class ProdutoPK implements Serializable {
public String codProduto;
public ProdutoPK(String codProduto) {
this.codProduto = codProduto;
}
24/04/04 01:48:02
jp@psique.org http://www.psique.org/cursos
177
Curso J150
public ProdutoPK() {}
public boolean equals(Object obj ) {
return codProduto.equals(((ProdutoPK)obj).codProduto);
}
public int hashCode() {
return codProduto.hashCode();
}
}
O entity bean
A classe entity bean a classe mais importante que contm
implementaes para os mtodos de retorno de chamada e mtodos
de negcio.
ProdutoBean.java
package org.psique.produto.ejb;
import
import
import
import
import
import
import
import
import
java.rmi.RemoteException;
java.sql.Connection;
java.sql.DriverManager;
java.sql.PreparedStatement;
java.sql.ResultSet;
java.sql.SQLException;
java.util.ArrayList;
java.util.Collection;
java.util.List;
import javax.ejb.CreateException;
import javax.ejb.EntityBean;
24/04/04 01:48:03
jp@psique.org http://www.psique.org/cursos
178
import
import
import
import
import
import
Curso J150
javax.ejb.EntityContext;
javax.ejb.FinderException;
javax.ejb.ObjectNotFoundException;
javax.naming.Context;
javax.naming.InitialContext;
javax.naming.NamingException;
/**
* Geter para o cdigo do produto
*
* @return
*/
public int getCodProduto() {
System.out.println("getCodProduto");
return codProduto;
}
/**
* Geter para o Nome do Produto
*
* @return
*/
public String getNomeProduto() {
System.out.println("getNomeProduto");
return nomeProduto;
}
/**
* Geter para a descrioo do produto
*
* @return
*/
public String getDescricao() {
24/04/04 01:48:05
jp@psique.org http://www.psique.org/cursos
179
Curso J150
System.out.println("getDescricao");
return descricao;
}
/**
* Geter para o preo
*
* @return
*/
public double getPreco() {
System.out.println("getPreco");
return preco;
}
/**
*
* Cria um novo entity, devolve a chave primria
* do entity criado.
*
* @param codProduto
* @param nomeProduto
* @param descricao
* @param preco
* @return
* @throws RemoteException
* @throws CreateException
*/
public ProdutoPK ejbCreate(
int codProduto,
String nomeProduto,
String descricao,
double preco)
throws RemoteException, CreateException {
System.out.println("ejbCreate");
this.codProduto = codProduto;
this.nomeProduto = nomeProduto;
this.descricao = descricao;
this.preco = preco;
Connection con = null;
PreparedStatement ps = null;
try {
String sql =
"INSERT INTO Produto"
24/04/04 01:48:07
jp@psique.org http://www.psique.org/cursos
180
Curso J150
/**
*
* Executado logo aps o create
*
* Deve existir um ejbPostCreate para cada
* ejbCreate existente (mesma assinatura)
*
* @param productId
* @param productName
* @param descricao
* @param preco
* @throws RemoteException
* @throws CreateException
24/04/04 01:48:09
jp@psique.org http://www.psique.org/cursos
181
Curso J150
*/
public void ejbPostCreate(
int productId,
String productName,
String descricao,
double preco)
throws RemoteException, CreateException {
System.out.println("ejbPostCreate");
}
/**
* @param primaryKey
* @return
* @throws RemoteException
* @throws FinderException
*/
/**
*
* Mtodo para localizaoo pela chave primria
* obrigatria a existncia!
*
* @param primaryKey
* @return
* @throws RemoteException
* @throws FinderException
*/
public ProdutoPK
ejbFindByPrimaryKey(ProdutoPK primaryKey)
throws RemoteException, FinderException {
System.out.println("ejbFindByPrimaryKey");
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql =
"SELECT nomeProduto" +
" FROM Produto" +
" WHERE codProduto=?";
int productId =
Integer.parseInt(primaryKey.codProduto);
con = getConnection();
ps = con.prepareStatement(sql);
ps.setInt(1, productId);
rs = ps.executeQuery();
24/04/04 01:48:10
jp@psique.org http://www.psique.org/cursos
182
Curso J150
if (rs.next()) {
rs.close();
ps.close();
con.close();
return primaryKey;
}
} catch (SQLException e) {
System.out.println(e.toString());
} finally {
try {
if (rs != null)
rs.close();
if (ps != null)
ps.close();
if (con != null)
con.close();
} catch (SQLException e) { }
}
throw new ObjectNotFoundException();
}
/**
* Mtodo para procurar por nome
*
* @param name
* @return
* @throws RemoteException
* @throws FinderException
*/
public Collection ejbFindByNome(String nome)
throws RemoteException, FinderException {
System.out.println("ejbFindByNome");
List produtos = new ArrayList();
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql =
"SELECT codProduto " +
" FROM Produto" +
24/04/04 01:48:12
jp@psique.org http://www.psique.org/cursos
183
Curso J150
184
Curso J150
ps = con.prepareStatement(sql);
ps.setInt(1, codProduto);
ps.executeUpdate();
} catch (SQLException e) {
System.out.println(e.toString());
} finally {
try {
if (ps != null)
ps.close();
if (con != null)
con.close();
} catch (SQLException e) { }
}
}
public void ejbActivate() {
System.out.println("ejbActivate");
}
public void ejbPassivate() {
System.out.println("ejbPassivate");
}
/*
* @see javax.ejb.EntityBean#ejbLoad()
*/
public void ejbLoad() {
System.out.println("ejbLoad");
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql =
"SELECT nomeProduto, descricao, preco"
+ " FROM produto"
+ " WHERE codProduto=?";
con = getConnection();
ps = con.prepareStatement(sql);
ps.setInt(1, this.codProduto);
rs = ps.executeQuery();
if (rs.next()) {
this.nomeProduto = rs.getString(1);
this.descricao = rs.getString(2);
this.preco = rs.getDouble(3);
24/04/04 01:48:16
jp@psique.org http://www.psique.org/cursos
185
Curso J150
}
} catch (SQLException e) {
System.out.println(e.toString());
} finally {
try {
if (rs != null)
rs.close();
if (ps != null)
ps.close();
if (con != null)
con.close();
} catch (SQLException e) {
}
}
}
public void ejbStore() {
System.out.println("ejbStore");
Connection con = null;
PreparedStatement ps = null;
try {
String sql =
"UPDATE Produto" +
" SET nomeProduto=?, descricao=?, preco=?" +
" WHERE codProduto=?";
ProdutoPK chave =
(ProdutoPK) contexto.getPrimaryKey();
int codProduto =
Integer.parseInt(chave.codProduto);
con = getConnection();
ps = con.prepareStatement(sql);
ps.setString(1, this.nomeProduto);
ps.setString(2, this.descricao);
ps.setDouble(3, this.preco);
ps.setInt(4, codProduto);
ps.executeUpdate();
} catch (SQLException e) {
System.out.println(e.toString());
24/04/04 01:48:18
jp@psique.org http://www.psique.org/cursos
186
Curso J150
} finally {
try {
if (ps != null)
ps.close();
if (con != null)
con.close();
} catch (SQLException e) {
}
}
}
public void setEntityContext(EntityContext contexto) {
System.out.println("setEntityContext");
// Guarda uma referncia para o contexto
// para uso posterior.
this.contexto = contexto;
}
public void unsetEntityContext() {
System.out.println("unsetEntityContext");
contexto = null;
}
public Connection getConnection() {
String dbUrl = null;
String userName = null;
String password = null;
Context initialContext;
Context environment;
Connection connection = null;
try {
initialContext = new InitialContext();
environment =
(Context) initialContext.lookup("java:comp/env/jdbc");
dbUrl = (String) environment.lookup("dbUrl");
userName =
(String) environment.lookup("dbUserName");
password =
(String) environment.lookup("dbPassword");
24/04/04 01:48:19
jp@psique.org http://www.psique.org/cursos
187
Curso J150
} catch (NamingException e) {
System.out.println(e.toString());
}
try {
connection =
DriverManager.getConnection(dbUrl,
userName,
password);
} catch (SQLException e) {
System.out.println(e.toString());
}
return connection;
}
}
188
Curso J150
189
Curso J150
public ProdutoPK
ejbCreate(
int codProduto,
String nomeProduto,
String descricao ,
double preco)
throws RemoteException, CreateException {
24/04/04 01:48:25
jp@psique.org http://www.psique.org/cursos
190
Curso J150
if(ps!=null)
ps.close();
if(con!=null)
con.close();
} catch(SQLException e) {}
}
191
Curso J150
String sql =
SELECT codProduto FROM PRODUTO WHERE codProduto=?;
192
Curso J150
Descritor de distribuio
Cada aplicativo EJB precisa ser acompanhado de um deployment
descriptor que deve ser salvo no diretrio META-INF do projeto, em
um arquivo chamado ejb-jar.xml.
193
Curso J150
24/04/04 01:48:31
jp@psique.org http://www.psique.org/cursos
194
Curso J150
Aplicativo Cliente
Tendo um entity bean instalado no servidor, voc pode escrever um
aplicativo cliente para testar o bean:
BeanClienteBMP.java
package org.psique.produto.cliente;
import java.util.Collection;
import java.util.Iterator;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import org.psique.produto.ejb.Produto;
import org.psique.produto.ejb.ProdutoHome;
24/04/04 01:48:33
jp@psique.org http://www.psique.org/cursos
195
Curso J150
196
Curso J150
System.out.println(
"Criando Barra de Chocolate");
home.create(
getChave(),
"Barra de Chocolate",
"Chocolate Bar 200g",
2.95);
System.out.println("Criando Biscoito");
home.create(
getChave(),
"Biscoito",
"Biscoito com menta, 300g",
9.25);
System.out.println("Criando Coca-cola");
Produto codProduto =
home.create(getChave(),
"Coca-cola",
"Coca-cola 600ml",
1.05);
codProduto.remove();
System.out.println(
"Agua mineral... procurando ");
Collection colecao =
(Collection) home.findByNome(
"gua mineral");
Iterator iterator = colecao.iterator();
while (iterator.hasNext()) {
codProduto = (Produto) iterator.next();
System.out.println("Cdigo: " +
codProduto.getCodProduto());
System.out.println(
"Nome do Produto: " +
codProduto.getNomeProduto());
System.out.println("Descrio: " +
codProduto.getDescricao());
System.out.println("Preco: " +
codProduto.getPreco());
24/04/04 01:48:37
jp@psique.org http://www.psique.org/cursos
197
Curso J150
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
public static int getChave() {
return (int) (Math.random() * Integer.MAX_VALUE);
}
}
24/04/04 01:48:39
jp@psique.org http://www.psique.org/cursos
198
Curso J150
findByPrimaryKey
findAll
findBy<campo>(<tipo-campo> valor)
24/04/04 01:48:40
jp@psique.org http://www.psique.org/cursos
199
Curso J150
24/04/04 01:48:42
jp@psique.org http://www.psique.org/cursos
200
Curso J150
Ex.:
ejb-jar.xml
...
<cmp-version>2.x</cmp-version>
<abstract-schema-name>ContaBean</abstract-schema-name>
<cmp-field>
<field-name>codConta</field-name>
</cmp-field>
<cmp-field>
<field-name>nome</field-name>
</cmp-field>
<cmp-field>
<field-name>saldo</field-name>
</cmp-field>
<primkey-field>codConta</primkey-field>
...
A tag cmp-version precisa ser 2.x para voc utilizar EJB 2.0 CMP.
As especificaes EJB 1.1 e 1.0 tem vrias lacunas em relao
2.x.
24/04/04 01:48:44
jp@psique.org http://www.psique.org/cursos
201
Curso J150
...
public abstract double ejbSelectAllSaldos() throws FinderException;
public double ejbHomeGetGetSaldoTotalDoBanco() throws Exception {
Collection c = this.ejbSelectAllSaldos();
Iterator i = c.iterator();
double soma = 0;
while(i.hasNext()) {
Conta c = (Conta)(i.next());
soma += c.getSaldo();
}
return soma;
}
...
24/04/04 01:48:45
jp@psique.org http://www.psique.org/cursos
202
Curso J150
CMP
BMP
Concreta
Acesso a banco de
dados
Geradas por
ferramentas
Codificada por
desenvolvedor
Estado de
persistncia
Representado por
campos persistentes
virtuais.
Codificado como
variveis de instncias
Acesso a todos
Obrigatrio
para persistncia e
campos de
relacionamento
Nenhum
Mtodo
findByPrimaryKey
Controlado pelo
continer
Codificado pelo
desenvolvedor
Mtodos finders
customizados
Controlado pelo
continer mas o
desenvolvedor pode
definir queries em
EJB QL
Codificado pelo
desenvolvedor
Mtodos select
Controlado pelo
continer
nenhum
Retorno do
ejbCreate
A interface remote
A interface remote do bean ProdutoCMP semelhante
ProdutoBMP:
ProdutoCMP.java
24/04/04 01:48:47
jp@psique.org http://www.psique.org/cursos
203
Curso J150
package org.psique.produto.ejb;
/**
* Interface Remota para ProdutoCMP.
*/
public interface ProdutoCMP
extends javax.ejb.EJBObject
{
public String getCodProduto() throws
java.rmi.RemoteException;
public void setCodProduto(String cod) throws
java.rmi.RemoteException;
public String getNomeProduto() throws
java.rmi.RemoteException;
public void setNomeProduto(String nome) throws
java.rmi.RemoteException;
public String getDescricao() throws
java.rmi.RemoteException;
public void setDescricao(String descricao) throws
java.rmi.RemoteException;
public double getPreco() throws
java.rmi.RemoteException;
public void setPreco(double preco) throws
java.rmi.RemoteException;
A interface home
A interface home define um mtodo create e dois finders.
ProdutoCMP.java
package org.psique.produto.ejb;
import java.util.Collection;
import org.psique.produto.ejb.ProdutoCMP;
24/04/04 01:48:49
jp@psique.org http://www.psique.org/cursos
204
Curso J150
/**
* Interface Home para ProdutoCMP.
*/
public interface ProdutoCMPHome
extends javax.ejb.EJBHome
{
// Nome ENC
public static final String
COMP_NAME="java:comp/env/ejb/ProdutoCMP";
// Nome Global
public static final String JNDI_NAME="ProdutoCMP";
public org.psique.produto.ejb.ProdutoCMP
create(int codProduto ,
java.lang.String nomeProduto ,
java.lang.String descricao ,
double preco)
throws javax.ejb.CreateException,
java.rmi.RemoteException;
public ProdutoCMP findByPrimaryKey(java.lang.String pk)
throws
javax.ejb.FinderException,
java.rmi.RemoteException;
public Collection findByNomeProduto(java.lang.String nome)
throws
javax.ejb.FinderException,
java.rmi.RemoteException;
}
24/04/04 01:48:50
jp@psique.org http://www.psique.org/cursos
205
Curso J150
ProdutoCMPBean.java
package org.psique.produto.ejb;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
public abstract class ProdutoCMPBean implements EntityBean {
EntityContext contexto;
public
public
public
public
String
String
String
double
codProduto;
nomeProduto;
descricao;
preco;
/**
*
* EM CMP,
* os mtodos acessores so ABSTRATOS
*
*/
public abstract String getCodProduto();
public abstract void setCodProduto(String cod);
public abstract String getNomeProduto();
public abstract void setNomeProduto(String nome);
public abstract String getDescricao();
public abstract void setDescricao(String descricao);
public abstract double getPreco();
public abstract void setPreco(double preco);
/**
* O create s se preocupa em abastecer as variveis
* de instncia utilizando-se dos getters e setters
* no necessria a criao no banco. O continer
* cuidar disto para ns.
24/04/04 01:48:52
jp@psique.org http://www.psique.org/cursos
206
Curso J150
*
* @param codProduto
* @param nomeProduto
* @param descricao
* @param preco
* @return
* @throws RemoteException
* @throws CreateException
*
*/
public String ejbCreate(
int codProduto,
String nomeProduto,
String descricao,
double preco)
throws RemoteException, CreateException {
System.out.println("ejbCreate");
setCodProduto(Integer.toString(codProduto));
setNomeProduto(nomeProduto);
setDescricao(descricao);
setPreco(preco);
return null;
}
/**
* Deve existir um ejbPostCreate para cada ejbCreate
* (com a mesma assinatura)
*
*
*
*/
public void ejbPostCreate(
int codProduto,
String nomeProduto,
String descricao,
double preco)
throws RemoteException, CreateException {
System.out.println("ejbPostCreate");
}
/**
* @throws RemoteException
*
*
24/04/04 01:48:54
jp@psique.org http://www.psique.org/cursos
207
Curso J150
*/
public void ejbRemove() throws RemoteException {
System.out.println("ejbRemove");
}
public
public
public
public
void
void
void
void
ejbActivate() {}
ejbPassivate() {}
ejbLoad() {}
ejbStore() {}
24/04/04 01:48:56
jp@psique.org http://www.psique.org/cursos
208
Curso J150
O deployment descriptor
209
Curso J150
</method-name>
<method-params>
<method-param>
java.lang.String
</method-param>
</method-params>
</query-method>
<ejb-ql><![CDATA[
SELECT OBJECT(PROD) FROM PRODUTOSCHEMA AS PROD
WHERE PROD.nomeProduto = ?1
]]></ejb-ql>
</query>
</entity>
</enterprise-beans>
</ejb-jar>
24/04/04 01:48:59
jp@psique.org http://www.psique.org/cursos
210
Curso J150
package org.psique.produto.cliente;
import java.util.Collection;
import java.util.Iterator;
24/04/04 01:49:01
jp@psique.org http://www.psique.org/cursos
211
Curso J150
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import org.psique.produto.ejb.ProdutoCMP;
import org.psique.produto.ejb.ProdutoCMPHome;
212
Curso J150
"600ml",
3.25);
System.out.println("Criando Barra de Chocolate");
home.create(chaveAleatoria(),
"Barra de Chocolate",
"Chocolate Bar 200g",
2.95);
System.out.println("Criando coca-cola");
produto =
home.create(25,
"Coca-cola",
"Coca-cola 600ml",
1.05);
System.out.println("Removendo coca-cola");
produto.remove();
24/04/04 01:49:04
jp@psique.org http://www.psique.org/cursos
213
Curso J150
24/04/04 01:49:06
jp@psique.org http://www.psique.org/cursos
214
Curso J150
A linguagem de consulta
EJB EJB-QL
Existem dois tipos de entity beans, CMP e BMP. CMP pode ser mais
simples que BMP, mas BMP oferece maior flexibilidade.
Embora a persistncia automtica pelo continer seja um bom
recurso de entitys CMP, os entitys BMP as vezes so preferidos em
funo da flexibilidade pois permitiriam a criao de finders
complexos.
Esta flexibilidade no est presente no entity CMP porque voc no
implementa os finders, voc fica dependente dos finders do
continer EJB. Que para o JBoss so: findByPrimaryKey, findAll, e
findBy<campo>.
Para contornar essa limitao de entity beans CMP, EJB 2.0
especifica uma linguagem chamada: Enterprise JavaBeans Query
Language (SQL), que os desenvolvedores de um bean podem usar
para selecionar dados para mtodos finder de entitys CMP. Para
otimizao de desempenho, a EJB QL pode ser compilada para uma
linguagem alvo do banco de dados ou outra armazenagem
persistente, exatamente como voc cria um procedimento
armazenado que encapsula a sua declarao SQL para agilizar a
execuo de sua declarao SQL.
As consultas EJB QL podem ser usadas de duas formas:
24/04/04 01:49:08
jp@psique.org http://www.psique.org/cursos
215
Curso J150
216
Curso J150
A clusula SELECT
A clusula SELECT especifica a sada da consulta EJB QL. Ela pode
conter um dos seguintes:
24/04/04 01:49:12
jp@psique.org http://www.psique.org/cursos
217
Curso J150
24/04/04 01:49:14
jp@psique.org http://www.psique.org/cursos
218
Curso J150
A clusula FROM
A clusula FROM define o domnio da consulta, declarando variveis
de identificao. O domnio da consulta pode ser restrito pelas
expresses de caminho. A clusula FROM pode conter mltiplas
variveis de identificao, separadas por uma vrgula. Ela tem a
seguinte sintaxe:
FROM identification_variable_declaration
[,identification_variable_declaration] *
Nessa clusula, o asterisco denota que o valor entre chaves que ele
segue pode ser repetido zero ou mais vezes. Alm do mais, a
identification_variable_declaration definida como a seguir:
identification_varible_declaration::=
collection_member_declaration | range_variable_declaration
collection_member_declaration::= IN
(collection_valued_path_expression) [AS] identifier
range_variable_declaration::= abstract_schema_name [AS]
identifier
219
Curso J150
24/04/04 01:49:17
jp@psique.org http://www.psique.org/cursos
220
Curso J150
A clusula WHERE
A clusula WHERE de uma consulta EJB QL determina a seleo de
dados. Ela tem a seguinte sintaxe:
WHERE conditional_expression
Outro exemplo:
...
<query>
<query-method>
<method-name>findOrganizacao_ejbql</method-name>
<method-params>
24/04/04 01:49:19
jp@psique.org http://www.psique.org/cursos
221
Curso J150
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql><![CDATA[
SELECT DISTINCT geral.organizacao.chefe
FROM organizacoes as geral
WHERE geral.nome = ?1 OR gera.apelido = ?1
]]></ejb-ql>
</query>
...
Literal
Identificao varivel
Expresso de caminho
Parmetro de entrada
Expresses between
Expresses in
Expresses like
Expresses funcionais
222
Curso J150
Literal
Um literal pode ser um string, um numero exato, um nmero
aproximado, um booleano. Uma string literal aparece dentro de um
par de haspas simples. Se o string literal contiver um nico caracter
de haspas internamente, o caractere precisa ser tirado, usando
outro caracter . Assim O'Connor representado como O'Connor.
Um literal numrico exato um valor numrico sem ponto decimal.
Um literal numrico aproximado um valor em ponto flutuante e
representado em notao cientfica, ou um valor numrico com
ponto decimal:
9E2 = (9 x 10^2)
Um literal lgico TRUE ou False.
Identificao varivel
Uma varivel de identificao foi definida na seo anterior, A
clusula FROM. Qualquer identificao que aparece na clusula
HWERE precisa ser declarada na clusula FROM.
Expresso de caminho
A expresso de caminho tambm foi definida na seo. A clusula
FROM. ilegal usar uma collection_valued_path_expression dentro
de uma clusula WHERE como parte de uma expresso condicional,
exceto em uma empty_comparison_expression ou
collection_member_expression.
Parmetros de entrada
Os parmetros de entrada obedecem s seguintes regras:
24/04/04 01:49:22
jp@psique.org http://www.psique.org/cursos
223
Curso J150
224
Curso J150
Expresses between
A seguir est a sintaxe para o uso do operador de comparao
[NOT] BETWEEN em uma expresso condicional:
arithmetic_expression [NOT] BETWEEN arithmetic-expr AND
arithmetic-expr
Expresses in
A seguinte a sintaxe para uso do operador de comparao [NOT]
IN em uma expresso condicional:
single_valued_path_expression [NOT] IN (string-literal [, stringliteral]* )
Expresses like
A seguir est a sintaxe para uso do operador de comparao [NOT]
LIKE em uma expresso condicional:
single_valued_path_expression [NOT] LIKE pattern-value [ESCAPE
escape-character]
24/04/04 01:49:26
jp@psique.org http://www.psique.org/cursos
225
Curso J150
Expresses funcionais
As seguintes so funes internas de EJB QL:
Funes de string:
Funes aritmticas:
24/04/04 01:49:27
jp@psique.org http://www.psique.org/cursos
226
Curso J150
EJB QL BNF
Abaixo a notao BNF de uma EJB QL, definido na especificao de
Enterprise JavaBeans:
Smbolos BNF
Descrio
::=
{...}
[...]
Um OR exclusivo.
24/04/04 01:49:29
jp@psique.org http://www.psique.org/cursos
227
Curso J150
[, identification_variable_declaration]*
identification_variable_declaration ::=
collection_member_declaration |
range_variable_declaration
collection_member_declaration ::=
IN (collection_valued_path_expression) [AS]
identifier
range_variable_declaration ::=
abstract_schema_name [AS] identifier
single_valued_path_expression ::=
{single_valued_navigation |
identification_variable}.cmp_field |
single_valued_navigation
single_valued_navigation ::=
identification_variable.
[single_valued_cmr_field.]*
single_valued_cmr_field
collection_valued_path_expression ::=
identification_variable.
[single_valued_cmr_field.]*
collection_valued_cmr_field
select_clause ::= SELECT [DISTINCT]
{single_valued_path_expression |
OBJECT(identification_variable)}
where_clause ::= WHERE conditional_expression
conditional_expression ::= conditional_term |
conditional_expression OR conditional_term
conditional_term ::= conditional_factor |
conditional_term AND conditional_factor
conditional_factor ::= [ NOT ] conditional_test
conditional_test ::= conditional_primary
conditional_primary ::=
simple_cond_expression |
(conditional_expression)
24/04/04 01:49:31
jp@psique.org http://www.psique.org/cursos
228
Curso J150
simple_cond_expression ::=
comparison_expression |
between_expression |
like_expression |
in_expression |
null_comparison_expression |
empty_collection_comparison_expression |
collection_member_expression
between_expression ::=
arithmetic_expression [NOT] BETWEEN
arithmetic_expression AND
arithmetic_expression
in_expression ::=
single_valued_path_expression
[NOT] IN (string_literal [, string_literal]* )
like_expression ::=
single_valued_path_expression
[NOT] LIKE pattern_value [ESCAPE escapecharacter]
null_comparison_expression ::=
single_valued_path_expression IS [NOT] NULL
empty_collection_comparison_expression ::=
collection_valued_path_expression IS [NOT]
EMPTY
collection_member_expression ::=
{single_valued_navigation |
identification_variable |
input_parameter}
[NOT] MEMBER [OF]
collection_valued_path_expression
comparison_expression ::=
string_value { =|<>} string_expression |
boolean_value { =|<>} boolean_expression} |
datetime_value { = | <> | > | < }
datetime_expression |
entity_bean_value { = | <> }
entity_bean_expression |
arithmetic_value comparison_operator
24/04/04 01:49:33
jp@psique.org http://www.psique.org/cursos
229
Curso J150
single_value_designator
arithmetic_value ::= single_valued_path_expression
|
functions_returning_numerics
single_value_designator ::= scalar_expression
comparison_operator ::=
= | > | >= | < | <= | <>
scalar_expression ::= arithmetic_expression
arithmetic_expression ::= arithmetic_term |
arithmetic_expression { + | - }
arithmetic_term
arithmetic_term ::= arithmetic_factor |
arithmetic_term { * | / } arithmetic_factor
arithmetic_factor ::= { + |- } arithmetic_primary
arithmetic_primary ::=
single_valued_path_expression |
literal | (arithmetic_expression) |
input_parameter | functions_returning_numerics
string_value ::= single_valued_path_expression |
functions_returning_strings
string_expression ::= string_primary |
input_expression
string_primary ::= single_valued_path_expression |
literal |
(string_expression) |
functions_returning_strings
datetime_value ::= single_valued_path_expression
datetime_expression ::= datetime_value |
input_parameter
boolean_value ::= single_valued_path_expression
boolean_expression ::=
single_valued_path_expression |
24/04/04 01:49:35
jp@psique.org http://www.psique.org/cursos
230
Curso J150
literal | input_parameter
entity_bean_value ::=
single_valued_navigation |
identification_variable
entity_bean_expression ::= entity_bean_value |
input_parameter
functions_returning_strings ::=
CONCAT(string_expression, string_expression) |
SUBSTRING(string_expression,
arithmetic_expression,
arithmetic_expression)
functions_returning_numerics::=
LENGTH(string_expression) |
LOCATE(string_expression,
string_expression[, arithmetic_expression]) |
ABS(arithmetic_expression) |
SQRT(arithmetic_expression)
24/04/04 01:49:37
jp@psique.org http://www.psique.org/cursos
231
Curso J150
Servio de mensagem
em Java
O ltimo tipo de EJB o message driven bean (MDB) ou, mensagem
direcionada para bean. Para isto, antes precisamos de um
introduo a JMS (Java Message Service). A prpria mensagem
direcionada para bean vista a seguir.
Justificativa para utilizao de MDB que a utilizao de
mensageria mais apropriada que a utilizao de RMI-IIOP em
vrios cenrios, pois assncrono e mais simples.
Performance
Um cliente RMI-IIOP precisa esperar ou ficar bloqueado enquanto o
servidor efetua o processamento. Apenas quando o servidor termina
todo o trabalho que tem para fazer, retorna ao cliente o resultado,
aps isto o cliente continua o processamento.
Disponibilidade
Quando um cliente RMI-IIOP chama o servidor, ele tem que estar
sendo executado. Se o servidor cair ou se a rede cair, o cliente no
pode executar suas operaes
24/04/04 01:49:39
jp@psique.org http://www.psique.org/cursos
232
Curso J150
Aplicao
Messaging
Aplicao
MOM
Aplicaao
Performance
Um cliente de mensageria no precisa ficar bloqueado quando
executa uma requisio. Como um exemplo, um cliente que envia
um pedido de compra ao servidor, pode continuar com o
processamento enquanto o servidor vai processando o pedido, sem a
necessidade de ficar esperando pela resposta. Sistemas do tipo atire
e esquea (fire-and-forget) podem ser simples de codificar usando
messaging.
24/04/04 01:49:41
jp@psique.org http://www.psique.org/cursos
233
Curso J150
Confiabilidade
Se seu message-oriented middleware suportar garantia de entrega,
voc pode enviar uma mensagem e ter certeza que ela chegar ao
destino, mesmo que o consumidor no momento esteja indisponvel.
Voc envia a mensagem para o MOM e o MOM encaminha a
mensagem ao consumidor, se ele no estiver disponvel no
momento, a mensagem fica no MOM at que o destinatrio volte.
Isto no possvel de ser feito com RMI-IIOP porque a conexo
direta entre cliente e servidor, no existe o MOM no meio do
caminho.
24/04/04 01:49:43
jp@psique.org http://www.psique.org/cursos
234
Curso J150
Como voc aprender, mais adiante, JMS tambm oferece esses dois
servios.
No entanto, um servio de envio de mensagem mais sofisticado
que um aplicativo de chat. Normalmente, em um aplicativo de chat
para troca de mensagens, o remetente e o(s) destinatrio(s)
precisam estar conectados ao mesmo tempo. Em um servio de
envio de mensagem, o remetente pode enviar uma mensagem sem o
destinatrio precisar estar conectado naquele mesmo momento. O
remetente envia a mensagem para um destino, e, depois, o
destinatrio a busca l.
JMS tambm separa os clientes. O remetente no precisa saber
nada sobre o destinatrio e vice-versa.
A API JMS
Durante muitos anos, os sistemas de MOM foram evoluindo de
forma proprietria. Cada produto tinha sua prpria API, o que
tornava os sistemas que utilizavam MOM no portveis. Era
tambm complicado para os desenvolvedores j que eles precisavem
conhecer os detalhes de cada API proprietria.
A Sun uniu foras com algumas empresas associadas para fazer o
design da API JMS, de modo a permitir a aplicativos Java criar,
enviar, e ler mensagens, bem como se comunicar com outras
implementaes de envio de mensagens. A verso original de JMS
foi lanada em agosto de 1998 e foi usada principalmente para
permitir aos aplicativos Java acessar sistemas de middleware
baseados em mensagem (MOM) existentes, como MQSeries da IBM.
Atualmente a verso mais recente da API JMS 1.1, que pode ser
baixada de http://java.sun.com/products/jms/docs.html.
Os aplicativos Java, que usam JMS, so chamados de clientes JMS e
o sistema de envio de mensagem, que gerencia o roteiro e a entrega
de mensagens, chamado de provedor JMS. Um cliente JMS que
24/04/04 01:49:45
jp@psique.org http://www.psique.org/cursos
235
Curso J150
24/04/04 01:49:47
jp@psique.org http://www.psique.org/cursos
236
Curso J150
Publish/Subscribe (pub/sub)
Nesse modelo, um cliente envia uma mensagem para um tpico e a
mensagem recebida por quaisquer clientes interessados que
assinam aquele tpico. Esse o modelo um-para-muitos, onde o
remetente tambm chamado publisher (publicador) e os
destinatrios so chamados de subscribers (assinantes). O ato de
enviar uma mensagem tambm chamado de publish (publicao).
Os tpicos enviam as mensagens diretamente a todos os assinantes
e no guardam as mensagens. Um cliente s pode consumir
mensagens depois de o cliente se inscrever em um tpico, e o
assinante precisa continuar a ser ativo para consumir mensagens
publicadas. Porm esta restrio , de alguma forma, relaxada em
JMS, permitindo a um cliente criar assinaturas durveis nas quais o
cliente pode receber mensagens enviadas enquanto ele no est
ativo.
Compare o modelo pub/sub com uma estao de rdio que divulga
notcias o tempo todo. As notcias podem ser recebidas por qualquer
rdio que esteja sintonizado na freqncia e modulao da estao
de rdio. Para receber uma parte de notcias em especial, um rdio
precisa estar sintonizado na hora em que a seo de notcias
difundida.
Point-to-Point (PTP)
Nesse modelo, um cliente envia uma mensagem que s recebida
por um cliente. O remetente envia uma mensagem para uma fila e o
destinatrio extrai essa mensagem da fila, em qualquer ocasio
conveniente que o destinatrio se conecta com o sistema. Uma fila
retm todas as mensagens recebidas at que elas sejam
consumidas, ou at que a mensagem expire.
O modelo PTP semelhante ao servio postal, em que o destinatrio
tem uma caixa postal em uma loja de correio. O remetente envia
24/04/04 01:49:49
jp@psique.org http://www.psique.org/cursos
237
Curso J150
Consumidor 2
Produtor 2
Consumidor 3
Ponto-a-ponto (point-to-point):
Produtor 1
Fila
Consumidor 1
Produtor 2
ConnectionFactory
Destination
Connection
Session
24/04/04 01:49:51
jp@psique.org http://www.psique.org/cursos
238
MessageProducer
MessageConsumer
Message
Curso J150
239
Curso J150
Interface Me
Ponto - a- Ponto
Pub/Sub
ConnectionFactory
Connection
Destination
Session
MessageProducer
MessageConsumer
QueueConnectionFactory
QueueConnection
Queue
QueueSession
QueueSender
QueueReceiver,
QueueBrowser
TopicConnectionFactory
TopicConnection
Topic
TopicSession
TopicPublisher
TopicSubscriber
24/04/04 01:49:55
jp@psique.org http://www.psique.org/cursos
240
Curso J150
ConnectionFactory
Um objeto ConnectionFactory usado para criar uma conexo com
um provedor JMS. Ele suporta uso consecutivo e contm parmetros
e configurao de conexo que foram definidos por um
administrador.
No pacote javax.jms, o objeto ConnectionFactory modelado pela
interface ConnectionFactroy, cuja assinatura :
public interface ConnectionFactory
E, para obter uma conexo para um provedor JMS pub/sub, voc usa
o seguinte cdigo:
Context context = new InitialContext()
TopicConnectionFactory topicConnectionFactory =
(TopicConnectionFactory) context.lookup
(TopicContextFactory);
241
Curso J150
Destination
Um objeto Destination encapsula um endereo especfico de
provedor. Um objeto Destination suporta uso consecutivo e, no
pacote javax.jms, representado pela interface Destination, cuja
assinatura :
public interface Destination
24/04/04 01:49:59
jp@psique.org http://www.psique.org/cursos
242
Curso J150
TopicConnectionFactory topicConnectionFactory =
(TopicConnectionFactory) context.lookup
(TopicConnectionFactory);
Topic topic = (Topic) context.lookup(topicName);
Connections
Um objeto Connections representa uma conexo ativa do cliente
JMS com um provedor JMS. Tipicamente, ele um soquete TCP/IP
entre um cliente JMS e um provedor JMS. O)s objetos Connection
suportam uso consecutivo e so representados pela interface
javax.jms.Connection. Essa interface Connection tem a seguinte
assinatura:
public interface Connection
243
Curso J150
QueueConnection queueConnection =
queueConnectionFactory.createQueueConnection();
Session
Um objeto Session um contexto de seqenciamento nico para
produzir e consumir mensagens. Um objeto Session representado
pela interface Session, que usa a seguinte assinatura:
public interface Session extends java.lang.Runnable
244
Curso J150
245
Curso J150
MessageProducer
Um objeto MessageProducer usado por um cliente JMS para
enviar mensagens a um destino. No pacote javax.jms, esse objeto
representado pela interface MessageProducer, que tem a seguinte
assinatura:
public interface MessageProducer
246
Curso J150
MessageConsumer
Um objeto MessagConsumer usado por um cliente JMS para
receber mensagem de um destino. No pacote javax.jms, esse objeto
representado pela interface MessageConsumer, que tem a
seguinte assinatura:
public interface MessageConsumer
24/04/04 01:50:13
jp@psique.org http://www.psique.org/cursos
247
Curso J150
Message
H muitos tipos de mensagens em JMS:
24/04/04 01:50:15
jp@psique.org http://www.psique.org/cursos
248
Curso J150
24/04/04 01:50:20
jp@psique.org http://www.psique.org/cursos
249
Curso J150
/*
* Criado em 18/04/2004 02:54:20
(Date of creation)
*
* Por: Joo Paulo Limberger
* jp@psique.org
http://www.psique.org/jp
*/
package org.psique.queue;
import java.util.Properties;
import
import
import
import
import
import
javax.jms.JMSException;
javax.jms.Queue;
javax.jms.QueueConnection;
javax.jms.QueueConnectionFactory;
javax.jms.QueueSender;
javax.jms.QueueSession;
24/04/04 01:50:22
jp@psique.org http://www.psique.org/cursos
250
import
import
import
import
import
Curso J150
javax.jms.Session;
javax.jms.TextMessage;
javax.naming.Context;
javax.naming.InitialContext;
javax.naming.NamingException;
/**
* @author jp
*
* 18/04/2004 02:54:20
*
*
*/
public class MessageSender {
public static void main(String[] args) {
QueueConnection queueConnection = null;
try {
Properties properties = new Properties();
properties.put(
Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
properties.put(
Context.PROVIDER_URL,
"localhost:1099");
Context context =
new InitialContext(properties);
QueueConnectionFactory queueConnectionFactory =
(
QueueConnectionFactory) context
.lookup(
"ConnectionFactory");
String queueName = "queue/A";
Queue queue =
(Queue) context.lookup(queueName);
queueConnection =
queueConnectionFactory
.createQueueConnection();
QueueSession queueSession =
queueConnection
.createQueueSession(
false,
Session.AUTO_ACKNOWLEDGE);
QueueSender queueSender =
queueSession.createSender(queue);
TextMessage message =
queueSession.createTextMessage();
message.setText(
24/04/04 01:50:24
jp@psique.org http://www.psique.org/cursos
251
Curso J150
24/04/04 01:50:26
jp@psique.org http://www.psique.org/cursos
252
Curso J150
/*
* Criado em 18/04/2004 03:08:24
(Date of creation)
*
* Por: Joo Paulo Limberger
* jp@psique.org
http://www.psique.org/jp
*/
package org.psique.queue;
import java.util.Properties;
import
import
import
import
import
import
import
javax.jms.JMSException;
javax.jms.Message;
javax.jms.Queue;
javax.jms.QueueConnection;
javax.jms.QueueConnectionFactory;
javax.jms.QueueReceiver;
javax.jms.QueueSession;
24/04/04 01:50:28
jp@psique.org http://www.psique.org/cursos
253
import
import
import
import
import
Curso J150
javax.jms.Session;
javax.jms.TextMessage;
javax.naming.Context;
javax.naming.InitialContext;
javax.naming.NamingException;
/**
* @author jp
*
* 18/04/2004 03:08:24
*
*
*/
public class MessageReceiver {
public static void main(String[] args) {
QueueConnection queueConnection = null;
try {
Properties properties =
new Properties();
properties.put(
Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
properties.put(
Context.PROVIDER_URL,
"localhost:1099");
Context context =
new InitialContext(properties);
QueueConnectionFactory queueConnectionFactory =
(
QueueConnectionFactory) context
.lookup(
"ConnectionFactory");
String queueName = "queue/A";
Queue queue =
(Queue) context.lookup(queueName);
queueConnection =
queueConnectionFactory
.createQueueConnection();
QueueSession queueSession =
queueConnection
.createQueueSession(
false,
Session.AUTO_ACKNOWLEDGE);
QueueReceiver queueReceiver =
queueSession.createReceiver(
queue);
queueConnection.start();
System.out.println(
"Recebendo mensagem:");
Message message =
24/04/04 01:50:30
jp@psique.org http://www.psique.org/cursos
254
Curso J150
queueReceiver.receive(1);
if (message != null) {
if (message
instanceof TextMessage) {
TextMessage textMessage =
(TextMessage) message;
System.out.println(
"Mensagem recebida:\n"
+ textMessage
.getText());
}
}
} catch (NamingException e) {
System.out.println(
"Naming Exception");
} catch (JMSException e) {
System.out.println("JMS Exception");
} finally {
if (queueConnection != null) {
try {
queueConnection.close();
} catch (JMSException e) {}
}
}
}
}
O cdigo acima, recebe a mensagem enviada pelo programa
anterior. Inicialmente feita uma busca JNDI para obter um
QueueConnectionFactory, e depois o Queue:
QueueConnectionFactory queueConnectionFactory =
(QueueConnectionFactory) context.lookup
("ConnectionFactory");
String queueName = "queue/A";
Queue queue = (Queue) context.lookup(queueName);
24/04/04 01:50:32
jp@psique.org http://www.psique.org/cursos
255
Curso J150
Exemplo de pub/sub
O topico um recurso administrado, ento precisamos criar o tpico
24/04/04 01:50:34
jp@psique.org http://www.psique.org/cursos
256
Curso J150
<mbean code="org.jboss.mq.server.jmx.Topic"
name="jboss.mq.destination:service=Topic,name=Precos">
<depends optional-attributename="DestinationManager">jboss.mq:service=DestinationManager</depends>
<depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
<attribute name="SecurityConf">
<security>
<role name="guest" read="true" write="true"/>
<role name="publisher" read="true" write="true" create="false"/>
<role name="durpublisher" read="true" write="true" create="true"/>
</security>
</attribute>
</mbean>
/*
* Criado em 17/04/2004 22:08:24
(Date of creation)
*
* Por: Joao Paulo Limberger
* jp@psique.org
http://www.psique.org/jp
*/
package org.psique.pubsub;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import
import
import
import
import
import
import
import
import
import
import
javax.jms.JMSException;
javax.jms.Session;
javax.jms.TextMessage;
javax.jms.Topic;
javax.jms.TopicConnection;
javax.jms.TopicConnectionFactory;
javax.jms.TopicPublisher;
javax.jms.TopicSession;
javax.naming.Context;
javax.naming.InitialContext;
javax.naming.NamingException;
/**
* @author jp
*
24/04/04 01:50:36
jp@psique.org http://www.psique.org/cursos
257
Curso J150
* 17/04/2004 22:08:24
*
*
*/
public class ClientePublicadorJMS {
public static void main(String[] args)
throws NamingException, JMSException {
// Inicializando JNDI
Properties properties = new Properties();
properties.put(
Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
properties.put(
Context.PROVIDER_URL,
"localhost:1099");
Context ctx =
new InitialContext(properties);
// Procurar pelo ConnectionFactory utilizando JNDI
TopicConnectionFactory factory =
(TopicConnectionFactory) ctx.lookup(
"javax.jms.TopicConnectionFactory");
// Utilizar o ConnectionFactory para criar a conexo JMS
TopicConnection connection =
factory.createTopicConnection();
// Usar o Connection para criar uma sesso
TopicSession session =
connection.createTopicSession(
false,
Session.AUTO_ACKNOWLEDGE);
// Procurar o topico via JNDI
Topic topico =
(Topic) ctx.lookup("topic/Precos");
// Criar o produtor da mensagem:
TopicPublisher publisher =
session.createPublisher(topico);
// inicializa a conexo
connection.start();
258
Curso J150
+ p.getProduto()
+ " teve seu preco reajustado de "
+ p.getValorAnterior()
+ " para "
+ p.getValor());
msg.setStringProperty(
"categoria",
p.getCategoria());
msg.setDoubleProperty(
"Valor",
p.getValor());
msg.setDoubleProperty(
"ValorAnterior",
p.getValor());
publisher.publish(msg);
// D um tempo
try {
Thread.sleep((long) (15000*Math.random()));
} catch (InterruptedException e) {}
}
}
static Map precos = new HashMap();
static Preco getPrecoAleatorio() {
Preco p = null;
String nomes[][] =
{ { "Leite", "Laticinios" }, {
"Iogurte", "Laticinios" }, {
"Feijao", "Cereias" }, {
"Arroz", "Cereias" }, {
"Lentilha", "Cereias" }, {
"Grao-de-bico", "Cereias" }, {
"Martelo", "Ferragens" }, {
"Prego", "Ferragens" }
};
int i =
(int) Math.random() * nomes.length;
String nome = nomes[i][0];
p = (Preco) precos.get(nome);
if (p == null) {
p = new Preco();
p.setProduto(nomes[i][0]);
p.setCategoria(nomes[i][1]);
p.setValor(
(double) ((int) (Math.random()
* 100000))
/ 100);
precos.put(p.getProduto(), p);
}
p.setValor(
(double) ((int) (Math.random()
* 100000))
/ 100);
24/04/04 01:50:39
jp@psique.org http://www.psique.org/cursos
259
Curso J150
return p;
}
}
/*
* Criado em 17/04/2004 22:35:08
(Date of creation)
*
* Por: Joo Paulo Limberger
* jp@psique.org
http://www.psique.org/jp
*/
package org.psique.pubsub;
/**
* @author jp
*
* 17/04/2004 22:35:08
*
*
*/
public class Preco {
private String produto;
private String categoria;
private double valor;
private double valorAnterior;
/**
* @return
*/
public String getCategoria() {
return categoria;
}
/**
* @return
*/
public double getValor() {
return valor;
}
/**
* @param string
*/
public void setCategoria(String string) {
categoria = string;
}
/**
24/04/04 01:50:42
jp@psique.org http://www.psique.org/cursos
260
Curso J150
* @param d
*/
public void setValor(double d) {
valorAnterior = valor;
valor = d;
}
/**
* @return
*/
public double getValorAnterior() {
return valorAnterior;
}
/**
* @return
*/
public String getProduto() {
return produto;
}
/**
* @param string
*/
public void setProduto(String string) {
produto = string;
}
}
/*
* Criado em 17/04/2004 22:08:24
(Date of creation)
*
* Por: Joo Paulo Limberger
* jp@psique.org
http://www.psique.org/jp
*/
package org.psique.pubsub;
import java.util.Properties;
import
import
import
import
import
import
import
import
javax.jms.JMSException;
javax.jms.Message;
javax.jms.Session;
javax.jms.TextMessage;
javax.jms.Topic;
javax.jms.TopicConnection;
javax.jms.TopicConnectionFactory;
javax.jms.TopicSession;
24/04/04 01:50:44
jp@psique.org http://www.psique.org/cursos
261
import
import
import
import
Curso J150
javax.jms.TopicSubscriber;
javax.naming.Context;
javax.naming.InitialContext;
javax.naming.NamingException;
/**
* @author jp
*
* 17/04/2004 22:08:24
*
*
*/
public class ClienteAssinanteJMS {
public static void main(String[] args)
throws NamingException, JMSException {
// Inicializando JNDI
Properties properties = new Properties();
properties.put(
Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
properties.put(
Context.PROVIDER_URL,
"localhost:1099");
Context ctx =
new InitialContext(properties);
// Procurar pelo ConnectionFactory utilizando JNDI
TopicConnectionFactory factory =
(TopicConnectionFactory) ctx.lookup(
"ConnectionFactory");
// Utilizar o ConnectionFactory para criar a conexo JMS
TopicConnection connection =
factory.createTopicConnection();
262
Curso J150
//TopicSubscriber subscriber =
//
session.createSubscriber(topico);
// Inicia a conexo...
connection.start();
while (true) {
System.out.println(
"Aguardando a chegada de uma mensagem");
// Espera 250 segundos por uma mensagem
Message mensagem =
subscriber.receive(250000);
if(mensagem==null) {
System.out.println("Cansei de esperar!!!");
break;
}
System.out.println(
"Chegou uma mensagem!");
try {
if (mensagem
instanceof TextMessage) {
TextMessage tm =
(TextMessage) mensagem;
String produto =
tm.getStringProperty(
"produto");
String categoria =
tm.getStringProperty(
"categoria");
double valor =
tm.getDoubleProperty(
"Valor");
double valorAnterior =
tm.getDoubleProperty(
"ValorAnterior");
String msg = tm.getText();
System.out.println(
"Nova mensagem\n" + msg);
System.out.println(
"valor" + valor);
System.out.println(
"valor anterior "
+ valorAnterior);
System.out.println(
"categoria " + categoria);
} else {
System.out.println(
"Nao estou preparado para receber "
+ mensagem
.getClass()
.getName());
}
24/04/04 01:50:48
jp@psique.org http://www.psique.org/cursos
263
Curso J150
} catch (Exception e) {
System.err.println("Ops!" + e);
}
}
}
RMI IL
A primeira camada de invocao baseada em RMI (Remote
Method Invocation). bem robusta pois baseada na tecnologia
RMI. Deve ser usada quando aplicaes clientes possuirem muitas
threads compartilhando a mesma conexo.
Esta IL vai tentar conectar-se via conexo TCP/IP via socket do
servidor para o cliente. Logo, clientes atrs de firewalls ou com
restries de segurana no devem utilizar.
OIL IL
A prxima camada que foi desenvolvida foi a Optimized IL (OIL). A
OIL usa protocolo TCP/IP e serializao que tem um overhead muito
baixo. Este foi o protocolo recomendado baseado em socket at a
adio do UIL2.
24/04/04 01:50:50
jp@psique.org http://www.psique.org/cursos
264
Curso J150
UIL IL
A Unified Invocation Layer (UIL) foi desenvolvida para permitir a
clientes Applet conectarem-se a servidores. Ela quase igual ao
protocolo OIL exceto que uma camada multiplexadora foi utilizada
para permitir canais dual. A camada multiplexadora cria dois
sockets virtuais sobre um socket fsico. Esta IL mais lenta que a
OIL porque tem um grande overhead na multiplexao. Esta IL est
depreciada em favor da UIL2.
UIL2 IL
A Unified version 2 Invocation Layer (UIL2) uma nova variao do
protocolo da UIL que tambm usa um nico socket entre o cliente e
o servidor, s que diferentemente do UIL e do OIL que utilizam
bloqueamento de mensagens a nvel de socket, o protocolo UIL2 usa
um nvel de transporte verdadeiramente assncrono para enviar e
receber mensagens. Isto possibilita melhora na utilizao do canal e
a IL preferida.
JVM IL
A Java Virtual Machine (JVM) IL foi desenvolvida para acabar com o
overhead do TCP/IP quando o cliente JMS estiver sendo executado
na mesma mquina virtual. Esta IL usa chamada direta a mtodos
dos servios do servidor e do cliente. Isto aumenta muito a
eficincia pois sockets no so criados e no necessria a criao
de threads auxiliares (para monitorar os sockets). Esta a IL que
ser usada pelos Message Driven Beans (MDB) ou outro
componente que executado na mesma mquina virtual que o
servidor tais como servlets ou MBeans.
24/04/04 01:50:51
jp@psique.org http://www.psique.org/cursos
265
Curso J150
HTTP IL
A camada de invocao HTTP permite o acesso aos servios do
JBossMQ sobre os protocolos HTTP ou HTTPS . Esta IL consiste em
um servlet baixado no deploy/jms/jbossmq-httpil.sar para controlar
o trfego http. Esta IL til para acessar o JMS atravs de firewall
quando a nico porto admitido requer HTTP.
Configurao da IL
No diretrio ${JBOSS_HOME}/server/default/deploy/jms, existem
arquivos xxx-service.xml, onde xxx a IL (oil-service.xml, oil2service.xml, rmi-il-service.xml, jvm-il-service.xml, uil2-service.xml).
Nestes arquivos pode-se ver o Atributo ConnectionFactoryJNDIRef,
que o nome que deve ser acessado para obter a fbrica
(ConnectionFactory). A conexo via http obtida utilizando-se
(HTTPConnectionFactory), pois via http o acesso via Servlet, o
gerenciamento feito pelo MBean
org.jboss.mq.il.http.HTTPServerILService .
24/04/04 01:50:53
jp@psique.org http://www.psique.org/cursos
266
Curso J150
24/04/04 01:50:55
jp@psique.org http://www.psique.org/cursos
267
Curso J150
24/04/04 01:50:57
jp@psique.org http://www.psique.org/cursos
268
Curso J150
MDBs so stateless
Os MDBs no armazenam estado conversasional.
A Application Programming
Interface (API)
Uma classe de message-driven bean precisa ser uma classe pblica
e precisa implementar as duas seguintes interfaces:
javax.ejb.MessageDrivenBean
javax.jms.MessageListener
24/04/04 01:50:59
jp@psique.org http://www.psique.org/cursos
269
Curso J150
A interface javax.jms.MessageListener
A assinatura da interface javax.jms.MessageListener a seguinte:
public interface javax.jms.MessageListener {
public void onMessage(Message message);
}
A interface javax.ejb.MessageDrivenBean
A javax.ejb.MessageDrivenBean tem a seguinte assinatura:
public interface MessageDrivenBean extends EnterpriseBean
A interface javax.ejb.MessageDrivenBean
A interface MessageDrivenContext oferece acesso ao contexto da
mensagem direcionada no tempo de execuo, que o continer
oferece a uma cpia de mensagem direcionada por enterprise bean.
O continer passa a interface MessageDrivenContext a uma cpia,
24/04/04 01:51:00
jp@psique.org http://www.psique.org/cursos
270
Curso J150
271
Curso J150
Empacotar o Bean
/*
24/04/04 01:51:04
jp@psique.org http://www.psique.org/cursos
272
Curso J150
javax.ejb.EJBException;
javax.ejb.MessageDrivenBean;
javax.ejb.MessageDrivenContext;
javax.jms.JMSException;
javax.jms.Message;
javax.jms.MessageListener;
javax.jms.Queue;
javax.jms.QueueConnection;
javax.jms.QueueConnectionFactory;
javax.jms.QueueSender;
javax.jms.QueueSession;
javax.jms.TextMessage;
javax.naming.InitialContext;
273
Curso J150
274
Curso J150
try {
TextMessage message =
(TextMessage) msg;
Queue queue =
(Queue) msg.getJMSReplyTo();
QueueSender sender =
session.createSender(queue);
TextMessage message2 =
session.createTextMessage(
message.getText());
sender.send(message2);
sender.close();
} catch (Exception e) {
e.printStackTrace();
}
}
24/04/04 01:51:10
jp@psique.org http://www.psique.org/cursos
275
Curso J150
24/04/04 01:51:12
jp@psique.org http://www.psique.org/cursos
276
Curso J150
O deployment descriptor
Como outros aplicativos EJB voc precisa de um descritor para
distribuir o seu MDB:
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD
Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejbjar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>MeuMDB</ejb-name>
<ejb-class>org.psique.ejb.MeuMDB</ejb-class>
<transaction-type>Container</transaction-type>
<acknowledge-mode>AUTO_ACKNOWLEDGE</acknowledge-mode>
<message-driven-destination>
<destination-type>javax.jms.Queue</destination-type>
</message-driven-destination>
<resource-ref>
<res-ref-name>jms/QCF</res-ref-name>
<res-type>ConnectionFactory</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</message-driven>
</enterprise-beans>
</ejb-jar>
24/04/04 01:51:14
jp@psique.org http://www.psique.org/cursos
277
Curso J150
</jboss>
Empacotamento do MDB
Para empacotar, utilizando jar, utilize o comando abaixo:
24/04/04 01:51:16
jp@psique.org http://www.psique.org/cursos
278
Curso J150
24/04/04 01:51:17
jp@psique.org http://www.psique.org/cursos
279
Curso J150
280
Curso J150
24/04/04 01:51:21
jp@psique.org http://www.psique.org/cursos
281
Curso J150
24/04/04 01:51:23
jp@psique.org http://www.psique.org/cursos
282
24/04/04 01:51:25
jp@psique.org http://www.psique.org/cursos
Curso J150
283
Curso J150
Chamando Beans de
outros Beans
284
Curso J150
Referncias EJB
No exemplo anterior procuramos por um bean em
java:comp/env/ejb. Esta uma localizao JNDI que a especificao
EJB recomenda (mas no requer) que voc coloca os beans que so
referenciados por outros beans.
24/04/04 01:51:28
jp@psique.org http://www.psique.org/cursos
285
Curso J150
286
Curso J150
287
Curso J150
<ejb-link>Catalogo</ejb-link>
</ejb-ref>
</session>
</enterprise-beans>
....
24/04/04 01:51:34
jp@psique.org http://www.psique.org/cursos
288
Segurana
Curso J150
Segurana
Existem duas principais medidas que os clientes devem obedecer
para acessar um sistema EJB com segurana.
Primeiro: O cliente precisa ser autenticado. Autenticao verifica
que o cliente quem alega ser. Por exemplo, o cliente pode entrar
com um usurio/senha (segredo compartilhado) na aplicao web e
estas credenciais so verificadas no cadastro do cliente. Aps
autenticado, o cliente associado com uma identidade segura para
o resto da sesso.
Segundo: O cliente precisa estar autorizado. Uma vez que o cliente
est autenticado, ele precisa ter permisso para executar as
operaes desejadas.
Existem uma diferena importante aqui: autenticao verifica quem
o cliente , autorizao checa se um cliente j autenticado tem
direitos para executar o servio desejado. Se o cliente tem uma
identidade ento ele j foi autenticado. A autorizao ocorre
durante as chamadas a mtodos de EJB.
Autenticao
Nas verses anteriores de EJB (1.0 e 1.1), no existia uma forma
portvel de autenticao. A forma especfica utilizada pelo cliente
era implementada no cdigo do cliente era da aplicao e
proprietria do continer. Cada tipo de continer controlava a
autenticao de forma diferente.
Com EJB2.0, a autenticao se tornou protvel e robusta. A
autenticao efetuada atravs de JAAS (Java Authentication and
24/04/04 01:51:36
jp@psique.org http://www.psique.org/cursos
289
Segurana
Curso J150
Authorization Service).
O que JAAS
JAAS (Java Authentication and Authorization Service) uma
interface portvel que habilita voc a se autenticar e autorizar
usurios em Java. Ela permite que voc logue em um sistema sem
que voc conhea o sistema de segurana que est sendo utilizado.
Atrs de JAAS o application server determina se suas credenciais
so autenticas.
O poder de JAAS reside na habilidade de usar praticamente
qualquer sistema de segurana. Alguns application servers
permitem que voc configure usurios e passwords no application
server, outros utilizam arquivos de propriedades lidos pelo
application server em tempo de execuo, outros ainda funcionam
integrados a SGBDs, LDAP, etc.
290
Segurana
Curso J150
LoginModule (javax.security.auth.spi.LoginModule)
Subject e Principal
Para autorizar um acesso a um recurso, aplicaes primeiro
precisam autenticar o requisitante da requisio. O framework JAAS
define o termo SUBJECT para representar a origem da requisio. A
classe Subject a classe central de JAAS. A classe Subject
representa informaes para uma nica entidade, tal como uma
pessoa ou um servio. Ela encapsula o principal da entidade, as
credenciais pblicas e a credencial privada. A API JAAS usa a
interface existente em Java2 java.security.Principal para
representar um principal, que essencialmente apenas um nome
digitado.
Durante o processo de autenticao, um Subject populado com
identidades associadas, ou Principals. Um Subject pode ter vrios
Principals. Por exemplo, uma pessoa pode ter um nome Principal
(Jos da Silva) e um CPF Principal (123.123.123-34), e um nome
de usurio Principal (josesilva), tudo que ajuda distinguir o
Subject de outro Subject. Para recuperar os Principals associado
a um Subject, dois mtodos esto disponveis:
{
...
public Set getPrincipals() {...}
public Set getPrincipals (Class c) {..}
}
291
Segurana
Curso J150
Autenticao de um Subject
A autenticao de um Subject requer um login no JAAS. O
procedimento de login consite dos seguintes passos:
1. Uma aplicao instancia um LoginContext passando o nome da
configurao de login e um CallbackHandler para popular os
objetos Callback obrigatrios pela configurao de
LoginModules.
2. O LoginContext consulta o Configuration para carregar todos
os LoginModules includos na configurao de login selecionada.
Se nenhum nome de configurao existir a configurao other
usada como default
3. A aplicao invoca o mtodo LoginContext.login.
4. O mtodo de login invoca todos os LoginModules carregados.
Como cada LoginModule tenta autenticar o Subject, el einvoca
um mtodo handle no CallbackHandler associado para obter as
informaes requeridas pelo processo de autenticao. As
informaes so passadas ao mtodo handle na forma de um
array de objetos Callback. Tendo sucesso, o LoginModule associa
os Principals relevantes e as credenciais com o Subject.
5. O LoginContext retorna o status de autenticao para a
aplicao. O sucesso representado pelo retorno de um mtodo
login. A falha representada pelo lanamento de uma
LoginException lanada pelo mtodo login.
6. Se a autenticao tiver sucesso, a aplicao recupera o Subject
autenticado usando o mtodo LoginContext.getSubject.
7. Depois que a autenticao do Subject estiver completa. Todos os
Principals e informaes relacionadas com o Subject pelo
mtodo de login podem ser removidas invocando o mtodo
LoginContext.logout.
A classe LoginContext prov os mtodos bsicos para autenticar os
Subjects e oferece um meio de desenvolver uma aplicao
independentemente da tecnologia utilizada para autenticao. O
LoginContext consulta um objeto Configuration para determinar
24/04/04 01:51:41
jp@psique.org http://www.psique.org/cursos
292
Segurana
Curso J150
24/04/04 01:51:43
jp@psique.org http://www.psique.org/cursos
293
Segurana
Curso J150
{
NameCallback nc = (NameCallback) callbacks[i];
nc.setName(username);
}
else if (callbacks[i] instanceof PasswordCallback)
{
PasswordCallback pc =
(PasswordCallback) callbacks[i];
pc.setPassword(password);
}
else
{
throw new UnsupportedCallbackException(
callbacks[i],
Callback desconhecido);
}
}
}
}
294
Segurana
Curso J150
295
Segurana
Curso J150
Autorizao
Uma vez que o cliente esteja autenticado, ele precisa passar pelo
teste de autorizao para chamar os mtodos de seus beans. Esta
autorizao est definida nas polticas de segurana (security
24/04/04 01:51:49
jp@psique.org http://www.psique.org/cursos
296
Segurana
Curso J150
Basic authentication.
O cliente Web informa um nome de usurio e senha para o servidor
Web. O servidor verifica estas credenciais no repositrio de
usurios e senhas. Note que apesar de ser uma forma simples de
checar no uma forma segura pois a senha mandada aberta para
o servidor. Alguns servidores J2EE admitem que voc utilize SSL
para encriptar estes dados.
Form-based authentication
Igual basic authentication, exceto que a aplicao utiliza um form
customizado em uma tela de login.
24/04/04 01:51:51
jp@psique.org http://www.psique.org/cursos
297
Segurana
Curso J150
Digest authentication
O cliente Web informa um digest para o Web server. Este digest
uma transformao matemtica da password e da mensagem. A
senha no enviada para o Servidor. O Servidor ento tenta
reproduzir a mensagem efetuando a mesma transformao que foi
feita no cliente, exceto que desta vez o Servidor usa uma copia
segura da password do cliente mantida em camada de persistncia.
Se o digest conferir, o usurio est autenticado.
Certificate authentication
O cliente Web pode informar um certificada padro X.509 para
provar sua identidade. O cliente pode (opcionalmente) assegurar
que o servidor quem ele imagina recebendo o certificado X.509
que autentica o servidor (autenticao mtua).
De forma programtica
Voc codifica no cdigo do bean. Sua regra de negcio integrada
com regras de segurana.
De forma declarativa
O continer faz a autorizao para voc. Voc declara como a
autorizao deve ser feita no deployment descriptor e o continer
faz todas as checagens de segurana necessrias. Voc
efetivamente delega a autorizao para o continer EJB.
298
Segurana
Curso J150
24/04/04 01:51:54
jp@psique.org http://www.psique.org/cursos
299
Segurana
Curso J150
24/04/04 01:51:56
jp@psique.org http://www.psique.org/cursos
300
Segurana
Curso J150
Referncias de segurana
Em ambos, EJBs e servlets podem ser declarados um ou mais
elementos do tipo security-role-ref. uma ligao de um papel
local para o componente com um papel da aplicao. Este
elemento usado para declarar que um componente est usando o
valor de um role-name (papel) como argumento para o mtodo
24/04/04 01:51:58
jp@psique.org http://www.psique.org/cursos
301
Segurana
Curso J150
24/04/04 01:52:00
jp@psique.org http://www.psique.org/cursos
302
Segurana
Curso J150
Identidade de Segurana
EJBs podem opcionalmente declarar um elemento security-identity.
novo em EJB 2.0 a capacidade de especificar qual identidade um
EJB deve usar quando ele invoca mtodos em outros componentes.
A identidade de invocao pode ser aquela que o usurio atual tem,
ou um papel especfico. O application assembler usa o elemento
security-identity com um elemento filho use-caller-identity para
indicar que a identidade do usurio correto deve ser propagada
como uma identidade de segurana para os mtodos invocados
feitos pelo continer EJB. Propagao da identidade do requisitante
usada por default na ausncia de uma declarao especfica de
um elemento security-identity.
Alternativamente, o application assembler pode user um elemento
filho run-as/role-name para especificar que um papel de segurana
especfico dado pelo valor de role-name deve ser utilizado como
identidade de segurana para a invocao do mtodo chamada pelo
EJB. Note que isto no muda a identidade do chamador (por
exemplo numa chamada de EJBContext.getCallerPrincipal()). No
lugar disto, os papis de segurana do chamador so configurados
para um nico papel especificado pelo valor do elemento runas/role-name. Um possvel uso para o elemento run-as para evitar
que clientes externos acessem EJBs internos. isto feito atribuindo
aos EJBs internos, elementos method-permission que restringe o
acesso a papeis que nunca sero atribudos a clientes externos.
EJBs que precisam usar EJB internos so ento configurados com
run-as/role-name apontando para o papel restrito aos componentes
internos.
Exemplo de descritor:
<!-- Um exemplo de ejb-jar.xml -->
<ejb-jar>
<enterprise-beans>
<sesion>
<ejb-name>UmSessionBean</ejb-name>
...
<security-identity>
<use-caller-identity/>
24/04/04 01:52:01
jp@psique.org http://www.psique.org/cursos
303
Segurana
Curso J150
</security-identity>
</session>
<sesion>
<ejb-name>ExecutarComoBean</ejb-name>
...
<security-identity>
<run-as>
<description>Um papel privado interno</description>
<role-name>PapelInterno</role-name>
</run-as>
</security-identity>
</session>
...
304
Segurana
Curso J150
305
Segurana
Curso J150
24/04/04 01:52:07
jp@psique.org http://www.psique.org/cursos
306
Segurana
Curso J150
<method>
<ejb-name>NomeEJB</ejb-name>
<method-name>metodo</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</method>
307
Segurana
Curso J150
<ejb-name>Pagamentos</ejb-name>
<method-name>getEmpregadoInfo</method-name>
</method>
<method>
<ejb-name>Pagamentos</ejb-name>
<method-name>updateMpregadoInfo</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</method>
</method-permission>
<method-permission>
<description>O papel do admin</description>
<role-name>admin</role-name>
<method>
<ejb-name>EmpregadoAdmin</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
<method-permission>
<description>Liberado para todos</description>
<unchecked/>
<method>
<ejb-name>EmpregadoHelp</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
<exclude-list>
<description>Nenhum mtodo com o nome
despedirOCheve do bean
DespedirEmpregado
pode ser usada neste deployment
</description>
<method>
<ejb-name>DespedirEmpregado</ejb-name>
<method-name>despedirOChefe</method-name>
</method>
</exclude-list>
</assembly-descriptor>
</ejb-jar>
24/04/04 01:52:13
jp@psique.org http://www.psique.org/cursos
308
Segurana
Curso J150
Segurana na WEB
Em uma aplicao Web, a segurana definida pelos papis
habilitados a acessar o contedo de um padro de URL (URL
Pattern) que identifica o contedo protegido. Este conjunto de
informaes declarado usando o arquivo web.xml com o elemtno
security-constraint. O contedo a ser seguro declarado usando um
ou mais elemtnos web-resource-collection. Cada elemento webresource-collection contm uma srie de elementos url-pattern
seguidos por uma srie opcional de elementos http-method. O valor
do elemento url-pattern especifica o padro da URL que precisa
combinar com o padro da requisio. O elemento http-method
especifica o tipo de requisio HTTP permitido.
O elemento opcional user-data-constraint especifica os requisitos
para a camada de transporte da conexo entre cliente e servidor.
Estes requisitos podem ser com relao integridade do contedo
(evitando que os dados sejam corrompidos no processo de
comunicao) ou para confidencialidade (prevenindo que sejam
lidos durante o trncito). O elemento transport-guarante especifica
o grau no qual a comunicao entre cliente e servidor deve ser
protegida. Os valores so: NONE, INTEGRAL ou CONFIDENTIAL. O
valor NONE significa que a aplicao no requer qualquer garantia
no transporte. O valor INTEGRAL significa que a aplicao requer
que os dados enviados entre o cliente e o servidor sejam enviados
de forma que no possam ser mudados no trnsito. O valor
CONFIDENTIAL significa que a aplicao requer que os dados
sejam transmitidos de forma a prevenir que sejam observados
durante a transmisso. Na maioria dos casos, a presena de
INTEGRAL ou CONFIDENTIAL indica que o uso de SSL requerido.
O elemento opcional login-config usado para configurar o mtodo
de autenticao que deve ser utilizado, a lista de nomes (realm) que
deve ser utilizada por esta aplicao e os atributos que so
necessrios pelo mecanismo de login. O elemento filho auth-method
especifica o mecanismo de autenticao para a aplicao Web.
Como um prerequisito para acessar qualquer recurso Web que se
24/04/04 01:52:15
jp@psique.org http://www.psique.org/cursos
309
Segurana
Curso J150
310
Segurana
Curso J150
</security-role>
</web0-app>
24/04/04 01:52:18
jp@psique.org http://www.psique.org/cursos
311
Segurana
Curso J150
312
Segurana
Curso J150
mdulo UsersRolesLoginModule
(org.jboss.security.auth.spi.UsersRolesLoginModule) ele suporta
mltiplos usurios e papis e e baseado em dois arquivos Java
Poperties. Um deles chamado user.properties e mapeia usurio
a senha (usuario=senha), o outro chamado roles.properties
mapeia usurios a papeis. Os arquivos de properties so carregados
durante a inicializao usando o mtodo initialize da thread do class
loader do contexto. Isto significa que estes arquivos podem ser
colocados no jar de deployment do J2EE, no diretrio de
configurao do JBoss ou em qualquer diretrio includo no JBoss
do servidor. O principal propsito deste mdulo simplicidade para
testes de segurana.
O arquivo users.properties utiliza um formato usuaro=senha onde
cada entra de usurio separada por uma linha
usuario1=senha1
usuario2=senha2
313
Segurana
Curso J150
jp.Roles=administrador,gerente
24/04/04 01:52:23
jp@psique.org http://www.psique.org/cursos
314
Transaes
Curso J150
Transaes
JTA Java Transaction API
Definio de Transao
Podemos definir uma transao como sendo uma unidade de
trabalho contendo uma ou mais operaes envolvendo um ou mais
recursos compartilhados tendo as propriedades ACID. ACID
significa Atomicidade, Consistncia, Isolamento e Durabilidade.
Uma transao uma unidade de trabalho, pode ser composta por
vrias operaes. No final a transao commitada se tudo der
certo. Se alguma operao intermediria falhar, tudo deve ser
desfeito e o estado, na medida do possvel, deve voltar a ser o do
incio da transao.
Estado inicial
Transao
Desfazimento (Roll-Back)
Falha
Sucesso
Estado final
Transao
efetivada
Atomicidade
Uma transao precisa ser atmica, ou seja indivisvel. Ou toda a
transao efetuada ou nada feito. Com isto no possvel que
apenas uma parte da transao seja feita. Em uma transferncia de
contas, o que se deseja : ou se faz o saque e o depsito ou no se
faz nada.
Consistncia
Quando uma transao termina, o sistema deve estar em um estado
24/04/04 01:52:25
jp@psique.org http://www.psique.org/cursos
315
Transaes
Curso J150
estvel e consistente.
Isolamento
Diferentes transaes deve ser isoladas umas das outras. Isto
significa que trabalho parcial feito em uma transao no pode ser
visto por outras at que a transao efetivada (comitada), e cada
processo em um sistema multi-usurio pode ser programado como
se fosse o nico processo acessando o sistema.
Durabilidade
As mudanas feitas durante uma transao sero feitas persistentes
quando a transao for efetivada (comitada).
Para exemplificar estes conceitos imagine uma transao para
efetuar a transferncia de fundos entre duas contas bancrias. A
transferncia envolve retirar o dinheiro de uma das contas e
depositar na outra.
S nos interessa o conjunto inteiro, saque + depsito, o sistema
ficaria inconsistente se somente uma das pernas da transao
fosse executada, isto explicita a atomicidade da transao, no
possvel dividi-la.
A consistncia significa que aps a transao a soma de ambos os
saldos deve continuar igual, ou seja, uma conta foi debitada em x, a
outra creditada em x, ento o total dos saldos deve permanecer
idntico.
O isolamento importante pois a nossa transao no pode sofrer
efeitos colaterais de outras transaes, imagine que para fazer o
saque da primeira conta temos um brevssimo intervalo de tempo
onde problemas podem ocorrer. Primeiro obtemos o saldo, depois
diminumos o valor, e em um terceiro passo atualizamos o valor do
24/04/04 01:52:27
jp@psique.org http://www.psique.org/cursos
316
Transaes
Curso J150
317
Transaes
Curso J150
back).
Na transferncia, o saldo salvo no incio, se antes de atualizar o
saldo o sistema notar que o saldo foi alterado, a transao vai falhar
e vai ser feito o desfazimento. Caso contrrio, o saldo final ser
salvo.
24/04/04 01:52:30
jp@psique.org http://www.psique.org/cursos
318
Transaes
Curso J150
O protocolo two-phase XA
Quando a transao est para ser efetivada, responsabilidade do
transaction manager ter certeza que tudo ser efetivado ou tudo
ser desfeito.
Quando muitos recursos estiverem envolvidos em uma transao, o
gerenciamento do commit fica mais complicado. No basta pedir
que cada recurso efetive suas alteraes, pois alguns podem
conseguir e outros no.
O protocolo two-phase XA utilizado para isto. O protocolo XA
acrescenta uma fase de preparao antes da fase de commit. Antes
de solicitar a efetivao das mudanas, o transaction manager pede
que cada recurso envolvido se prepare para o commit. Quando o
recurso sinalizar que est preparado para o commit da transao.
Ento a primeira fase consiste em solicitar aos recursos que fazem
parte da transao que se preparem para o commit. Se algum falhar
na preparao a transao ser desfeita. Mas se todos os recursos
sinalizarem que esto prontos para o commit, a segunda fase do
protocolo XA comea. A segunda fase quando o transaction
manager manda que cada um dos recursos efetivem a transao.
Como todos j sinalizaram que estavam preparados, este passo no
deve falhar.
Excees heursticas
Heurstica o mtodo de ensino que consiste em que o educando
24/04/04 01:52:32
jp@psique.org http://www.psique.org/cursos
319
Transaes
Curso J150
24/04/04 01:52:34
jp@psique.org http://www.psique.org/cursos
320
Transaes
Curso J150
24/04/04 01:52:36
jp@psique.org http://www.psique.org/cursos
321
Transaes
Curso J150
24/04/04 01:52:38
jp@psique.org http://www.psique.org/cursos
322
Transaes
Curso J150
insertMaquina(saldoMaquina);
ut.commit();
} catch (Exception ex) {
try {
ut.rollback();
saldoMaquina = estado;
} catch (SystemException e) {
throw new EJBException(Rollback falhou+e);
}
throw new EJBException(Transao falhou +ex);
}
}
Suporte a UserTransaction
A interface javax.transaction.UserTransaction permite aplicao
explicitamente controlar transaes. Para session beans que
gerenciam as transaes por s (BMT), um objeto UserTransaction
pode ser obtido chamando-se o mtodo getUserTransaction no
contexto do bean javax.ejbSessionContext.
Para beans BMT, no utilizar lookups JNDI para se obter a interface
UserTransaction. Fazer isto viola a especificao de EJB e o objeto
UserTransaction retornado no tem os acessos que o continer EJB
precisa para fazer checagens importantes.
Para usar a interface UserTransaction em outros lugares, o Mbean
24/04/04 01:52:40
jp@psique.org http://www.psique.org/cursos
323
Transaes
Curso J150
Mtodos de
javax.transaction.UserTransaction:
begin()
Inicia uma nova transao. Esta transao fica associada com a
thread corrente.
commit()
Executa o protocolo de two-phase commit em uma transao
existente associada com a thread corrente. Cada gerenciador de
recurso ir efetivar as alteraes.
getStatus()
Retorna o estado da transao associada com esta thread.
rollback()
Fora o rollback de uma transao associada com a thread corrente.
setRollbackOnly()
A chamada a este mtodo far com que esta transao seja desfeita.
setTransactionTimeout(int)
Indica o mximo tempo em milissegundos que a transao pode
24/04/04 01:52:41
jp@psique.org http://www.psique.org/cursos
324
Transaes
Curso J150
Constantes
STATUS_ACTIVE
Indica que a transao est ocorrendo e ativa.
STATUS_NO_TRANSACTION
No existe transao no momento
STATUS_MARKED_ROLLBACK
A transao est ocorrendo mas est marcada para ser desfeita. Isto
pode ter sido ocorrido por uma chamda do mtodo setRollbackOnly
();
STATUS_PREPARING
A transao corrente est se preparando para ser efetivada
(durante a fase 1 do protocolo two-phase commit).
STATUS_PREPARED
A transao corrente est preparada para a efetivao (fase 1
completa)
STATUS_COMMITING
A transao corrente est em processo de efetivao. (durante a
fase 2)
24/04/04 01:52:43
jp@psique.org http://www.psique.org/cursos
325
Transaes
Curso J150
STATUS_COMMITED
A transao terminou de efetivar (acabou a fase 2)
STATUS_ROLLING_BACK
A transao corrente est em processo de desfazimento.
STATUS_ROLLEDBACK
A transao corrente terminou o processo de desfazimento.
STATUS_UNKNOWN
O estado da transao corrente no pode ser determinado.
24/04/04 01:52:45
jp@psique.org http://www.psique.org/cursos
326
Transaes
Curso J150
<assembly-descriptor>
<container-transaction>
<method>...</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
...
</assembly-descriptor>
Exemplo de ejb-jar.xml
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>BancoEJB</ejb-name>
<home>j2eetut.bank.BancoHome</home>
<remote>j2eetut.bank.Banco</remote>
<ejb-class>j2eetut.bank.BancoBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>BancoEJB</ejb-name>
<method-name>getSaldoPoupanca</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assemby-descriptor>
</ejb-jar>
NotSupported
Supports
Required
RequiresNew
24/04/04 01:52:47
jp@psique.org http://www.psique.org/cursos
327
Transaes
Mandatory
Never
Curso J150
Required
Indica que o mtodo deve ser chamado em uma transao. Se no
existir transao, uma nova transao ser criada, se j existir uma
transao, a nova chamada far parte do escopo da transao
anterior.
Supports
Indica que o mtodo suporta transaes. Ser includo no escopo da
transao se existir uma, se no existir no ser criada transao.
RequiresNew
Indica que uma nova transao deve ser iniciada para a chamada do
motodo. Havendo ou no transao, uma nova ser iniciada.
NotSupported
Indica que o mtodo no suporta transaes. Se o mtodo for
chamado no escopo de uma transao, a mesma ser suspensa
enquanto durar a execuo do mtodo.
Mandatory
Indica que o mtodo s pode ser chamado no escopo de uma
transao pr-existente. Se for chamado fora de transao, ser
lanada uma exceo do tipo
javax.transaction.TransactionrequiredException.
24/04/04 01:52:49
jp@psique.org http://www.psique.org/cursos
328
Transaes
Curso J150
Never
Indica que o mtodo nunca pode ser chamado durante uma
transao. Se houver uma chamada durante uma transao, ser
lanada uma RemoteException (ou EJBexception em clientes locais).
Atributo de
Transa o
Stateless
Stateful
Session Bean Session Bean
imple m e n t a n
do Session
Synchroni z a t
ion
Required
Sim
Sim
RequiresNew Sim
Sim
Mandatory
Sim
Sim
Supports
Sim
No
NotSuppor te d Sim
No
Never
Sim
No
Entity Bean
Sim
Sim
Sim
No
No
No
Sim
No
No
No
Sim
No
Excees
A especificao de J2EE classifica as excees em System
exceptions e Application exceptions. As System exceptions so
excees que indicam erros no servidor e servios usados pela
aplicao, so instncias de RemoteException e RuntimeException.
Causam rollback automtico de transaes. As Application
exceptions so excees que indicam erro na lgica da aplicao.
So subclasses de Exception que no so System exceptions. No
causam rollback pois o continer no pode avaliar se a exceo
grave o suficiente para provocar o rollback.
O servio de transaes indispensvel para garantir a integridade
dos dados. melhor utilizar CMT (Continer-Manager Transaction)
sempre que possvel, pois mais simples, menor risco de deadlock e
gargalos, facilita a separao de papis e a especializao. O
deployer pode ajustar a poltica de transaes ao ambiente onde
24/04/04 01:52:51
jp@psique.org http://www.psique.org/cursos
329
Transaes
Curso J150
Session Synchronization
As vzes, o continer no tem como automticamente desfazera lgo
que tenha sido feito. Um EMail enviado por exemplo, no tem como
ser desfeito. Variveis de instncia em Statefull SessionBeans
tambm no tem seu estado restaurado em caso da transao
falhar. Uma soluo para estes casos implementar
SessionSynchronization:
public class ContadorBean implements SessionBean,
SessionSynchronization {
public int val;
public int oldVal;
public void ejbCreate(int val) {
this val = val;
this.oldVal = val;
}
// Chamado antes de comear a transao
public void afterBegin() {
oldVal = val;
}
// Chamado antes do commit
public void beforeCompletion() {
}
// Chamado logo aps o commit
public void afterCompletion(boolean b) {
// b o indicativo de sucesso ou falha
if ( ! b )
val = oldVal; // Se falhar, acerte o valor
// do atributo de instncia
}
public int count() {
24/04/04 01:52:52
jp@psique.org http://www.psique.org/cursos
330
Transaes
return
}
public void
public void
public void
public void
Curso J150
++val();
ejbRemove() {}
ejbActionvate() {}
ejbPassivate() {}
setSessionContext(SessionContext ctx) {}
24/04/04 01:52:54
jp@psique.org http://www.psique.org/cursos
331
Curso J150
Anexo 1 Cluster no
JBoss
O application server JBoss suporta cluster de uma forma quase
automtica. O primeiro prottipo surgiu em abril de 2001 foi
codificado por Sacha Labourey. Bill Burke juntou-se a Sacha em
Agosto de 2001 e juntos refizeram do zero o que hoje o sistema de
cluster do JBoss.
O que um cluster?
Um cluster um conjunto de ns com um objetivo comum. Um n
pode ser um computador, ou, uma instncia de um servidor (caso
em que vrias instncias de servidores existem em um nico
servidor).
No JBoss o clusterring tem dois objetivos:
1 Tolerncia a falhas
2 Balanceamento de carga.
JNDI
RMI
24/04/04 01:52:56
jp@psique.org http://www.psique.org/cursos
332
Curso J150
Entity Beans
Parties
Um cluster um conjunto de ns. No JBoss um n uma instncia
de um servidor. Vrias instncias podem ser agrupadas em uma
partio. Em uma rede, podemos ter diferentes parties. Para
diferenci-las, cada partio tem um nome.
Partio B
Partio A
JBoss
N 1
JBoss
N 5
JBoss
N 2
JBoss
N 6
JBoss
N 3
JBoss
N 7
JBoss
N 4
JBoss
N 8
JBoss
N 9
Partio C
Rede
24/04/04 01:52:58
jp@psique.org http://www.psique.org/cursos
333
Curso J150
24/04/04 01:52:59
jp@psique.org http://www.psique.org/cursos
334
Curso J150
Descoberta de ns 'Automgica'
Com os clusteres do JBoss, no existe a necessidade de definir a
topologia do cluster. As nicas informaes interessantes so: O
nome do cluster (o nome da partio). Depois que o nome da
partio for configurado, qualquer node pode dinamicamente
juntar-se ou deixar a partio.
Configurando o JBoss
Cada n participante do cluster deve ter ao menos uma partio.
Um n pode participar em mais de um cluster iniciando vrias
parties, cada uma com um nome diferente, mas o normal que
um n participe de apenas uma partio. Evidentemente cada
partio consome recursos, por isto, limitar a quantidade de
parties uma boa idia.
O JBoss vm com trs configuraes para o servidor: minimal,
default e all. A opo de clustering est apenas habilitada na
configurao all. Um arquivo chamado cluster-service.xml no
diretrio deploy descreve a configurao para a partio default do
cluster - DefaultPartition. Este xml l o MBean para parties e
inicializa o JGroups e alguns outros componentes.
Veja a definio de clustering:
<mbean code=org.jboss.ha.framework.server.ClusterPartition
name=jboss:service=DefaultPartition/>
335
Curso J150
Quando um cliente remoto faz um lookup para um HA-JNDI, o HAJNDI ir delegar para um contexto JNDI local quando no for
possvel encontrar o objeto no cluster global. Ento, um EJB home
lookup para um HA-JNDI, ser sempre delegado para uma instncia
local de JNDI.
Na implementao corrente, HA-JNDI funciona com sua prpria
rvore JNDI global no cluster, bem como uma rvore JNDI local
disponvel no JBoss.
24/04/04 01:53:03
jp@psique.org http://www.psique.org/cursos
336
Curso J150
ClientesHAJNDIeautodescoberta
Quando trabalhamos s com um servidor JBoss, a configurao do
JNDI bem simples: Precisamos saber unicamnete o nome do
servidor ou o endereo IP e o porto do servidor JNDI.
Quando trabalhamos com um cluster de servidores, a configurao
no to simples. Qual servidor estar sendo executado? Se
pudessemos saber isto, no precisaramos de cluster. Como no
sabemos, a propriedade java.naming.provider.url pode aceitar uma
lista de urls separadas por vrgula.
java.naming.provider.url=servidor1:1100,servidor2:1100,serv
idor3:1100,servidor4:1100
24/04/04 01:53:05
jp@psique.org http://www.psique.org/cursos
337
Curso J150
24/04/04 01:53:06
jp@psique.org http://www.psique.org/cursos
338
Curso J150
Anexo 2 Criando um
session bean no WSAD
da IBM
Abaixo um passo a passo visual sobre como criar um bean utilizando
o WSAD 5.1.1 (IBM - Websphere Studio Application Developer).
O primeiro passo criar um projeto EJB:
24/04/04 01:53:08
jp@psique.org http://www.psique.org/cursos
339
Curso J150
24/04/04 01:53:10
jp@psique.org http://www.psique.org/cursos
340
Curso J150
24/04/04 01:53:12
jp@psique.org http://www.psique.org/cursos
341
Curso J150
24/04/04 01:53:14
jp@psique.org http://www.psique.org/cursos
342
Curso J150
24/04/04 01:53:16
jp@psique.org http://www.psique.org/cursos
343
Curso J150
24/04/04 01:53:17
jp@psique.org http://www.psique.org/cursos
344
Curso J150
24/04/04 01:53:20
jp@psique.org http://www.psique.org/cursos
345
24/04/04 01:53:22
jp@psique.org http://www.psique.org/cursos
Curso J150
346
Curso J150
24/04/04 01:53:23
jp@psique.org http://www.psique.org/cursos
347
Curso J150
Quem quem:
BusinessObject
Representa os dados do cliente. o objeto que requer acesso
origem dos dados para obter os dados. Um objeto de negcio pode
ser implementado como um session bean, um entity bean, ou algum
outro objeto java, em adio a um servlet ou helper para acessar a
origem dos dados.
24/04/04 01:53:26
jp@psique.org http://www.psique.org/cursos
348
Curso J150
DataAccessObject
O DataAccessObject o objeto principal deste pattern. O
DataAccessObject abstrai as implementaes de acesso a dados
para o BusinessObject para habilitar acesso transparente aos dados.
O BusinessObject delega a leitura e gravao de dados para o
DataAccessObject.
DataSource
a representao da origem dos dados. Um data source pode ser
um banco de dados RDBMS, OODBMS, XML, arquivo sequencial,
arquivo serializado, ou qualquer outra possibilidade. Um data
source pode ser tambm um outro sistema (legado/mainframe),
servio (B2B, Webservice), ou algum tipo de repositrio (LDAP por
exemplo).
ValueObject ou TransferObject
a representao do objeto utilizado para transportar os dados
entre componentes. O DataAccessObject pode usar VOs (ou DTOs)
para retornar dados ao cliente. O DataAccessObject pode tambm
receber os dados do cliente em um VO para alterar os dados no data
source.
24/04/04 01:53:27
jp@psique.org http://www.psique.org/cursos
349
Curso J150
Estratgias
Automatic DAO Code Generation Strategy
J que cada BusinessObject corresponde a um DAO especfico,
possvel estabelecer relacionamentos entre o BusinessObject, DAO e
fonte de dados. Uma vez que os relacionamentos estiverem
estabelecidos, possvel escrever uma aplicao para gerao de
cdigo automtica para acesso aos dados. Os metadados para gerar
o DAO podem vir de um descritor escrito pelo desenvolvedor.
Alternativamente, o cdigo pode automaticamente analisar o banco
de dados para prover os DAOs para acessar o banco de dados.
350
Curso J150
24/04/04 01:53:31
jp@psique.org http://www.psique.org/cursos
351
Curso J150
Conseqncias
Possibilita Transparncia
Os Business objects podem usar o data source sem conhecer os
detalhes da implementao do data source. Acessar
transparentemente porque os detalhes esto escondidos no DAO.
Facilita Migrao
Uma camada de DAOs torna mais fcil a uma aplicao migrar para
uma implementao de banco de dados diferente. Os objetos de
negcio no conhecem a implementao da base de dados. A
migrao implica to somente em alterar a camada dos DAOs. Se
estiver implementado com Factory, possibilita prover
implementaes de fbricas concretas para cada tipo de
implementao de persistncia. Ento a migrao pode se resumir
criao de uma nova fbrica e implement-la na aplicao.
24/04/04 01:53:33
jp@psique.org http://www.psique.org/cursos
352
Curso J150
353
Curso J150
24/04/04 01:53:38
jp@psique.org http://www.psique.org/cursos
354
Curso J150
24/04/04 01:53:40
jp@psique.org http://www.psique.org/cursos
355
Definies, acrnimos e
abreviaes
Curso J150
Definies, acrnimos e
abreviaes
ACL
EJB
MOM
RMI
24/04/04 01:53:42
jp@psique.org http://www.psique.org/cursos
356
Definies, acrnimos e
abreviaes
Curso J150
RMI-IIOP
24/04/04 01:53:44
jp@psique.org http://www.psique.org/cursos
357
Definies, acrnimos e
abreviaes
Curso J150
Bibliografia
Tutorial do J2EE
ROMAN, Ed e AMBLER, Scott, Mastering Enterprise Java Beans
Ed Roman
LABOUREY, Sacha e BURKE, Bill. JBoss AS Clustering. Atlanta, GA:
JBoss Group.
24/04/04 01:53:47
jp@psique.org http://www.psique.org/cursos
358