O documento descreve uma introdução ao Java EE 5 e às mudanças entre EJB 2.1 e EJB 3.0. Ele apresenta os pré-requisitos e referências para o curso, a ementa do curso, as principais especificações do Java EE 5, as diferenças em relação ao J2EE e as características e limitações do EJB 2.1 em comparação com o EJB 3.0.
2. Audiência, pré-requisitos e
referências
Audiência
Desenvolvedores que desejam aprender sobre a plataforma JEE
Pré-requisitos
Desenvolvedores com pelo menos 1 ano de experiência em sistemas
distribuídos, usando tecnologia Java (web/cliente servidor)
Referências (material de apoio)
EJB 3.0 - livro: Mastering Enterprise JavaBeans Third Edition – ISBN-10:
0764576828
Disponível para download, gratuito, no site http://www.theserverside.com
Possui código fonte disponível (exemplos)
http://www.theserverside.com/tt/books/wiley/masteringEJB/index.tss
JPA -
http://www.theserverside.com/tt/articles/content/JPA101_Chapter/article.htm
l
NetBeans IDE – versão 5.5.1
http://www.netbeans.org/
3. Ementa do curso
Introdução à conteiners EJB e a necessidade de ambientes distribuídos
Plataforma Java EE e Containers EJB
JBoss Application Server
Introdução ao Java EE 5
Java EE 5 – Especificações
Java EE 5 x J2EE - Diferenças
EJB 2.1 x EJB 3.0 – O que mudou?
EJB 2.1 – Características
EJB 2.1 – Limitações
EJB 3.0 – Características
EJB 3.0 – Especificações
EJB 3.0 – Novidades
EJB 3.0 - Interoperabilidade com EJB 2.x
4. Ementa do curso
Stateless Session Beans
Statefull Session Beans
SessionBeans e WebServices
Introdução à JPA
Serviço de Email
Introdução a JMS e Message Driven Beans
EJB 3.0 - Transações
Segurança com JAAS
EJB Timers e Interceptors
6. Introdução à containers EJB e a
necessidade de ambientes distribuídos
Plataforma Java EE e Containers EJB
A plataforma Java EE é baseada em um modelo de componentes bem
definido, robusto, escalável e em constante evolução. Cada
componente da plataforma Java EE tem como foco objetivos
específicos de uma aplicação corporativa, e dessa forma tais
componentes executam em um ambiente de execução especial,
conhecido como container Java EE.
Um servidor de aplicações Java EE possui basicamente dois tipos de
container: o container Web onde são disponibilizados e executados os
componentes Servlet e JSP, responsáveis pela camada de
apresentação de uma aplicação corporativa, e o container EJB onde são
executados os componentes Enterprise Java Beans, responsáveis pelas
regras de negócio e de acesso a dados de uma aplicação corporativa.
O primeiro benefício direto dessa divisão é permitir aos
desenvolvedores focar nas características específicas de um
determinado componente e ambiente de execução e também
7. Introdução à containers EJB e a
necessidade de ambientes distribuídos
Entretanto, o maior benefício resultante dessa abordagem é poder tirar
proveito de toda a infra-estrutura de serviços que um servidor de
aplicações Java EE (e seus containers) oferece, possibilitando obter de
forma transparente suporte para vários serviços tais como segurança,
controle de transações, resource pooling (instâncias de objetos,
conexões e outros), controle automático do ciclo de vida dos
componentes e outros, evitando a recorrência dessa preocupação em
projetos e permitindo aos desenvolvedores focar na implementação
das regras de apresentação, navegação, integração e regras de
negócios específicas de uma determinada solução, de acordo com o
nicho de negócios específico que uma solução deve atender
(financeira, telecomunicações, agronegócios e outros).
O slide seguinte mostra a arquitetura típica de um servidor de
aplicações, destacando os containers Web e EJB e os serviços e APIs
que suportam os componentes que executam nesses containers.
8. Introdução à containers EJB e a
Data
necessidade de ambientes distribuídos JDBC
Application Logic
RDBMS
Client
JavaMail
HTML/ Web Container
XML Mail Server
Servlets JSPs J2EE RMI
Application
Server Java Application
RMI/IIOP
JavaMail
JDBC
JNDI
JMS
JTA
JAF
Applet
EJB Container IIOP
Session Beans Entity Beans
CORBA
Client JNDI
Application
RMI/IIOP
JavaMail
JDBC
JNDI
JMS
JTA
JAF
Directory Services
JMS
Message Queue
9. Introdução à containers EJB e a
necessidade de ambientes distribuídos
Considerando especificamente os componentes Enteprise Java Beans,
desde a primeira versão da especificação EJB esse modelo de
componentes considera a necessidade de execução e suporte a um
ambiente distribuído, onde componentes específicos executam em
camadas distintas e tem responsablidades bem definidas.
Como consequência, para obter a confiabilidade e robustez que são
requisitos mais cruciais de uma aplicação corporativa, um ambiente
distribuído deve suportar vários aspectos tais como suporte a chamada
remota de métodos (RPC-Remote Procedure Call), balanceamento de
carga (load-balancing), suporte à falhas (failover), operação em
cluster, controle de transações e execução concorrente, apenas para
citar alguns aspectos importantes.
Como já foi citado anteriormente, tais questões são endereçadas de
forma transparente por um servidor de aplicações Java e, obviamente,
por um container EJB.
10. Introdução à conteiners EJB e a
necessidade de ambientes
distribuídos
JBoss Application Server
JBoss é um servidor de aplicação Java EE certificado para o
desenvolvimento e disponibilização de aplicações Java
Enterprise, sendo que o mesmo nasceu como um projeto Open-
source, logo no início da especificação de Enteprise Java Beans.
Na época, estavam disponíveis apenas containers Web sendo o
mais conhecido o Tomcat e então foi criado o projeto EJBOSS
(EJB Open-Source Software) e posteriormente o seu criador
mudou o nome do projeto para JBOSS.
Atualmente é considerado o servidor de aplicações líder de
mercado, com o maior número de deployments mundialmente,
sendo que o JBoss Group agora é parte da Red Hat, que
adquiriu o mesmo em 2006.
O JBoss é o servidor de aplicações utilizado para a realização
12. Introdução ao Java EE 5
“O Java EE 5 reduz significativamente o custo e a
complexidade para o desenvolvimento e
disponibilização de soluções multi-camadas, resultando
em serviços que podem ser disponibilizados e
extendidos de forma simples e rápida” - Sun
Microsystems
O Java EE 5 define uma especificação que engloba
outras especificações que são componentes da
plataforma Java EE 5, sendo essa especificação
chamada de “umbrella”
Java Platform, Enterprise Edition 5 (Java EE 5) - JSR-
244
13. Java EE 5 - Especificações
APIS WebServices
Implementing Enterprise Web Services
JSR-109 - http://jcp.org/en/jsr/detail?id=109
Java API for XML-Based Web Services (JAX-WS) 2.0
JSR-224 - http://jcp.org/en/jsr/detail?id=224
Java API for XML-Based RPC (JAX-RPC) 1.1
JSR-101 - http://jcp.org/en/jsr/detail?id=101
Java Architecture for XML Binding (JAXB) 2.0
JSR-222 - http://jcp.org/en/jsr/detail?id=222
SOAP with Attachments API for Java (SAAJ)
JSR-67 - http://jcp.org/en/jsr/detail?id=67
Streaming API for XML
JSR-173 - http://jcp.org/en/jsr/detail?id=173
Web Service Metadata for the Java Platform
JSR-181 - http://jcp.org/en/jsr/detail?id=181
14. Java EE 5 - Especificações
APIs Web
Java Servlet 2.5
JSR-154 - http://jcp.org/en/jsr/detail?id=154
JavaServer Faces 1.2
JSR-252 - http://jcp.org/en/jsr/detail?id=252
JavaServer Pages 2.1
JSR-245 - http://jcp.org/en/jsr/detail?id=245
JavaServer Pages Standard Tag Library
JSR-52 - http://jcp.org/en/jsr/detail?id=52
15. Java EE 5 - Especificações
APIs Enterprise (inclui EJB 3.0)
Enterprise JavaBeans 3.0
JSR-220 - http://jcp.org/en/jsr/detail?id=220
J2EE Connector Architecture 1.5
JSR-112 - http://jcp.org/en/jsr/detail?id=112
Common Annotations for the Java Platform
JSR-250 - http://jcp.org/en/jsr/detail?id=250
Java Message Service API
JSR-914 - http://jcp.org/en/jsr/detail?id=914
17. Java EE 5 - Especificações
APIs de Segurança e Gerenciamento
J2EE Application Deployment
JSR-88 - http://jcp.org/en/jsr/detail?id=88
J2EE Management
JSR-77 - http://jcp.org/en/jsr/detail?id=77
Java Authorization Contract for Containers
JSR-115 - http://jcp.org/en/jsr/detail?id=115
18. Java EE 5 x J2EE - Diferenças
J2EE, poderoso mas complexo
Java EE 5 mantêm as capacidades da plataforma, mas agora de
forma muito mais simples e produtiva, sendo esse o foco
principal da JSR-24
Características do Java EE 5
Uso de Annotations
Alteraa forma como as bibliotecas e as ferramentas tratam
o código
Conventions (or container defaults)
O desenvolvedor deixa a maior parte do trabalho de
configuração para os containers, que fornecem um conjunto
bem definido de valores default, que foram convencionados
levando em conta os casos mais comuns
19. Java EE 5 x J2EE - Diferenças
Características do Java EE 5
Dependency Injection
“Do not call me, I will call you”. As dependências são
injetadas automaticamente nos componentes pelo
container, com ajuda das annotations. Não é preciso buscar
os recursos explicitamente
Deployment Descriptors são opcionais
“boilerplate code” ficou obsoleto e os deployment
descriptors são opcionais
Mecanismo Leve de Persistência
JPA - Modelo de persistência unificado, não limitado a EJBs.
As classes podem ser usadas em outros componentes,
inclusive fora do servidor de aplicação. As Entities agora são
classes POJO, (Plain Old Java Object), suportando conceitos
20. Java EE 5 x J2EE - Diferenças
Características do Java EE 5
Entity Manager API
Principal mudança do Java EE 5, considerando a interação
com banco de dados. O EM gerencia o ciclo de vida e estado
das entities, suportando CRUD, pesquisa, execução de
queries (inclusive dinâmicas), mecanismo de vinculação,
liberação e unificação (attach/detach/merge)
JP-QL – Java Persistence QL
O antigo EJB-QL 2.1 foi melhorado e agora suporta: named
queries, queries com named parameters, dynamic queries,
bulk updates e deletes. O JP-QL também suporta queries SQL
nativas
Característicasherdadas dos “concorrentes” – JBoss
Hibernate, Oracle Toplink, JDO
22. EJB 2.1 x EJB 3.0 – Diferenças
EJB 2.1 - Características
Apesar da especificação EJB 2.1 possuir recursos poderosos
(mas ainda assim ser incompleta), a mesma é muito complexa
Muitas classes e interfaces que devem ser implementadas
JNDI lookups – não existe DI
Uso de interfaces do pacote javax.ejb
Modelo de programação confuso
Deployment Descriptors (DDs) são obrigatórios
Vários anti-patterns - Entity Beans
23. EJB 2.1 x EJB 3.0 – Diferenças
EJB 2.1 - Limitações
Para criar um EJB simples você precisar criar vários DDs,
geralmente um definido pela especificação e um proprietário,
de acordo com servidor de aplicação alvo
Um conjunto de três arquivos-fonte (pelo menos) deve ser
criado
Múltiplos métodos callback devem ser implementados e alguns
possivelmente nem serão usados
Você tem que arremesar e tratar vários tipos de exceções,
desnecessariamente
Os EJBs não podem ser testados fora do container;
EJB-QL é limitada e difícil de usar, forçando a utilização de JDBC
e SQL ou outro mecanismo de persistência para cobrir as
24. EJB 2.1 x EJB 3.0 – Diferenças
EJB 3.0 - Características
Facilidade no desenvolvimento, simplicidade
Poucas classes e interfaces, uso de POJOs (Plain Old Java
Objects) e POJI (Plain Old Java Interfaces)
Dependency Injection (sem JNDI lookups)
Não requer implementação de interfaces específicas
Não requer deployment descriptors (opcional)
Mecanismo de persistência simplificado
Mapeamento O/R robusto e com suporte a conceitos OO
(herança, polimorfismo, etc)
25. EJB 2.1 x EJB 3.0 – Diferenças
EJB 3.0 - Especificações
JSR-000220 Enterprise JavaBeans 3.0 – FR (Final Release) –
Specifications
As especificações foram segmentadas visando facilitar o aprendizado
por parte dos desenvolvedores de aplicações, bem como a
implementação dos containers EJB por parte dos desenvolvedores de
servidores de aplicações (Vendors)
Desenvolvedores de aplicações que desejam usar EJB 3.0 para
aplicações comerciais, corporativas
Enterprise JavaBeans 3.0 Final Release (ejbcore)
ejb-3_0-fr-spec-ejbcore.pdf
Enterprise JavaBeans 3.0 Final Release (persistence)
ejb-3_0-fr-spec-persistence.pdf
Enterprise JavaBeans 3.0 Final Release (simplified)
ejb-3_0-fr-spec-simplified.pdf
26. EJB 2.1 x EJB 3.0 – Diferenças
EJB 3.0 - Especificações
Desenvolvedores que desejam construir um container que
implementa as especificações de EJB 3.0
Enterprise JavaBeans 3.0 Final Release (ejbcore)
ejb-3_0-fr-spec-ejbcore.pdf
Enterprise JavaBeans 3.0 Final Release (persistence)
ejb-3_0-fr-spec-persistence.pdf
Enterprise JavaBeans 3.0 Final Release (simplified)
ejb-3_0-fr-spec-simplified.pdf
27. EJB 2.1 x EJB 3.0 – Diferenças
EJB 3.0 - Novidades
DI – Dependency Injection
Os recursos são injetados quando a instância é construída.
Referências para:
EJBContext
DataSources
UserTransaction
Environment Entries
EntityManager
TimerService
Outros EJBs
28. EJB 2.1 x EJB 3.0 – Diferenças
EJB 3.0 - Novidades
Visão do cliente (client view) simplificada
Session beans agora usam interfaces Java simples
Não requer EJB(Local)Home interfaces
Não requer EJB(Local)Object interfaces
A classe do bean (bean class) é uma classe Java simples,
portanto:
É uma classe Java plana (POJO)
Implementa interfaces Java comuns (POJI)
29. EJB 2.1 x EJB 3.0 – Diferenças
EJB 3.0 - Novidades
JPA – Java Persistence API
Simplifica
o modelo de programação de entidades (agora
chamadas de entities e não entity beans)
Suporte para modelagem OO, incluindo herança e
polimorfismo
Endereça as limitações anteriores que existiam para as
queries EJB-QL
Suportamapeamento O/R de forma robusta e com várias
abordagens
As entidades podem ser usadas (e testadas) fora do
container
Remove a necessidade de usar alguns patterns, como
30. EJB 2.1 x EJB 3.0 – Diferenças
EJB 3.0 - Novidades
JPA – Mapeamento O/R
Facilidadepara que os desenvolvedores Java executem o
mapeamento de um modelo de objetos para um banco
relacional
Odesenvolvedor fica seguro sobre o mapeamento entre o
DB Schema e o modelo de domínio dos objetos
O desenvolvedor controla o mapeamento da forma como
quiser, restrito ao modelo do banco
Osmapeamentos podem ser expressos usando annotations
ou XML
31. EJB 2.1 x EJB 3.0 – Diferenças
EJB 3.0 - Novidades
JPA – Entity Manager
O EntityManager serve como uma interface “home”
genérica, considerando as operações que envolvem entities
Possui métodos para gerenciamento do ciclo de vida do
bean
Persist, remove, merge, flush, refresh, etc
Funcionalidadesimilar ao Hibernate Session, JDO
PersistenceManager e outros similares
32. EJB 2.1 x EJB 3.0 – Diferenças
EJB 3.0 - Interoperabilidade com EJB 2.X
Aplicações escritas usando a API EJB 2.1 e anteriores funcionam
sem alterações nos containers EJB 3.0 (backward compatibility)
Flexibilidade para migração de containers
Novas aplicações usando EJB 3.0 podem ser clientes de EJBs
antigos (specs anteriores), sem mudanças na visão do
cliente pré-existente
33. EJB 3.0 – exercício
Iniciar o IDE NetBeans e selecionar File > New
Project > Enterprise > Enterprise Application.
Definir o nome do projeto como JavaEEcomEJB3.0,
selecionar o servidor Jboss Application Server 4,
selecionar a Java EE version como Java EE 5,
aceitar o checkbox que define os nomes para os
projetos web (Create Web Application Modue) e ejb
(Create EJB Module). Clicar em Finish (próximo
slide). Os projetos Enteprise (Java EE 5), EJB 3.0 e
Web serão mostrados na aba Projects do NetBeans
(slide seguinte).
37. Stateful Session Beans - definição
Independente da versão de EJB em questão (EJB 2.x. ou 3.0),
geralmente um session bean é um componente reusável que
possui serviços (métodos) que suportam uma determinada regrada
de negócio. Os serviços desse session bean são definidos
basicamente pela sua interface de negócio (business interface),
que por sua vez também passou a ser um POJI.
Um stateless session bean, como o próprio nome diz, não guarda
estado entre duas invocações de um dos seus métodos, sendo que
um mesmo cliente poderá usar duas instâncias diferentes de um
session bean quando chamando um mesmo método,
consecutivamente, não há garantia que uma mesma instância será
usada para um mesmo cliente (o container mantém um pool de
instâncias do stateless session bean).
38. Stateless Session Beans - definição
Dessa forma, o importante é lembrar que um stateless
session bean não armazenará estado entre duas
chamadas de método e que dessa forma, todo o estado
que um determinado método de negócio necessita para
operar corretamente deve ser passado na chamada ao
método.
No contexto específico da especificação EJB 3.0, um
stateless session bean passou a ser basicamente um
POJO, com a diferença que esse POJO também pode ser
gerenciado pelo container e não exige a implementação
de interfaces específicas, como javax.ejb.SessionBean.
39. Stateless Session Beans - definição
Uma referência indireta (stub) para um stateless session
bean pode ser recuperada através do nome da interface,
utilizando um busca (lookup) no contexto JNDI ou então pode
ser injetado (dependency injection) através da anotação
@EJB, sendo essa a grande novidade do EJB 3.0. No caso,
não é mais necessário ter uma Home interface como era o
caso de versões de EJB anteriores ao EJB 3.0.
As interfaces de negócio de um session bean podem ser
declaradas como remotas ou locais - @Remote ou @Local,
dependendo da anotação que for usada na classe do bean e
como default será definida como local caso não seja
especificada nenhuma anotação.
40. Stateless Session Beans –
implementação
Um stateless session bean deve possuir a anotação
@Stateless, ou então deve ser definido como Stateless
através do uso do deployment descriptor, como na
versão EJB 2.x.
Como dito anteriormente, a classe do bean não precisa
mais implementar a interface javax.ejb.SessionBean.
No slide seguinte temos um exemplo de definição de
um stateless session bean (POJO), bem como de uma
interface de negócio (POJI). Observe as anotações
@Stateless, @Local e @Remote.
41. Stateless Session Beans –
implementação
...
@Stateless
public class ServidorFacade implements ServidorFacadeLocal {
@PersistenceContext
private EntityManager em;
public ServidorFacade() {
}
public void create(Servidor servidor) {
em.persist(servidor);
}
public void edit(Servidor servidor) {
em.merge(servidor);
}
...
42. Stateless Session Beans –
implementação
...
@Local
public interface ServidorFacadeLocal {
void create(Servidor servidor);
void edit(Servidor servidor);
void destroy(Servidor servidor);
Servidor find(Object pk);
List findAll();
List findAllIds();
}
...
43. Stateless Session Beans – exercício
1) Completar o código da classe StatelessSessionBean disponível na pasta /src da estrutura de
projeto, incluindo as anotações necessárias para definição de um SLSB.
Incluir as anotações @Stateless, @Remote, @Local;
Compilar o código de forma que não apresente erros, empacotar as classes e efetuar o deploy na pasta
JBOSS_HOME/server/default/deploy do servidor JBoss.
2) Usar o NetBeans para criar SLSB com nome StatelessSessionBean. Seguir os passos abaixo,
detalhados nos slides que seguem:
Selecione o pacote do projeto EJB com botão direito,, selecionar New > Session Bean;
Definir o pacote como com.synos.treinamento.sjeeejb3;
Definir o nome do bean como StatelessSessionBean;
Selecionar os checkboxes para interfaces Remote e Local;
Clicar em Finish. Será exibido o código para o SLSB, observe a anotação @Stateless.
Adicionar um método de negócio, clicar no código com botão direito > EJB Methods > Add Business
method;
Compilar e empacotar o código usando o NetBeans;
Realizar o deploy do EJB. Todos os passos estão detalhados nos slides seguintes.
50. Stateful Session Beans - definição
Um stateful session bean tem a capacidade de manter estado
entre duas chamadas de métodos, ou seja, se um cliente de um
stateful session bean estiver usando uma mesma referência (stub)
entre duas chamadas de método, há a garantia de que as
chamadas serão atendidas por uma mesma instância de um SFSB.
Existe um relacionamento um para um entre um SFSB e o cliente
do mesmo.
A interface de negócio de um stateful session bean que usa a
versão 3.0 da especificação de EJB também é uma POJI (Plain Old
Java Object). A interface também pode ser definida como local ou
remota - @Local ou @Remote - da mesma forma que é feito para
os stateless session bean e também será definida por default como
local caso não haja nenhuma anotação.
51. Stateful Session Beans - definição
Da mesma forma que os stateless session bean, não é mais necessário ter
uma Home interface como era o caso de versões de EJB anteriores ao EJB
3.0.
SFSB podem implementar a interface SessionSynchonization, o que
permite o stateful ter informações sobre o estado da transação no qual ele
está participando, como por exemplo ser informado sobre uma transação
que falhou, através de chamadas aos metódos da interface. No caso, só é
possivel implementar essa interface caso a aplicação esteja usando
Container Managed Transactions (CMT). Esse assunto será discutido
posteriormente durante o curso. Abaixo temos os três métodos dessa
interface:
void afterBegin() throws EJBException, RemoteException
void beforeCompletion() throws EJBException,RemoteException
void afterCompletion(boolean committed) throws EJBException,
RmoteException
52. Stateful Session Beans -
implementação
A implementação de um SFSB também é bem simples. Basta
anotar a classe do bean com a anotação @Stateful e para ter a
manutenção de estado entre chamadas, criar varíaveis de
instância para armazenar o mesmo.
É importante ressaltar que a classe do bean precisa implementar a
interface java.io.Serializable (bem como todas as variáveis de
instãncia), de forma que o bean possa ser passivado (serializado)
quando as instâncias não estiverem sendo utilizadas, permitindo
ao container gerenciar seus recursos de forma mais adequada,
bem como ser ativado (deserializado).
O desenvolvedor pode definir métodos arbitrários e marcá-los com
as anotações @PrePassivate e @PostActivate, sendo que os
mesmos serão chamados antes da passivação e após a ativação de
um SFSB.
53. Stateful Session Beans -
implementação
...
@Stateful
public class ServidorFacade implements ServidorFacadeLocal {
String cluster;
public ServidorFacade() {
}
public void setCluster(String cluster) {
this.cluster = cluster;
}
public String getCluster() {
return this.cluster;
}
...
54. Stateful e Stateless Session Beans
– métodos callback
Existem métodos que permitem um session bean incorporar pontos de extensão aos
eventos do ciclo de vida (criação, destruição, passivação, ativação) normal do
mesmo, de forma que possa ser executado código específico na ocorrência desses
eventos. Os métodos bem como a descrição dos mesmos estão listados abaixo:
@PostConstruct: o método com essa anotação será chamado pelo container
logo após a instanciação do bean. Essa anotação é válida para stateless e
stateful session beans;
@PreDestroy: o método com essa anotação será chamado pelo container antes
do container destruir uma instância do bean presente no pool de instâncias.
Essa anotação é válida para stateless e stateful session beans;
@PrePassivate: o método com essa anotação é chamado antes do container
passivar uma instância de um stateful session bean. Essa anotação é válida
apenas para statefull session beans;
@PostActivate: o método com essa anotação é chamado assim que um bean
que estava passivado se tornar ativo novamente. Essa anotação é válida apenas
para statefull session beans.
55. Stateful Session Beans – exercício
1) Completar o código da classe StatefulSessionBean disponível na pasta /src da estrutura de
projeto, incluindo as anotações necessárias para definição de um SFSB.
Incluir as anotações @Stateless, @Remote, @Local;
Compilar o código de forma que não apresente erros, empacotar as classes e efetuar o deploy na pasta
JBOSS_HOME/server/default/deploy do servidor JBoss.
2) Usar o NetBeans para criar SFSB com nome StatefulSessionBean. Seguir os passos abaixo,
detalhados nos slides que seguem:
Selecione o pacote do projeto EJB com botão direito,, selecionar New > Session Bean;
Definir o pacote como com.synos.treinamento.sjeeejb3;
Definir o nome do bean como StatefulSessionBean;
Selecionar os checkboxes para interfaces Remote e Local;
Clicar em Finish. Será exibido o código para o SFSB, observe a anotação @Stateful;
Adicionar um atributo e um método de negócio que usa o atributo, clicar no código com botão direito > EJB
Methods > Add Business method;
Compilar e empacotar o código usando o NetBeans;
Realizar o deploy do EJB. Todos os passos estão detalhados nos slides seguintes.
60. Session Beans e Web Services
O suporte a Web Services foi introduzido na especificação EJB a partir da versão 2.1
e com a especificação EJB 3.0 o suporte ficou ainda mais simples e direto
Para expor os serviços de um componente stateless session bean como um
WebService basta incluir a anotação @WebService bem como expor os serviços
(métodos) desse Web Service utilizando a anotação @WebMethod, sendo essa
última anotação opcional e caso a mesma não seja especificada todos os métodos
públicos da classe do Web Service serão expostos como serviços
O arquivo WSDL com a descrição do WebService será gerado automaticamente pelo
container. Uma discussão mais abrangente sobre o conceito de Web Services e SOA
está além do escopo desse curso, por se tratar de um assunto bem extenso.
O empacotamento do serviço utiliza um arquivo ejb-jar normal, comum para
qualquer componente EJB e se não forem usadas as anotações indicadas, ainda sim
é possível utilizar um arquivo webservice.xml detalhando o mapeamento do Web
Service e dos serviços (métodos que ele oferece, bastando incluir o arquivo
webservice.xml a pasta META-INF do pacote ejb-jar.
O próximo slide apresenta um exemplo de classe com as anotações necessárias
para expor um componente EJB stateless session bean como Web Service.
61. Session Beans e Web Services
...
@Stateless
@WebService(serviceName=”MyServer”, portName=”MyServerPort”)
public class ServidorFacade implements ServidorFacadeLocal {
@PersistenceContext
private EntityManager em;
public ServidorFacade() {
}
public void create(Servidor servidor) {
em.persist(servidor);
}
@WebMethod
public void edit(Servidor servidor) {
em.merge(servidor);
}
62. Session Beans e Web Services -
exercício session bean StatelessSessionBean como WebService utilizando as
1) Expor o stateless
anotações @WebService e @WebMethod. Completar as anotações nó código da pasta
/src e conferir o resultado com o código da solução.
2) Usar o NetBeans para expor o stateless session bean StatelessSessionBean como
WebService.
Compilar e empacotar o código usando o NetBeans;
Realizar o deploy do EJB. Todos os passos estão detalhados nos slides seguintes.
65. JPA – Java Persistence API
Esse capítulo introduz a JPA – Java Persistence API e suas principais caractéristicas e
anotações, no contexto do curso de EJB 3.0, que trata também outras APIs da
especificação. Para um estudo detalhado da JPA, aconselhamos o curso Java
Persistence Architecture (SJPA) 20 h, também ministrado pela Synos.
A Java Persistence API (JPA) fornece um padrão para utilização de POJOs (Plain Old
Java Objects) como entidades que representam dados de em uma tabela de banco
de dados, através de um mecanismo de mapeamento objeto-relacional. A JPA
aproveitou muitos conceitos e padrões que já eram adotados por outros
mecanismos de persistência level como Hibernate e Toplink, por exemplo.
Entretanto, um dos grandes benefícios da JPA é que ela é um padrão definido pelo
JCP, dentro do escopo da especificação de EJB 3.0 (JSR-220). Outros benefícios são
listados abaixo:
Simplificação significativa das APIS para mapeamento O/R e persistência
As entities pode ser executadas (e consequentemente testadas) fora do
container EJB
Suporte a conceitos OO tais como como herança e polimorfismo
Introdução da JP-QL, que melhora bastante o suporte a execução de queries
66. JPA – Java Persistence API
Entities
Entidade é uma classe que representa uma tabela em um
mecanismo de persistência de dados, podendo ser
persistida e posteriormente recuperada (não-volátil)
As entidades são classes POJO simples com anotações e
não requerem mais a implementação de interfaces
específicas
Toda entidade deve ter um construtor padrão (no-
arguments constructor)
Toda entidade possui uma chave primária (identity), pode
ser persistida e recuperada (persistability) e pode
participar em uma transação (transactionability)
67. JPA – Java Persistence API
Entities
Abaixo temos um exemplo de entidade utilizando as
anotações @Entity, @Column e @Id:
@Entity(name = "MOBILE_ENTITY")
class MobilePhoneEntity{
public MobilePhoneEntity() {} //no-arg constructor
@Column(name = “MOBILE_MODEL”, nullable = true, length = 35)
private String model;
@Column(name = “MOBILE_MANUFACTURER” nullable = true, length = 100)
private String manufacturer;
private Double price;
@Id
@Column(name = “MOBILE_IMEI_NO”, nullable = false)
private String imeiNumber;
68. JPA – Java Persistence API
Entities
A Chave primária (@Id) pode ser simples ou composta
Para suportar chaves-compostas deve ser definida uma
classe para representar a chave-composta
A chave primária pode ser atribuída pelo
desenvolvedor ou gerada automaticamente usando a
anotação @GeneratedValue
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String imeiNo;
69. JPA – Java Persistence API
Entities – Ciclo de Vida
70. JPA – Java Persistence API
Entities – Ciclo de Vida
New
Quando a instância da entidade foi criada usando a palavra-chave new
Não possui Id
Managed
Quando a instância da entidade tem um Id associado a um contexto de
persistência
Removed
Quando a instância da entidade tem um id persistente associado a um
contexto de persistência
A instância está marcada indicando que o registro deve ser excluído do
banco de dados
Detached
Quando a instância da entidade tem tem um id persistente, mas não está
associada a um contexto de persistência
71. JPA – Java Persistence API
Entities – Herança
Abaixo estão especificadas as três estratégias de herança que podem
ser utilizadas:
Single Table Strategy
Todas as classes na hierarquia são mapeadas para uma tabela única,
utilizando um campo descriminador para identificar uma classe
específica
Table Per Class Strategy
Cada classe na hierarquia é mapeada para uma tabela e todas as
propriedades das classes são mapeadas para colunas da tabela
correspondente
Joined Subclass Strategy
A tabela raiz da hierarquia é representada por uma tabela e cada
subclasse é representada por uma tabela separada que contém campos
específicos para a subclasse e também campos que representam as
chaves primárias
72. JPA – Java Persistence API
Detached Entities
Entidades desacopladas não estão associadas a um
contexto de persistência
Uma entidade deve obrigatoriamente implementar a
interface Serializable se ela for trafegar na rede
(chamadas remotas)
Asentidades desacopladas tornaram os design patterns
DTO/TO/VO obsoletos
Deveser usado o método merge() para tonar a entidade
managed novamente
73. JPA – Java Persistence API
Entities – EntityManager
O EntityManager é a interface que o desenvolvedor possui para
controlar o ciclo de vida da entidade, através dos métodos abaixo:
new()
Cria uma nova entidade
persist()
Persiste uma entidade
refresh()
Atualiza o estado da entidade
remove()
Marca uma entidade para remoção
merge()
Sincroniza o estado de entidades desacopladas
74. JPA – Java Persistence API
EntityManager - criação
Em uma aplicação Java EE, o EntityManager pode ser
injetado pelo container.
@Resource
private EntityManager entityManager;
Em uma aplicação Java SE, o Entity manager pode ser
obtido através da interface EntityManagerFactory e da
classe Persistence
EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory(“PersistentUnitNam
e”);
EntityManagereManager =
entityManagerFactory.createEntityManager();
75. JPA – Java Persistence API
EntityManager e Query
O EntityManager também é uma factory para objetos que
implementam a interface Query, que permite realizar
pesquisas customizadas
createQuery()
retorna uma instância de query usando JP-QL
createNamedQuery()
retorna uma instância de query identificada
createNativeQuery()
retorna uma instância de query usando SQL nativo
76. JPA – Java Persistence API
Queries
Melhorias implementadas na JP-QL
Suporte a Group By e Having
Sub-queries
Suporte a novas funções SQL
UPPER, LOWER, TRIM, CURRENT_DATE e outras
Funções SQL adicionais
Joins
Consultas polimórficas
Suporte consultas dinâmicas (Dynamic Queries) e
consultas nomeadas (Named Queries)
77. JPA – Java Persistence API
Queries - exemplos
Dynamic Queries
public List findWithName (String name) {
return em.CreateQuery (
“SELECT c FROM Customer c” +
“WHERE c.name LIKE :custName”)
.setParameter(“custName”, name)
.setMaxResults(10)
.getResultList();
}
Named Queries
@NamedQuery(
name=“findCustomersByName”,
queryString=“SELECT c FROM Customer c” +
“WHERE c.name LIKE :custName”
)
@PersistenceContext public EntityManager em;
List customers = em.createNamedQuery(“findCustomersByName”).setParameter(“cust
Name”, “smith”).getResultList();
78. JPA – Java Persistence API
Mapeamento O/R
A JPA possui várias anotações que permitem efetuar o
mapeamento objeto-relacional de forma bem flexível
Relacionamentos entre entidades (tabelas)
Junções (Joins)
Tabelas e colunas
Estruturasde banco de dados (sequences, colunas
auto-increment)
79. JPA – Java Persistence API
Mapeamento O/R - relacionamentos
Os relacionamentos entre as entidades podem ser
definidos utilizando as anotações abaixo
@OneToOne
@OneToMany
@ManyToOne
@ManyToMany
80. JPA – Java Persistence API
Mapeamento O/R – operações em cascata
Permitir propagar o alcance de uma operação para
afetar entidades relacionadas
As operações em cascada ocorrem somente quando
as
entidades estão associadas ao PersistenceContext
Cascade=PERSIST
Cascade=REMOVE
Cascade=MERGE
Cascade=REFRESH
Cascade=ALL
81. JPA – Java Persistence API
Persistence Context
Um Persistence Context trabalha em conjunto com o
EntityManger para gerenciar um conjunto definido de entidades
Ele cuida das mudanças que uma entidade pode sofrer,
suportando o Entity Manager nas tarefas de commit e rollback
de alterações
Quanto um EntityManager é criado, ele está implicitamente
associado a um Persistence Context
Existem dois tipos de Persistence Context
Persistence Context com escopo de transação – o tempo de vida
desse PC depende do tempo de vida de uma transação (para um
grupo de entities em um ponto específico no tempo)
Persistence Context extendido – o PC vai existir mesmo após a
execução de uma transação e as entities permanecem associadas
82. JPA – Java Persistence API
Persistence Unit
Uma persistence unit fornece um agrupamento lógico para um grupo de
entidades que devem compartilhar uma mesma configuração
Um arquivo persistence.xml file é utilizado para gerenciar uma ou mais
persistence units.
Cada persistence unit é configurada com um provedor junto com um data-
source JDBC e um grupo de entities associado. Exemplo:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="mobile-broker-ejbPU" transaction-type="JTA">
<jta-data-source>java:/MobileBrokerDS</jta-data-source>
<properties/>
</persistence-unit>
</persistence>
83. JPA – Java Persistence API – exercício
1) Completar o código da classe MyEntity disponível na pasta /src da estrutura de projeto,
incluindo as anotações necessárias para definição de uma Entity.
Incluir a anotação @Entity;
Conferir o resultado na pasta /solucoes;
2) Usar o NetBeans para criar uma Entity com nome MyEntity.
Selecione o pacote do projeto EJB com botão direito,, selecionar New > Entity Class;
Definir o pacote como com.synos.treinamento.sjeeejb3;
Definir o nome do bean como MyEntity e clicar no botão Create Persistence Unit;
Selecionar o datasource JavaEEcomEJB3.0, disponibilizado previamente na pasta
JBOSS_HOME/server/default/deploy – arquivo java-ee-com-ejb-3-ds.xml.
Selecionar também o radio button Drop and Create, que vai criar e dropar as tabelas no banco de dados
MySQL, conforme a entidade vá sofrendo alterações (cria todo o DDL para as operaões no banco). Clicar
em Create;
Clicar em Finish. Observe as anotações @Entity, @Id e @GeneratedValue;
Compilar e empacotar o código usando o NetBeans;
Realizar o deploy do EJB. Todos os passos estão detalhados nos slides seguintes.
88. Introdução a JMS e Message-
Driven Beans
JMS – Java Message Service
JMS é um padrão de mensageria desenvolvido com o intuito de
endereçar algumas desvantagens apresentadas por outros
padrões de mensageria. O JMS tem basicamente duas partes,
uma API que o desenvolvedor utiliza para enviar e receber
mensagens e uma SPI – Service Provider Interface – utilizada
para permitir a integração de diferentes tipos de
implementações (providers) JMS.
Uma implementação específica possui os detalhes que são
necessários para realizar a integração a um MOM (Message-
Oriented Middleware) específico, sendo que um provider JMS
trabalha com um conceito parecido com o dos drivers JDBC
(interfaces genéricas com implementações específicas).
89. Introdução a JMS e Message-
Driven Beans
JMS – Java Message Service
Existem dois tipos de modelos de mensageria, Publish-
Subscribe (Topics) e Point-to-Point (Queues):
Publish-Subscribe – Com esse modelo, você pode ter muitos
produtores para uma mensage em tembém muitos consumidores
da mensagem, caracterizando uma implementação de um modelo
distribuído para propogação de eventos. Os subscribers registram
seu interesse em receber um determinado evento e os publishers
criam os eventos que serão propagados, sendo que ambos utilizam
um Topic.
Point-to-Point – Com esse modelo, você poderá ter apenas um
consumidor para cada mensagem enviada. Vários consumidores
podem pegar mensagens de uma mesma Queue, mas a mensagem
será consumida apenas uma vez, por apenas um dos
consumidores.
90. Introdução a JMS e Message-
Driven Beans
MDB – Message-Driven Bean
Message-driven beans não possuem uma interface de negócios
(business interface), ou seja, não é possível invocar diretamente
um MDB. Entretanto, o MDB deve implementar uma interface
chamada javax.jms.MessageListener, que por sua vez possui
um método onMessage(Record inputData).
No EJB 3.0, a classe do MDB deve usar a anotação
@MessageDriven, que especifica a Queue ou Topic que um MDB
deve utilizar. Como dito anteriormente, a classe do bean
também deve implementar a interface MessageListener e
sobrescrever o método onMessage(). Quando uma mensagem
chega a Queue ou Topic no qual o MDB está vinculado, o
container invoca o método onMessage() do bean e passa a
mensagem enviada como um argumento para o método.
91. Introdução a JMS e Message-
Driven Beans
MDB – Message-Driven Bean
Message-driven beans não possuem uma interface de negócios
(business interface), ou seja, não é possível invocar diretamente um
MDB. Entretanto, o MDB deve implementar uma interface chamada
javax.jms.MessageListener, que por sua vez possui um método
onMessage(Record inputData).
No EJB 3.0, a classe do MDB deve usar a anotação @MessageDriven,
que especifica a Queue ou Topic que um MDB deve utilizar. Como dito
anteriormente, a classe do bean também deve implementar a interface
MessageListener e sobrescrever o método onMessage(). Quando uma
mensagem chega a Queue ou Topic no qual o MDB está vinculado, o
container invoca o método onMessage() do bean e passa a mensagem
enviada como um argumento para o método.
No próximo slide temos um exemplo de MDB implementando conforme
o contrato da interface MessageListener e as anotações
correspondentes e posteriormente um exemplo de um cliente JMS,
92. Introdução a JMS e Message-
Driven Beans
@MessageDriven(activateConfig = {@ActivationConfigProperty
(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="queue/mdb") })
public class EmailBean implements MessageListener {
public void onMessage (Message msg) {
try {
TextMessage tmsg = (TextMessage) msg;
Timestamp sent = new Timestamp(tmsg.getLongProperty("sent"));
... ...
} catch (Exception e) {
e.printStackTrace ();
}
}
// ... ...
}
93. Introdução a JMS e Message-
Driven Beans
Cliente JMS – envio de mensagens
Para enviar uma mensagem para uma Queue (e
consequentemente para um MDB), o cliente JMS deve usar
as classes da API padrão JMS para obter uma referência
para a Queue alvo, através do nome da queue
(queue/mdb) e então enviar a mensagem.
Os passos são idênticos quando utilizando um Topic ao
invês de uma Queue, mudando basicamente a interface
utilizada bem como as classes Factory.
95. Introdução a JMS e Message-
Driven Beans
Message-Drive Beans - Callbacks
Os MDBs podem trabalhar com os callbacks abaixo,
discutidos anteriormente
@PostConstruct: o método com essa anotação
será chamado pelo container logo após a
instanciação do bean.
@PreDestroy: o método com essa anotação será
chamado pelo container antes do container
destruir uma instância do bean presente no pool
de instâncias.
96. Message-Driven Beans – exercício
1) Completar as anotações nó código do bean MessageDrivenBean na
pasta /src e conferir o resultado com o código da pasta solucoes;
2) Usar o NetBeans para criar um message-driven bean que deverá estar
vinculado a queue/A, pré-configurada pelo servidor JBoss um MDB. Seguir
os passos abaixo, detalhados nos slides que seguem:
Selecione o pacote do projeto EJB com botão direito, New > Message-
Driven Bean;
Usar o pacote com.synos.treinamento.ejb3.biz.control;
Definir o nome do bean como MessageDrivenBean;
Compilar e empacotar o código usando o suporte do NetBeans ao
desenvolvimento de EJBs;
Realizar o deploy do EJB e criar um cliente JMS simples que enviará
uma mensagem para a queue/A, que por sua vez será consumida pelo
MDB MessageDrivenBean.
99. EJB 3.0 - Transações
Transações – Introdução
O suporte a transações é uma característica chave de um
servidor de aplicações Java. Ele garante a integridade do
sistema mesmo em caso de falhas na rede ou no hardware de
comunicação.
Geralmente a lógica de uma aplicação requer que todas as
atualizações consecutivas em um banco de dados sejam bem
sucedidas, caso contrário não deve ocorrer nenhum update e
devemos iniciar novamente a operação. A API de EJB 3.0 tornou
muito fácil a declaração de atributos de transação em um POJO
através do uso de anotações. Na realidade, as transações tem
um papel importante na interação entre session beans e
message-driven beans.
100. EJB 3.0 - Transações
Gerenciamento de transações
As transações de um EJB podem ser gerenciadas de três
formas:
Container – o desenvolvedor especifica os atributos de
gerenciamento e atributos de transação e o container fica
responsável por implementar a lógica de gerenciamento de
acordo com a parametrização informada. O gerenciamento é
realizado no lado do servidor;
Bean – o desnvolvedor fica responsável por fornecer toda a
lógica de gerenciamento da transação, incluindo os commits
e rollbacks explícitos. O gerenciamento é realizado no lado
do servidor;
Cliente – o desenvolvedor fica responsável por fornecer a
lógica do gerenciamento no cliente, que utiliza a interface
UserTransaction para realizar as operações de commit e
101. EJB 3.0 - Transações
Gerenciamento de transações – configuração
No EJB 3.0, existem anotações que permitem configurar
quem ficará responsável pelo gerenciamento da
transação:
O gerenciamento da transação é configurado com a
anotaçãoo @TransactionManagementType, sendo que
essa anotação deve ser especificada no nível da classe.
O atributo value pode assumir os valores abaixo:
TransactionManagementType.CONTAINER: o
container gerencia as transações (default).
TransactionManagementType.BEAN: o bean
gerencia as transações.
102. EJB 3.0 - Transações
Gerenciamento de transações
O exemplo abaixo mostra o uso da anotação
TransactionManagementType:
@Stateful
@TransactionManagement(value=TransactionManagementType.CONTAIN
ER)
public class CartBean implements Cart {
private ArrayList items;
...
}
103. EJB 3.0 - Transações
Anotações para controle de transações
Em aplicações EJB 3.0, se o método requer uma
transação, todas as operações no método, incluindo
atualizações no banco de dados só são efetivadas se o
método retornar normalmente, sem falhas.
Se uma exceção não tratada é lançada nesse método (ou
em métodos que o método invoca), o gerenciador de
transações desfaz todas as mudanças realizadas.
A anotação utilizada para delcarar os atributos da
transação é a @TransactionAttribute.
104. EJB 3.0 - Transações
A anotação @TransactionAttribute pode receber os seguintes
argumentos:
REQUIRED: o método anotado é executado dentro de uma transação. Se o
método chamador já está dentro de uma transação, a transação é utilizada. Se
não, uma nova transação é iniciada.
MANDATORY: O método anotado tem que ser invodcado no contexto de uma
transação (o metódo chamador deve ter uma transação, obrigatoriamente).
Caso contrário, um erro é lançado.
REQUIRES_NEW: O método anotado é chamado dentro de uma nova transação.
Se o chamador já possuir uma transação, ela é suspendida.
SUPPORTS: Se o método anotado é chamado a partir de uma transação, a
transação é utilizada. Se ele for chamado sem uma transação, nenhuma
transação será iniciada.
NOT_SUPPORTED: Se o método anotado for chamado a partir de uma transação,
um erro será lançado.
105. EJB 3.0 - Transações
No EJB 3.0, o EntityManager tem que executar em um contexto
transacional para assegurar a integridade do banco de dados. O
transaction manager sempre sincroniza o banco de dados quando ele
realiza o commit, ou antes da próxima query. É possível chamar o método
EntityManager.flush() para forçar os updates na mémória para o banco de
dados, no meio de uma transação.
Uma transação falha quando a aplicação lança uma RuntimeException ou
uma ApplicationException. Abaixo temos um exemplo de como definir uma
ApplicationException (exceção customizada pelo desenvolvedor):
@ApplicationException(rollback=true)
public class TransException extends Exception {
public TransException () { }
}
106. EJB 3.0 - Transações
Quando uma transação falha, o banco de dados é restaurado
para o estado antes da transação, mesmo se o contexto de
persistência tiver sido forçado antes da transação terminar e
todos os objetos entity bean gerenciados são detachados
No exemplo abaixo, é gerada uma instância de classe que
representa uma ApplicationException dentro do método
updateExchangeRate(). Como o método foi declarado como
transacional, a exceção causa o cancelamento de todos as
operações executadas.
107. EJB 3.0 - Transações
@Stateless
public class CalculatorBean implements Calculator {
@PersistenceContext
protected EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void updateRate (double newrate) throws Exception {
...
// Emulate a failure
double prob = Math.pow (0.5, 1./size);
if (Math.random() > prob) {
// Emulated failure causes rollback
throw new TransException ();
// Or one can throw a RuntimeException to trigger the rollback operation
}
}
}
108. EJB 3.0 - Transações – exercício
1) Declarar o método add do stateless session bean StatelessSessionBean
com a anotação @NotSupported. Completar as anotações nó código da
pasta /src e conferir o resultado com o código da solução.
2) Usar o NetBeans para declarar o método add do stateless session bean
StatelessSessionBean com a anotação @NotSupported
Compilar e empacotar o código usando o NetBeans;
Realizar o deploy do EJB;
Criar um client simples e chamar o método add, verificar a exceção
que será informada, o que indica que o atributo foi respeitado.
111. Segurança com JAAS
Segurança na plataforma Java EE
A plataforma Java EE define contratos bem definidos entre quem
desenvolve os componentes de uma aplicação e quem configura as
aplicações no ambiente de execução.
O desenvolvedor deve declarar os requisitos de segurança para a
aplicação, que devem ser satisfeitos durante a sua configuração. Os
mecanismos de segurança declarativa usados numa aplicação são
definidos no documento de deployment descriptor de uma unidade de
disponibilização do Java EE (arquivos .WAR, .EAR, .JAR). Cada container
mapeia os requisitos da aplicação para os mecanismos que segurança
implementados pelo container, de forma que a infra-estrutura oferecida
pelo servidor de aplicação seja aproveitada.
A arquitetura de segurança do Java EE possibilita a propagação de forma
transparente das credenciais de segurança de um determinado usuário
entre os componentes de uma aplicação Java EE. Em outras palavras, se o
usuário se logar em uma página web, não precisará se autenticar
novamente para acessar um componente EJB a partir daquela página, onde
112. Segurança com JAAS
Segurança Java EE - Autenticação
A autenticação em servidores Java EE utiliza os seguintes
conceitos:
Realm (domínio) – Uma coleção de usuários e grupos
que são controlados por uma mesma política de
autenticação;
User (usuário) – A identidade de um indivíduo (ou
programa);
Group (grupo) – Um conjunto de usuários autenticados;
Role (papel) – Um nome abstrato para a permissão de
acesso a um conjunto particular de recursos numa
aplicação.
113. Segurança com JAAS
JAAS - Java Authentication and Authorization Service
Java Authentication and Authorization Service (JAAS) é um
conjunto de APIs que permitem a autenticação e autorização de
usuários e forçam o controle de acesso aos recursos de um
sistema.
O JAAS implementa a versão Java do padrão Pluggable
Authentication Module (PAM). Esse padrão permite que as
aplicações se mantenham independentes da tecnologia de
autenticação usada, sendo que novos módulos podem ser .
Adicionados sem necessidade de modificações na aplicação.
A implementação usada para a autenticação é determinada em
tempo de execução através das configurações em um arquivo
de login, como por exemplo o arquivo login-config.xml presente
na pasta JBOSS_HOME/server/default/conf do servidor JBoss.
114. Segurança com JAAS
JAAS - Java Authentication and Authorization Service
No JAAS, um Subject (javax.security.auth.Subject) é uma
entidade em um sistema, que será autenticada e para a qual
serão atribuídas permissões. Um subject pode ser qualquer
entidade, como uma pessoa ou um processo.
Principals representam as identidades do Subject. Devem
implementar as interfaces java.security.Principal e
java.io.Serializable e são distinguidos pelo seu nome. Quando
um subject é autenticado, ele é povoado com um ou mais
principals. Por exemplo, um subject pode ter como identidade o
seu CPF.
Groups são conjuntos de Principals. A interface
java.security.acl.Group é subinterface de java.security.Principal,
o que significa de que um grupo também é uma identidade do
115. Segurança com JAAS
JAAS - Autenticação
A autenticação no JAAS é feita através do contexto de
segurança (javax.security.auth.login.LoginContext), identificado
por um nome único. Para um contexto são definidos um ou mais
módulos de login (classes que implementam a interface
javax.security.auth.spi.LoginModule).
Os módulos de login são os responsáveis pela implementação
da tecnologia de autenticação. O exemplo mais comum é a
autenticação baseada em usuário e senha, mas outros módulos
poderiam autenticar o usuário, por exemplo, baseado em
chaves de segurança, biometria e outros. O LoginModule pode
comparar essas informações com dados em um banco de
dados, servidor LDAP, arquivos texto, XML ou qualquer outro
repositório de usuários.
116. Segurança com JAAS
JAAS - Autenticação
O programador da aplicação não precisa se preocupar com o
funcionamento do LoginModule. Deve saber apenas como
especificar, através de um arquivo de configuração, qual o
módulo será usado para autenticar o usuário em um
determinado security domain.
Para que o LoginModule se comunique com o usuário e obtenha
informações de autenticação, a aplicação usa um
javax.security.auth.callback.CallbackHandler. A aplicação
implementa um CallbackHandler e o passa para o LoginContext,
que o passará aos módulos. Esses LoginModules usarão o
CallbackHandler para solicitar entrada de dados ao usuário e
enviar informações. Cada CallbackHandler pode implementar
sua própria interface com o usuário, podendo ser, por exemplo,
textual, gráfica, formulário web e outras.
117. Segurança com JAAS
JAAS - Autenticação
A interface CallbackHandler define apenas o método abaixo:
void handle(Callback[] callbacks) throws java.io.IOException,
UnsupportedCallbackException;
O LoginModule passa para o método handle um vetor de
Callbacks (veja o pacote javax.security.auth.callback), como o
NameCallback (requisição de nome do usuário),
PasswordCallback (requisição de senha do usuário) e
TextOutputCallback (informação ao usuário) e o
CallbackHandler implementa a interação com o usuário
necessária para contemplar as ações requisitadas.
118. Segurança com JAAS
JAAS - Autenticação
O diagrama de seqüência no slide seguinte mostra a
sequência de autenticação com o JAAS. O JAAS Client é a
aplicação que usará o JAAS, MyCallbackHandler é a
implementação de CallbackHandler específico para a
aplicação. LoginContext é uma classe do sistema (não
será implementado pela aplicação) e SomeLoginModule é
um LoginModule qualquer configurado para a aplicação
(pode ser implementado pela própria aplicação ou por
terceiros).
Após o sucesso da autenticação, a aplicação obtém um
objeto javax.security.auth.Subject chamando o método
getSubject() de LoginContext. Esse objeto conterá os
120. Segurança com JAAS
Segurança Java EE - Autorização
A autorização de acesso a recursos no J2EE é feita através de
roles. Para um recurso ou conjunto de recursos é definido a role
necessária ao usuário para que este tenha acesso liberado.
Caso o usuário não esteja autenticado, um novo login poderá
ser exigido. Podem ser usados dois tipos de segurança:
Segurança Declarativa: as roles são definidas no deployment
descriptor (DD) e autorizam acesso aos recursos Java EE. A
ligação das roles aos usuários é feita pelos containers Java
EE.
Segurança Programática: quando a segurança declarativa não é
suficiente, pode-se usar componentes de segurança da linguagem
para implementar os requisitos necessários.
121. Segurança com JAAS
Segurança Java EE - Autorização
Controle de acesso a EJBs
O controle de acesso aos EJBs é definido especificando-se no
arquivo /META-INF/ejb-jar.xml as roles existentes e quais são
os roles necessários para permitir ao usuário o acesso aos
métodos do bean, ou então através das anotações
introduzidas no EJB 3.0.
Abaixo temos um exemplos de configuração de permissão
usando o DD e também uma explicação sobre as anotações
para configuração de permissões.
122. Segurança com JAAS
Segurança Java EE - Autorização
Controle de acesso a EJBs - ejb-jar.xml
<ejb-jar>
<assembly-descriptor>
<security-role>
<role-name>AuthorizedEJBUser</role-name>
</security-role>
<method-permission>
<role-name>AuthorizedEJBUser</role-name>
<method>
<ejb-name>Information</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getInformacoes</method-name>
<method-params>
</method-params>
</method>
123. Segurança com JAAS
Segurança Java EE - Autorização
Controle de acesso a EJBs – ejb-jar.xml (continuação)
<method>
<ejb-name>Information</ejb-name>
<method-intf>Home</method-intf>
<method-name>create</method-name>
<method-params>
</method-params>
</method>
</method-permission>
...
</assembly-descriptor >
...
</ejb-jar>
124. Segurança com JAAS
Segurança Java EE - Autorização
Controle de acesso a EJBs – anotações
O EJB 3.0 fornece anotações para especificar as opções de
segurança, sendo que as anotações abaixo foram introduzidas na
versão 3.0 da especificação:
* @SecurityRoles
* @MethodPermissions
* @Unchecked
* @Exclude
* @RunAs
125. Segurança com JAAS
Segurança Java EE - Autorização
Controle de acesso a EJBs – anotações
O exemplo abaixo mostra um EJB simples, um SLSB chamado PingEjb e também
inclui uma checagem de autorização.
@Remote({Ping.class})
@Stateless
public class PingEjb implements Ping {
@PermitAll
public String pingPermitAll() {
return "PingEjb: pingPermitAll";
}
@DenyAll
public String pingPermitAll() {
return "PingEjb: pingDenyAll";
}
@RolesAllowed({"staff"})
public String ping() {
return "PingEjb: ping";
}
}
126. Segurança com JAAS
Segurança Java EE - Autorização
Controle de acesso a EJBs – anotações
Noexemplo, note as três anotações de segurança no bean PingEjb:
@PermitAll,
@DenyAll, and @RolesAllowed. No caso, o Java EE 5 introduziu cinco
anotações, restando também as anotações @DeclareRoles e
@RunAs.
@PermitAll – todos os roles podem invocar métodos
@DenyAll – nenhum role pode acessar os métodos
@RolesAllowed – no exemplo, somente usuários com role “staff”
podem acessar o método
Vejamos outro exemplo de como proteger os métodos de um EJB
3.0:
127. Segurança com JAAS
Segurança Java EE - Autorização
@RunAs(value="staff")
@DeclareRoles({"staff", "temporary"})
@RolesAllowed({"ttrole"})
@Stateless
public class HelloEjb implements Hello {
@Resource private SessionContext sc;
@EJB private Ping ping;
}
128. Segurança com JAAS
Segurança Java EE - Autorização
public String hello() {
if (!sc.isCallerInRole("staff") &&
!sc.isCallerInRole("temporary")) {
return "HelloEjb: hello";
} else {
throw new RuntimeException(
"of role staff or temporary");
}
@RolesAllowed({"myrole"})
public String ping() {
return ping.ping();
}
}
129. Segurança com JAAS
Segurança Java EE - Autorização
Existem duas anotações @RolesAllowed no exemplo HelloEjb, um
no nível da classe, outro no nivel do método.
A anotação @RolesAllowed no nível da classe se aplica a todos os métodos de
negócio do bean. Entretanto, ela pode ser sobreposta por uma anotação
específica para um método, no nível do método, se ela existir. Observe que o
método ping está sujeito a uma anotação no nível de método
@RolesAllowed({"myrole"}).
A anotação @RunAs especifica um role para invocações subsequentes dentro de
um método, mas não para invocações diretas do método em questão. No
exemplo, HelloEjb.ping() invoca o método Ping.ping() como um usuário de role
"staff" ao invés de usar o role do usuário logado.
A anotação @DeclareRoles é utilizada para definir roles utilizadas pelo
componente. No HelloEjb, os roles "staff" e "temporary" podem ser usados pela
chamada isCallerInRole() dentro do método hello.
130. EJB 3.0 - Transações – exercício
1) Declarar o método add do stateless session bean StatelessSessionBean
com a anotação @DenyAll. Completar as anotações nó código da pasta
/src e conferir o resultado com o código da solução.
2) Usar o NetBeans para declarar o método add do stateless session bean
StatelessSessionBean com a anotação @DenyAll
Compilar e empacotar o código usando o NetBeans;
Realizar o deploy do EJB;
Criar um client simples e chamar o método add, verificar o que será
informado, o indicando que o atributo foi respeitado, ou seja, nenhuma
role pode acessar o método.
133. EJB Timers e Interceptors
EJB Timers
O serviço EJB Timer é fornecido pelo container EJB com o intuito de
possibilitar a implementação de execuções baseadas em um intervalo de
tempo e agendamento para execução de tarefas.
A especificação de EJB suporta duas formas de objetos Timer:
Timer de ação simples – um timer de ação simples é um timer que
expira apenas uma vez (ao contrário de um timer de intervalo, onde
múltiplas expirações são possívels).
Timer de intervalo – um timer de intervalo (ou timer multi-ação) vai
recorrer no tempo considerando múltiplos de um determinado
intervalo, de forma que esse tipo de timer terá portanto múltiplas
expirações em intervalos de tempo regulares.
134. EJB Timers e Interceptors
EJB Timers
A API EJB Timer fornece quatro interfaces para a implementação de
serviços temporizados.
javax.ejb.TimerService - essa interface suporta os componentes EJB na criação de
timers (ação simples ou intervalo) bem como a recuperação de timers existentes
(criados por outros EJBs).
javax.ejb.Time - essa interface permite recuperar informações sobre os objetos Timer
que foram criados anteriormente pelos EJBs.
javax.ejb.TimedObject - componentes EJB pode implementar essa interface para
receber notificações baseadas em intervalos de tempo (callbacks) em objetos Timer.
O método ejbTimeout() será invocado pelo container quando o tempo expirar.
javax.ejb.TimerHandle – essa interface é implementada pelo container de forma que
um EJB possa utilizar esse handle para reconstruir um objet timer um um outro
momento (semelhante a um javax.ejb.Handle), sendo que obviamente a interface
TimerHandle extende a interface Serializable possibilitando ao TimerHandle ser
serializado. Devido a esse fato, objetos TimerHandle são objetos locais não sendo
permitido passar objetos TimerHandle como argumentos para chamadas de método
remotas.
135. EJB Timers e Interceptors
EJB Timers
É possível configurar um timer EJB 3.0 usando um stateless session bean
ou message-driven bean. O serviço do Timer (Timer Service) pode ser
acessado usando anotações ou fazendo um lookup no contexto JNDI.
Abaixo temos um exemplo de implementação de um TimedObject
utilizando a anotação @Resource em um método para injetar a referência
a um Timer:
@Stateless public class AmbienteFacade implements AmbienteFacadeLocal
{
...
@Resource Timer EmpDurationTimer;
...
}
136. EJB Timers e Interceptors
EJB Interceptors
Serviços em tempo de execução como controle de transações e segurança são
executados em um bean quando um método é invocado. Esses serviços
geralmente são implementados como métodos interceptores gerenciados pelo
container. Entretanto, a versão 3.0 de EJB também permite aos desenvolvedores
implementar interceptores definidos pelo mesmo, que podem ser executados
antes e depois da execução de um método. Essa possibilidade é muito útil pois
permite ao desenvolvedor ter mais controle sobre uma transação por exemplo,
verificações de segurança e outros.
Os interceptores oferecem um controle fino sobre o fluxo de invocação de um
método, podendo ser usados por Session Beans (stateful e stateless) e Message-
Driven Beans.
Interceptors podem ser definidos na própria bean class ou em uma classe
externa, sendo que os métodos interceptores sempre serão chamados antes da
execução dos metódos de negócio de um bean.
Abaixo temos a assinatura típica de um método interceptor.
public Object <methodName>(javax.ejb.InvocationContext)
137. EJB Timers e Interceptors
EJB Interceptors
Um método interceptor define um parâmetro do tipo InvocationContext, e essa
interface por sua vez define os métodos abaixo:
public interface InvocationContext{
public Object getBean();
public Method getMethod();
public Object[] getParameters();
public void setParameters(Object params[]);
public EJBContext getEJBContext();
public Object proceed() throws Exception;
}
138. EJB Timers e Interceptors
EJB Interceptors
A anotação @Interceptor determina um interceptor
definido em uma outra classe, sendo que se mais de um
interceptor for necessário, é possível usar a anotação
@Interceptors.
A anotação @AroundInvoke indica que um método atua
como interceptor, sendo que interceptor podem ser
aplicados a todos os métodos de negócio de um bean. O
código abaixo é um exemplo de um interceptor definido
na própria classe do bean e logo em seguida temos um
exemplo de um interceptor definido em uma classe
externa.
139. EJB Timers e Interceptors
EJB Interceptors
@StateLess
@Interceptor("MyCustomInterceptor")
public class BusinessBean{
@AroundInvoke
public Object customInterceptor(InvocationContext invContext)
throws Exception{
...
invContext.proceed();
}
}
public class MyCustomInterceptor{
@AroundInvoke
public Object customInterceptor(InvocationContext invContext)
throws Exception{
...
invContext.proceed();
}
}