Maverick v1.0

64
MAVERICK PRESSÃO

description

Apresentação Jboss Seam

Transcript of Maverick v1.0

Page 1: Maverick v1.0

MAVERICK

PRESSÃO

Page 2: Maverick v1.0

Maverick 1.0 é o framework Jboss Seam 2.2.x para utilização com JavaEE 5

customizado!

Full stack → abstrai/resolve praticamente todos os problemas de uma aplicação WEB.

Exemplo: Autenticação, autorização, pool de conexões, injeção de dependência, envio de

e-mail, geração de PDFs, Web Services, cache etc.

Customizações:

- Templates de páginas

- Seam Crud Application Framework

Page 3: Maverick v1.0

Servidor de Aplicação

- Implementam diversas das especificações anteriores para podermos utilizá-las em nossos sistemas.

- RedHat Jboss Application Server 5

- GlassFish Application Server v2 → é a referência de implementação, não quer dizer que é o melhor

- O termo “application server web profile” passou a existir desde o JavaEE 6 e referencia servidores que não ofertam tudo, somente parte das especificações.

Fontes:http://www.oracle.com/technetwork/java/javaee/overview/compatibility-jsp-136984.htmlhttp://www.oracle.com/technetwork/java/javaee/overview/compatibility-javaee5-jsp-141098.htmlhttps://access.redhat.com/articles/112673

Page 4: Maverick v1.0

Maverick-GenO Processo de criação de um sistema é sempre tedioso e propenso a erros. Um script de configuração auxilia o

desenvolvedor nesse processo, copiando os arquivos necessários para os lugares corretos e seguindo as convenções

de desenvolvimento da IPLANRIO.

O Maverick-Gen cria o sistema com o Padrão de Interface da Empresa, autenticando no LDAP do RIOMAIL e

seguindo as convenções de pacotes definidas pela IPLANRIO.

A Ferramenta é uma customização do Seam-Gen distribuído em conjunto com o Framework JBoss Seam. Nada

foi criado do zero, a mesma estrutura do Seam-Gen é utilizada para a criação do Sistema com as devidas

customizações para o Ambiente e Padrões de Desenvolvimento da Empresa.

O Maverick-Gen utiliza somente a parte de criação de projetos do Seam-Gen. O Gerador automático de CRUDS

e as ferramentas de engenharia reversa não são utilizadas por não estarem em conformidade com as práticas

utilizadas na IPLANRIO.

O Seam Crud Framework não deve ser utilizado. As classes EntityHome e EntityQuery devem ser evitadas.

Page 5: Maverick v1.0

JavaEE 5

- São uma série de especificações bem detalhadas de como deve ser implementado um software utilizando-se de serviços de infraestrutura.

- Finalidade é reutilizar essa base de infraestrutura já pronta para focarmos no desenvolvimento do negócio sem preocupar-se com grande parte de código de infraestrutura.

Outra finalidade é evitar o vendor lock-in trazendo liberdade para utilização da implementação de outro fabricante qualquer sem precisar alterar seu software.

- Quais especificações são estas?

Fontes:http://www.caelum.com.br/apostila-java-web/o-que-e-java-ee/#3-3-servidor-de-aplicacao

Page 6: Maverick v1.0

Algumas Especificaçãoes do JavaEE

- JSF → Java Server Faces

- EJB → Enterprise Java Beans

- JPA → Java Persistence API

- JAX-WS e JAX-B → Java API for XML Web Services e Java API for XML Binding

- JAAS → Java Authentication and Authorization Service

- JTA → Java Transaction API

- JMS – Java Message Service

- JNDI → Java Naming and Directory Interface

Page 7: Maverick v1.0

Servidor de Aplicação

- Implementam diversas das especificações anteriores para podermos utilizá-las em nossos sistemas.

- RedHat Jboss Application Server 5

- GlassFish Application Server v2 → é a referência de implementação, não quer dizer que é o melhor

- O termo “application server web profile” passou a existir desde o JavaEE 6 e referencia servidores que não ofertam tudo, somente parte das especificações.

Fontes:http://www.oracle.com/technetwork/java/javaee/overview/compatibility-jsp-136984.htmlhttp://www.oracle.com/technetwork/java/javaee/overview/compatibility-javaee5-jsp-141098.htmlhttps://access.redhat.com/articles/112673

Page 8: Maverick v1.0

Servlet Container

- Servidor que suporta basicamente a parte WEB → Servlet, JSP, JSTL, JSF

- Não necessariamente o JavaEE Web Profile nem o JavaEE completo.

- Exemplos: Apache Tomcat e Jetty

- O Tomcat é o servlet container padrão utlizado pelo JBoss.

Fontes:http://www.caelum.com.br/apostila-java-web/servlets/#5-2-servletshttp://www.caelum.com.br/apostila-java-web/

Page 9: Maverick v1.0

Camadas

- Visão – view → exibe informações para o cliente - páginas

- Controle – controller → recebe as informações capturadas repassando-as para a camada de serviço. Também controla o fluxo de navegação das páginas exibindo os resultados e mensagens para a camada de visão.

- Serviço – service → coordena as classes de domínio para executar uma história de usuário.

- Domínio – domain → possui as regras de negócio. Está dividada em entidades, objetos de valor, repositórios, fábricas...

- Infra – infra → manipulação de arquivos, criptografia, envio de e-mail...

Fontes:http://jeap.rio.rj.gov.br/maverick

Page 10: Maverick v1.0

Estrutura de um Projeto Maverick

- src/main --> Pasta de código onde devem ficar os pacotes da camada de domínio.

Exemplo: br.gov.rj.rio.iplanrio.nomedoprojeto.domain

Devido a restrições no classloader do seam as classes desse pacote não são "Hot-Deploy" qualquer alteração força o desenvolvedor a restartar o Servidor de Aplicação para suas alterações serem refletidas na aplicação.

- src/hot --> Pasta de código que abriga todas as outras classes das mais variadas camadas da aplicação.

Exemplo: br.gov.rio.rj.iplanrio.nomedoprojeto.controller, br.gov.rio.rj.iplanrio.nomedoprojeto.service, br.gov.rj.rio.iplanrio.nomedoprojeto.domain.repository, br.gov.rio.rj.iplanrio.nomedoprojeto.infra

Todas as classes nesse pacote são "Hot-Deploy", qualquer alteração nas mesmas são refletidas automaticamente para a aplicação.

src/test --> Pasta de código que contêm as classes de teste da aplicação. Cada pacote nas pastas src/main e src/hot devem ter seus respectivos pacotes de testes.

Fontes:http://jeap.rio.rj.gov.br/maverick

Page 11: Maverick v1.0

+ Estrutura de um Projeto Maverick

- JRE System Library → Item específico do eclipse quie indica o JRE/JDK utilizado no projeto

- Referenced Libraries → As bibliotecas referenciadas pelo eclipse são exibidas aqui. Deve-se atentar que essas bibliotecas não são construídas junto com a aplicação, essa função é realizada em outro lugar, aqui são as bibliotecas referenciadas pela IDE, para o desenvolvedor conseguir efetuar o autocomplete do código e a checagem automática de tipos do eclipse.

- classes → Esta pasta contêm os arquivos compilados(.class) da aplicação. Um filtro do eclipse impede a visualização desses arquivos.

lib → Pasta que possui todas as bibliotecas necessárias para o desenvolvimento de uma aplicação com Jboss Seam. Nessa pasta estão todas as possíveis bibliotecas que a aplicação poderá utilizar.

No momento da construção da aplicação o script ANT verifica as bibliotecas declaradas nos arquivos

deployed-jars-ear.list e deployed-jars-war.list e efetua uma cópia das mesmas para a aplicação

Resumindo, se precisa incluir uma biblioteca em sua aplicação você deve efetuar uma cópia para a pasta lib, incluir seu nome no arquivo deployed-jars-ear.list ou deployed-jars-war.list e incluir a mesma no buildpath do eclipse.

Fontes:http://jeap.rio.rj.gov.br/maverick

Page 12: Maverick v1.0

+ Estrutura de um Projeto Maverick

- dist → Esta pasta contém o arquivo .ear da aplicação. O script de construção monta o "binário" da aplicação nessa pasta e depois copia a mesma para o servidor de aplicação.

exploded-archives → Nesta pasta a aplicação é criada em seu modo de desenvolvimento. O script *ANT monta a aplicação nessa pasta em sua forma explodida, assim conseguimos atualização Real Time de qualquer alteração na aplicação (excluindo as alterações na pasta de código src/main).

resources → Todos os arquivos de configuração estão nessa pasta.

src → Representação física das pastas src/main, src/hot e src/test, um filtro do eclipse impede a visualização das classes nessa pasta. Qualquer alteração deve ser efetuada pela versão lógica das pastas em src/main, src/hot e src/test.

view → Todas as páginas, imagens e arquivos CSS estão nessa pasta.

build.xml → Arquivo de construção ANT. Todas as tarefas de construção estão nesse arquivo. O script compila as classes, executa os testes, monta a aplicação e copia a mesma para o servidor de aplicação.

*ANT é um construtor feito em Java para construir aplicativos não só em Java mas em outras linguagens também.

Fontes:http://ant.apache.org/

Page 13: Maverick v1.0

+ Estrutura de um Projeto Maverick

- build-dev.properties → Arquivo com parâmetros para o script de construção em modo de desenvolvimento.

- build-prod.properties → Arquivo com parâmetros para o script de construção em modo de produção.

- build.properties → Arquivo com parâmetros para o script de construção tanto para o modo de desenvolvimento quanto para o modo de produção. Definimos aqui as variáveis jboss.home e jboss.domain.

- debug-jboss-estoque.lauch, estoque.lauch e explode.lauch → Arquivos responsáveis pela construção automática da aplicação. Quando você salva qualquer arquivo no eclipse ele automaticamente constrói a aplicação e atualiza a mesma no servidor de aplicação.

- deployed-jars-ear.list → Arquivo onde estão declaradas as bibliotecas necessárias para a execução da aplicação. Nesse arquivo ficam as bibliotecas relacionadas com as funcões Enterprise da aplicação.

- deployed-jars-war.list → Arquivo onde estão declaradas as bibliotecas necessárias para a execução da aplicação. Nesse arquivo ficam as bibliotecas relacionadas com as funções WEB da aplicação.

- hibernate-console.properties → Arquivo de configuração do plugin Hibernate Console.

- seam-gen.properties → Cópia do arquivo de configuração necessário para a criação da aplicação.

- validate.xml → Arquivo responsável por validações no momento da construção da aplicação.

Page 14: Maverick v1.0

+ Estrutura de um Projeto Maverick

- .classpath → Arquivo que contém LIBs necessárias para execução e compilação do projeto Java dentro do Eclipse e não no projeto executado diretamente no Servidor de Aplicação Jboss, pois no servidor as LIBs tem que estar em locais próprios para seu perfeito reconhecimento.

- .project → Arquivo com configurações gerais para poder importar o projeto no Eclipse.

Para onde vão as LIBs declaradas nestes arquivos?

- deployed-jars-ear.list → vão para a pasta LIB de um pacote EAR deployado.

- deployed-jars-war.list → vão para a pasta WEB-INF/LIB do pacote WAR deployado.

Fontes:http://www.guj.com.br/articles/108

Page 15: Maverick v1.0

Pasta resources- nomedoprojeto-dev-ds.xml e nomedoprojeto-prod-ds.xml → configuram os respectivos datasources(string de

conexão com o banco, usuário, senha, parâmetros do pool de conexões do JBoss) de cada persistence-unit de

acordo com o ambiente de utilização(desenvolvimento ou produção).

- messages_pt_BR.properties → arquivo de mensagens

- seam.properties → Arquivo de marcação do JBoss Seam utilizado para scan e configuração dos componentes do framework. Exemplo é a anotação @Name que é scaneada nas classes do projeto e

META-INF

- application.xml → arquivo de configuração para deployment dos módulos em um pacote EAR para JavaEE.

A TAG context-root é onde troca-se o contexto inicial da aplicação.

<context-root>/je-nomedoprojeto</context-root>

Exemplo: http://localhost:8080/je-nomedoprojeto

- persistence-dev.xml e persistence-prod.xml → configuram as unidades de persistência para cada ambiente.

Fontes:http://docs.oracle.com/javase/7/docs/api/java/util/ResourceBundle.htmlhttps://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html

Page 16: Maverick v1.0

+Pasta resources- seam.properties → Arquivo de marcação do JBoss Seam utilizado para scan e configuração de classes

gerenciadas pelo Seam com anotação @Name. Estas classes são escaneadas para associar o nome destes

componentes para utilização no JSF.We need to include a seam.properties file in the root of the archive(ear/war/jar) file.We have to do this for all the archive's whereever we are using the @Name Annotation. Seam will check every

Java class packaged in that archive for component annotations, and bind them to names according to their @Name annotations. If there is no seam.properties file, no checking will be done, and your

components won’t be bound to JSF names. Why does Seam force you to flag your archives this way ? Well, if an archive contains a significant number of classes, parsing all of them for Seam

annotations can be an expensive operation. Even if it’s only a one-time scan performed when an application is deployed, you might like to avoid this when possible. How exactly does Seam trigger the

scan for component names? Configuring an application to use Seam included the addition of a listener to the web.xml deployment file:

-listener-

-listener-class-org.jboss.seam.servlet.SeamListener-/listener-class-

-/listener-

This listener is the key to the component-naming magic (as well as several other Seam capabilities). When the web container starts up the web context for the application, it initializes any listeners

configured in the web.xml file. The SeamListener, in its initialization routine, checks each archive that has been loaded with the application for a seam.properties file (it does this through some class

loader games that I won’t go into here). If an archive contains this file, it’s a simple matter (through other class loader games) to iterate through all the classes loaded in that archive for @Name

annotations. Each one that’s found is inserted into a list of name bindings with the appropriate details needed to manage the component at runtime .

Page 17: Maverick v1.0

+Pasta resourcesWEB-INF

- components.xml → principal arquivo de configuração de componentes utilizados no JBoss Seam.

Basicamente aqui são configurados as fábricas de entityManagers associadas a cada persistence-unit, alguns

parâmetros de conversação e o método que faz a chamada da autenticação.

- faces-config.xml → arquivo de configuração do JSF utilizando-se Facelets para renderização. Como o JBoss

Seam utiliza o pages.xml para configuração da navegação, este arquivo terá somente o prefixo do resource bundle

de mensagens(pt_BR, en_US etc), a linguagem default e demais linguagens suportadas para internacionalização.

- pages.xml → define regras de navegação de páginas, regras de segurança de acesso, reescrita, ações a serem

executadas ao abrir uma página, redirecionamento e mensagens para exceptions específicas.

- web.xml → configura Servlets e filtros do Seam bem como diversos parâmetros do JSF e Facelets. A principal

configuração é o timeout da SESSION definido neste arquivo.

Fontes:https://docs.jboss.org/seam/2.2.2.Final/reference/en-US/html_single/#xml.descriptor

Page 18: Maverick v1.0

JSF e FaceletsJSF → É um framework component-based para Interfaces Web que segue a especificação: JSR 252.

Facelets → É um framework baseado em templating(ui:composition, ui:define, ui:insert) e formatação XML.

Aplicações em JSF quase sempre utilizam Facelets, que foi especialmente desenvolvido para trabalhar com JSF,

já que o Facelets sabe trabalhar com o ciclo de vida de requisições do JSF.

O Facelets possui várias vantagens como a facilidade na criação e reutilização de páginas e componentes, melhor

depuração de erros(o Facelets exibe o ponto exato onde ocorreu o erro na página) e Facelets também é de 30% a

50% mais rápido que JSP para montar as páginas(não gera códigos Java Servlets compilando-os com o JSP, ele é

XML-compliant usando um compilador SAX para rapidamente interpretar o XML das páginas, leia-se juntar os

templates e construir a árvore de componentes JSF).

Então podemos concluir que o Facelets constrói a árvore de componentes(fica salva na HttpSession do usuário)

do JSF implementando o ViewHandler(classe abstrata do JSF que gerencia a árvore de componentes da Restore

View a Render Response). E o JSF é quem gera o HTML final a partir dos objetos montados na árvore.

Fontes:http://www.rponte.com.br/2009/01/19/o-que-todo-bom-desenvolvedor-jsf-deveria-saber/http://www.rponte.com.br/2008/11/12/aplicacoes-serias-em-jsf-usam-facelets/

Page 19: Maverick v1.0

JSF – Implementação vs ComponentesImplementações

MOJARRA → É a implementação de referência da Oracle. É a que o JBoss Seam utiliza, já que possuem somente

o conjunto de componentes RichFaces, ou seja, eles não tem sua própria implementação e usam a Mojarra.

MYFACES → É a implementação feita pela Apache.

Componentes → Rodam em cima de uma implementação do JSF e fornecem componentes a mais, já que a

própria implementação apenas fornece componentes simples. Podem trabalhar em conjunto em uma mesma

aplicação de forma a termos a maior variedade possível para ajudar-nos no desenvolvimento de páginas do

sistema. Utilizamos os 3 componentes a seguir em nossos projetos na IplanRio:

PRIMEFACES → O próprio.

RICHFACES → Da Red Hat.

TOMAHAWK → Da Apache.

Fontes:http://www.rponte.com.br/2009/01/19/o-que-todo-bom-desenvolvedor-jsf-deveria-saber/http://www.rponte.com.br/2008/02/18/qual-implementacao-jsf-voce-usa/https://jcp.org/en/jsr/detail?id=252

Page 20: Maverick v1.0

Ciclo de Vida do JSF

Fontes:http://docs.oracle.com/javaee/5/tutorial/doc/bnaqq.html

Page 21: Maverick v1.0

EL – Expression Language

É uma linguagem desenvolvida pela antiga SUN, comprada pela Oracle, com o objetivo de remover parte do

código de páginas JSP(os scriplets <%...%> com códigos Java dentro dificultando o entendimento e design da

página) e mais tarde utilizado no JSF. Contém operadores, sintaxe própria e palavras reservadas(ne, eq,

empty...).

Provê um mecanismo para comunicação entre a camada de visão e a camada de controle. É utilizada pelo JSF

para acessar os valores das propriedades de objetos Java nos controladores através de seus métodos GETTERS e

SETTERS, isto é, faz o binding(ligação) destes valores para as páginas em JSF.

Exemplo de uso:

<s:div rendered="#{estoqueController.lista.size() > 0}" >

<c:if test="${datePattern ne '' and dateType eq ''}">

<s:convertDateTime pattern="${datePattern}" type="date"/>

</c:if>Fontes:http://docs.oracle.com/javaee/6/tutorial/doc/gjddd.htmlhttps://jcp.org/en/jsr/detail?id=245http://www.caelum.com.br/apostila-java-web/javaserver-pages/#6-6-el-expression-languagehttp://docs.oracle.com/javaee/1.4/tutorial/doc/JSPIntro7.html

Page 22: Maverick v1.0

Pressão? Tenso? Tem risco? Dúvidas?

Page 23: Maverick v1.0

Criando o Projeto Estoque a partir do Projeto SilfaeSHELL

cd /maverick/projetos_java7

./maverick-criar-projeto-api.sh estoque silfae

Zipar a pasta estoque e apagá-la

ABRIR JBOSSDEV STUDIO no workspace /maverick/projetos_java7

Importar projeto estoque.zip

ALTERAR build.properties

jboss.home=/maverick/jboss-eap-5.2

jboss.domain=default

Page 24: Maverick v1.0

JAR vs WAR vs EAR

JAR – Java Archive → contém classes Java, texto, imagens etc como forma de distribuir bibliotecas na

plataforma Java.

WAR – Web Application Archive → contém arquivos de uma aplicação web como xml, html, tag libraries,

imagens, css, libs de funções web etc.

EAR – Enterprise Archive → contém arquivos de uma aplicação que roda em um servidor de aplicação, ou seja, é

um formato de arquivo utilizado pelo JavaEE. Pode ter arquivos vários módulos web dentro dele, isto é, vários

WAR empacotados em um só arquivo para facilitar a distribuição.

Em nosso caso a principal diferença para o WAR é que usamos o EAR quando utilizamos EJBs em nosso projeto.

Fontes:http://en.wikipedia.org/wiki/JAR_(file_format)http://en.wikipedia.org/wiki/WAR_(file_format)http://en.wikipedia.org/wiki/EAR_(file_format)

Page 25: Maverick v1.0

Reexplode vs RedeployAmbas sãos TARGETs do ANT prontas no JBoss Seam para construir e fazer deploy do projeto.

REEXPLODE → deploy em PASTA. Executa 3 targets: unexplode, clean, explode.

unexplode: faz o undeploy da pasta explodida e seu datasource, ou seja, deleta a pasta WAR ou EAR do projeto

na e o datasource na pasta DEPLOY do JBoss.

clean: deleta os diretórios temporários exploded-archives e dist.

explode: recompila o projeto como PASTA em exploded-archives do projeto e copia-o para a pasta DEPLOY do

JBoss junto com o XML do datasource do projeto.

REDEPLOY → deploy em ARQUIVO. Executa 3 targets: undeploy, clean, deploy.

undeploy: deleta o arquivo WAR ou EAR do projeto e o datasource na pasta DEPLOY do JBoss.

clean: deleta os diretórios temporários exploded-archives e dist.

deploy: recompila o projeto como ARQUIVOS separados na pasta DIST do projeto, junta-os em um só arquivo e

copia-o para a pasta DEPLOY do JBoss junto com o XML do datasource.

Page 26: Maverick v1.0

+Reexplode vs Redeploy

A tag redeploy é utilizada em projetos construídos pelo *Jenkins em nossos ambientes, pois a distribuição em

forma de ARQUIVO é mais fácil de copiar para as instâncias do JBoss ou para o **Nexus.

Em ambientes locais de desenvolvimento utilizamos somente a tag reexplode, pois o formato de PASTA permite o

HOT-DEPLOY através da IDE JBbossDev Studio.

Caso execute a tag redeploy após um reexplode deve-se deletar a pasta do projeto antes dentro da pasta DEPLOY

do JBoss, pois o ANT não conseguirá copiar a PASTA cujo nome de projeto já existe em forma de arquivo.

*Jenkins → sistema desenvolvido para facilitar a execução de builds automatizados, ou seja, evita trabalho manual dispendioso e

propenso a erros. Faz parte da prática de desenvolvimento chamada integração contínua, cujo objetivo é ter um feedback instantâneo

garantindo que todo o sistema funcione a cada build.

**Nexus → é um repositórios de artefatos. Muito utilizado para armazenar LIBs no formato do Maven(podendo ser utilizado pela

ferramenta IVY, que utiliza o mecanismo de gerenciamento de dependências do Maven em projetos ANT) e binários de um projeto.

Fontes:http://blog.caelum.com.br/integracao-continua-de-projeto-java-com-jenkins/http://blog.caelum.com.br/integracao-continua/http://www.sonatype.com/nexus/why-nexus/why-use-a-repo-managerhttp://www.infoq.com/br/news/2010/08/acelere-builds-com-nexus

Page 27: Maverick v1.0

POJOs e Javabeans

POJO – Plain Old Java Object → termo inventado por Martin Fowler no ano 2000 para difundir a ideia de

quanto mais simples melhor. São classes que possuem construtor sem argumentos com métodos de acesso get e

set.

Javabeans – grãos Java → analogia com os grãos de café que encapsulam o sabor – generalizando, são POJOs

serializáveis ou que implementam ou estendem outras classes.

Não tem nada a ver com enterprise java beans que são os EJBs. A especificação é muito grande e está detalhada

no site da Oracle.

Fontes:http://camilolopes.wordpress.com/2008/06/04/serializacao-em-java/http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.htmlhttp://www.caelum.com.br/apostila-java-web/http://pt.wikipedia.org/wiki/Plain_Old_Java_Objects

Page 28: Maverick v1.0

EJBs

EJB – Enterprise Java Bean → especificação surgiu em 1998 e faz parte de um dos principais componentes da

plataforma JavaEE. Tem o objetivo de facilitar o desenvolvimento de sistemas OO distribuídos, porém ao longo

dos anos, com alternativas mais simples, houve muitos questionamentos sobre o uso de EJBs e sua magnitude

para resolver problemas cotidianos matando uma formiga com uma bala de canhão. A própria especificação EJB

evoluiu em sua versão 3.1 para tornar-se mais simples.

Nós utilizamos EJBs principalmente no desenvolvimento de web services e de repositórios com acesso direto via

JDBC. Em todo o resto utilizamos POJOs gerenciados pelo JBoss Seam.

Fontes:http://www.devmedia.com.br/conhecendo-o-ejb-revista-easy-java-magazine-24/26402

Page 29: Maverick v1.0

JPA

JPA – Java Persitence API → especificação para realizar o mapeamento objeto-relacional(ORM). No JavaEE 5

utiliza-se a JPA 1.0 detalhada na JSR 220.

Principais implementações existentes no mercado:

Hibernate da Jboss

EclipseLink da Eclipse Foundation

OpenJPA da Apache

TopLink JPA da Oracle

Fontes:http://www.caelum.com.br/apostila-java-web/uma-introducao-pratica-ao-jpa-com-hibernate/https://jcp.org/en/jsr/detail?id=220

Page 30: Maverick v1.0

HibernateFramework de persistência para Java open source e líder de mercado. Assim como o JBoss Seam foi criada por

Gavin King.

O Hibernate surgiu primeiro e inspirou a especificação da JPA, o qual o próprio Hibernate passou a fazer parte

mais tarde.

Utilizamos a versão 3.3.2.GA_CP05 para o core do Hibernate e a versão 3.4.0.GA_CP05 do Hibernate

EntityManager, este último que implementa a JPA 1.0 que faz parte do JavaEE 5. As versões superiores do

Hibernate já implementam JPA 2.0.

O Hibernate abstrai o código SQL e toda a camada JDBC gerando SQLs em tempo de execução. O SQL que

serve para um determinado banco de dados fala "dialetos" diferentes que podem ser trocados ao mudarmos para

outro banco sem alterarmos código Java, sendo o mapeamento ORM transparente para a aplicação.

Fontes:http://hibernate.org/http://www.caelum.com.br/apostila-java-web/uma-introducao-pratica-ao-jpa-com-hibernate/

Page 31: Maverick v1.0

PERSISTENCE.XMLEste é o arquivo de configuração utilizado no JPA. É similar ao hibernate.cfg.xml do Hibernate.

Nele temos diversas configurações para cada persistence-unit como o provider, o tipo de transação(JTA ou

RESOURCE_LOCAL), propriedades específicas do Hibernate(como *hibernate.dialect para definir o dialeto a

ser utilizado) etc.

- provider → org.hibernate.ejb.HibernatePersistence – Indica o nome da classe que provê o mecanismo de persistência externo, isto é,

a implementação necessária para criar-se um EntityManagerFactory(está na LIB hibernate-entitymanager.jar).

- transaction-type → JTA ou RESOURCE_LOCAL. Quando um <jta-datasource> é usado o default é JTA.

Se <non-jta-datasource> é usado, RESOURCE_LOCAL é o default.

- jta-data-source → É o nome JNDI do datasource, ou seja, no arquivo nomedoprojeto-dev-ds.xml ou nomedoprojeto-prod-ds.xml

temos a tag <jndi-name>estoqueDatasource</jndi-name> que é associada a um determinado persistence-unit através da tag

<jta-data-source>estoqueDatasource</jta-data-source> no persistence.xml por exemplo.

*Um dialeto encapsula todas as diferenças em como o Hibernate deve comunicar-se com um banco de dados particular para

completar algumas tarefas como obter um valor de seqüência, estruturar uma consulta SELECT ou converter um tipo de objeto

Java(String) para o tipo correspondente no banco(varchar).Fontes:http://www.caelum.com.br/apostila-java-web/uma-introducao-pratica-ao-jpa-com-hibernate/https://docs.jboss.org/hibernate/entitymanager/3.4/reference/en/html_single/http://adrielcafe.com/cafelog/hibernate/46-hibernate-tipos-de-dados-e-dialetos-suportados

Page 32: Maverick v1.0

+PERSISTENCE.XML

- hibernate.hbm2ddl.auto → uma das propriedades do Hibernate que mais utilizamos. Esta propriedade permite validar ou exportar

schemas DDL(Data Definition Language: comandos alter, drop, create) automaticamente para o banco de dados.

Em desenvolvimento utilizamos UPDATE e em produção utilizamos NONE, que é um valor não mapeado que não mudará a base de

dados.

Fontes:http://learningviacode.blogspot.com.br/2011/09/hibernatehbm2ddlauto-2.htmlhttp://blog.eyallupu.com/2007/05/hibernates-hbm2ddl-tool.html

Modo Lê import.sql Altera estrutura do banco

Comentário

update Não Sim

create Sim Sim Deleta a base antes de criá-la

create-drop Sim Sim Deleta a base ao fechar a SessionFactory

validate Não Não

Page 33: Maverick v1.0

RESOURCE_LOCAL vs JTAJTA – Java Transaction API é um padrão definido pela JSR 907. Normalmente implementado em um servidor de aplicações, para

delimitar as fronteiras de uma transação dentro de uma aplicação.

RESOURCE_LOCAL → a aplicação controla transações locais do próprio datasource.

JTA → o servidor de aplicação JBoss controla transações globais entre múltiplos datasources.

Em um ambiente JavaEE o padrão é JTA, que é o padrão utilizado pelo JBoss Seam.

Em um EntityManager com JTA o JBoss Seam, através do Seam Transaction Management, cuida das transações

fazendo o begin, commit e rollback “por baixo dos panos”.

Se utilizar um EntityManager RESOURCE_LOCAL é sua a responsabilidade de demarcar transações com

entityManager.getTransaction().begin() e entityManager.getTransaction().commit();

Para desabilitar o controle automático de transações devemos alterar o atributo transaction-management-enabled para false no

arquivo components.xml:

<core:init debug="@debug@" jndi-pattern="@jndiPattern@" transaction-management-enabled="true"/>Fontes:http://www.madbit.org/blog/programming/836/persistence-with-jpa2-resource_local-vs-jta/https://jcp.org/en/jsr/detail?id=907http://pt.wikipedia.org/wiki/Java_Transaction_APIhttp://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/transactions.html

Page 34: Maverick v1.0

DATASOURCESno-tx-datasource → datasource sem transações. Exemplo: somente consultas.

local-tx-datasource → datasource que não suporta two phase commit.

xa-datasource → datasource que suporta two phase commit.

Two phase commit é uma transação com mais de um participante.

Exemplo do Paulo Silveira da Caelum: O padre (transaction coordinator) avisa cada um dos noivos (resources) para se prepararem

para o casamento (commitment). Depois de avisados e preparados, o padre sabe quem quer casar(primeira fase). Na segunda fase da

cerimônia o padre avisa para cada participante se deve haver casamento(commitment) ou divórcio (rollback).

Fontes:http://www.mastertheboss.com/jboss-datasource/jboss-datasource-configuration

Page 35: Maverick v1.0

+DATASOURCES

No dia-a-dia de nosso desenvolvimento utilizamos sempre local-tx-datasources controladas via JTA.

Quando utilizamos múltiplos datasources declaramos o transaction-type do persistence-unit principal do sistema

como JTA e os demais persistence-units como RESOURCE_LOCAL, estes últimos são declarados como no-tx-

datasources no arquivo de XML do datasource.

Page 36: Maverick v1.0

+HibernateNo JBoss Seam a LIB persistence-api.jar(LIB contida em hibernate-entitymanager se baixada do site do Hibernate) que contém o

pacote javax.persistence. Neste pacote temos as interfaces para as principais anotações da JPA que são implementadas nas LIBs

hibernate-entitymanager podendo utilizar os recursos do hibernate-core. Um exemplo é o método getDelegate() →

Session session = (Session) entityManager.getDelegate(); → implementado em hibernate-entitymanager para pegarmos a Session do

Hibernate, que está localizada no hibernate-core. Por que pegamos a Session do Hibernate? Porque queremos métodos específicos

dele como a CRITERIA ou utilização de QUERY CACHES, por exemplo.

Caso queira utilizar anotações específicas do Hibernate como o @Cascade temos as LIBs hibernate-annotations.

Da mesma forma para validações de atributos utilizamos as LIBS contidas em hibernate-validator, como a anotação @NotNull, que

na JPA é o mesmo que anotar com @Column(nullable = false). A diferença é que no JBoss Seam o JSF está integrado com o

Hibernate Validator(tag <s:validateAll> por exemplo) e não com as anotações de validação da JPA.

A versão 4 do Hibernate Validator passou a ser a implementação de referência da Bean Validation 1.0(detalhada na JSR 303), que

nasceu fazendo parte da especificação JavaEE 6. Assim as anotações para validação de nossas entidades passaram a fazer parte do

pacote javax.validation.Fontes:http://www.caelum.com.br/apostila-java-web/uma-introducao-pratica-ao-jpa-com-hibernate/http://antoniogoncalves.org/2010/03/03/bean-validation-with-jpa-1-0/http://www.differencebetween.info/difference-between-java-and-javax

Page 37: Maverick v1.0

+Hibernate – Performance?

Na maioria das vezes o problema está na sua aplicação e não no Hibernate!

- Tabela sem índices;

- Consultas mal-feitas;

- Muitos hits ao banco de dados;

- Pool de conexões(o servidor de aplicação JBoss tem o seu próprio pool de conexões, não

usamos o C3P0 do Hibernate) mal configurado.

Resolvendo estas questões, em poucos casos será necessário recorrer a outros tipos de

abordagens para solucionar problemas de performance no acesso aos dados, como

utilização de JDBC puro.

Page 38: Maverick v1.0

Persistence Unit e Persistence Context

Persistence Unit → Uma unidade de persistência ou persistence-unit é um conjunto de classes mapeadas com

@Entity.

Persistence Context → está associado a um persistence-unit. É um contexto gerenciado pelo EntityManager permitindo a

sincronização entre o estado dos objetos e o banco de dados.

Através da inversão de controle e injeção de dependências o framework se encarrega de manter o EntityManager ativo durante um

contexto de persistência, isto é, ambos permanecem sincronizados para realizar operações de persistência necessárias durante este

contexto.

Exemplo: um CRUD onde pesquisamos os objetos, os editamos e os salvamos. Todo este momento com a página aberta devemos ter

um MESMO EntityManager ativo para realizar estas operações de consulta e gravação dos dados neste contexto extendido, isto é,

em uma conversação longa o estado dos objetos é mantido entre as requisições HTTP e o MESMO EntityManager está lá disponível

para uso a qualquer momento. Este é o padrão OpenSessionInView que assim como na Session se aplica ao EntityManager também

mantendo a sessão(conexão) ativa até o final da requisição.

Fontes:http://www.devmedia.com.br/introducao-ao-entitymanager/5206

Page 39: Maverick v1.0

Persistence Unit e Persistence Context

Page 40: Maverick v1.0

Inversão de Controle e Injeção de Dependência

Inversão de Controle → É uma técnica que inverte a responsabilidade sobre a criação e ciclo de vida de um objeto

diminuindo o acoplamento entre classes: Hollywood Principle "Don't call us, we'll call you".

Injeção de dependência → É uma forma para resolvermos a inversão de controle.

Fontes:http://www.devmedia.com.br/inversao-de-controle-x-injecao-de-dependencia/18763

Page 41: Maverick v1.0

+Inversão de Controle e Injeção de DependênciaExemplo: Criando um EntityManager na “unha”

@Beforepublic void iniciarTeste() throws Exception {

try {Class.forName("org.hsqldb.jdbcDriver");connection = DriverManager.getConnection("jdbc:hsqldb:mem:lis","sa", "");

} catch (Exception ex) {ex.printStackTrace();Assert.fail("Problemas para iniciar banco HSQL.");

}try {

emFactory = Persistence.createEntityManagerFactory("lis");entityManager = emFactory.createEntityManager();

} catch (Exception ex) {ex.printStackTrace();Assert.fail(ex.getCause().getMessage());

}}

@Afterpublic void finalizarTeste() throws Exception {

if (entityManager != null) {entityManager.close();

}

if (emFactory != null) {emFactory.close();

}try {

connection.createStatement().execute("SHUTDOWN");} catch (Exception ex) {

ex.printStackTrace();Assert.fail("Problemas para Finalizar Teste");

}}

Page 42: Maverick v1.0

+Inversão de Controle e Injeção de DependênciaExemplo: JBoss Seam agora com a responsabilidade de controlar o ciclo de vida do EntityManager e injetá-lo na

classe para utilização.

@Name("todosOsProdutos")public class TodosOsProdutos {

@In private EntityManager entityManager;

public TodosOsProdutos() {

}

public List<Produto> obterTodos(){return entityManager.createQuery("from Produto order by nome").getResultList();

}

}

A classe TodosOsProdutos não precisa saber como criar um EntityManager. Imagine o código anterior todo aqui nesta classe

TodosOsProdutos, ou seja, ela tendo a responsabilidade de criar esta infraestrutura para persistir e pesquisar objetos Produto.

Agora, invertemos o controle sobre o EntityManager da classe TodosOsProdutos para o JBoss Seam, que internamente sabe como

criar e gerenciar o ciclo de vida do EntityManager diminuindo o acoplamento entre as classes TodosOsProdutos e EntityManager. A

forma como a inversão de controle foi realizada neste exemplo foi através da injeção de dependência por propriedade(Property

Injection), que é como o JBoss Seam trabalha. Outros frameworks já suportam Construtor Injection, o próprio CDI faz isso.

Page 43: Maverick v1.0

Session vs EntityManagerSão serviços responsáveis por centralizar todas as ações de persistência realizando a conexão física com um banco

de dados, ou seja, administram o mapeamento ORM provendo APIs para consultas, inserção, deleção, cache etc

de objetos em um banco de dados, bem como administram serviços transacionais como o JTA.

Session → para gerenciar objetos com o Hibernate. É obtido através de uma SessionFactory.

EntityManager → para gerenciar objetos com JPA. Gerencia um contexto de persistência. É obtido através de

um EntityManagerFactory.

Fontes:http://www.devmedia.com.br/introducao-ao-entitymanager/5206http://www.devmedia.com.br/entendendo-hibernate-session/29215http://www.tutorialspoint.com/hibernate/hibernate_sessions.htmhttp://www.caelum.com.br/apostila-java-web/uma-introducao-pratica-ao-jpa-com-hibernate/

Page 44: Maverick v1.0

EntityManager no JBoss SeamNo JBoss Seam injetamos o EntityManager assim:

@Inprivate EntityManager entityManager;

O EntityManagerFactory é configurado no arquivo components.xml: <persistence:managed-persistence-context name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/estoqueEntityManagerFactory">

Exemplo de uso:

public List<Produto> obterTodos(){return entityManager.createQuery("from Produto order by nome").getResultList();

}

public List<Produto> obterTodos(){Session session = (Session) entityManager.getDelegate();return session.createQuery("from Produto order by nome").list();

}

Page 45: Maverick v1.0

+EntityManager

Principais métodos de um EntityManager:

Page 46: Maverick v1.0

Ciclo de vida dos objetos

Fontes:http://java.boot.by/scbcd5-guide/ch06.html

Page 47: Maverick v1.0

Ciclo de vida dos objetos

Fontes:http://pt.slideshare.net/caroljmcdonald/td09jpabestpractices2

Page 48: Maverick v1.0

+EntityManagerpersist → persiste uma entidade tornando-a managed.

merge → atualiza uma entidade retornando uma cópia dela como managed e o objeto passado não fica attached

ao persistence context, somente a cópia.

remove → deleta uma entidade.

find → procura uma entidade por sua chave primária e a devolve managed. Se ela já estiver no contexto de

persistência devolve sua versão em cache, caso contrário uma nova instância do objeto é carregada do banco de

dados. Se não encontrar devolve null.

clear → apaga o contexto de persistência fazendo com que todas as entidades fiquem detached.

flush → sincroniza o contexto de persistência com o banco de dados, isto é, executa as instruções SQL em cache imediatamente na base de dados. Deve estar em uma transação aberta para ser executado.

FlushModeType → AUTO ou COMMIT. O padrão é AUTO onde o flush é feito automaticamente após um commit ou aleatoriamente antes de queries serem executadas. FlushModeType como COMMIT só realiza o flush quando o commit é realizado em uma transação.

O JBoss Seam incluiu o MANUAL, que não existe na JPA. Faz com que o flush nunca ocorra, somente se o flush for chamado explicitamente. Este é o padrão que utilizamos!

Fontes:http://docs.oracle.com/javaee/5/api/javax/persistence/EntityManager.htmlhttp://blog.caelum.com.br/entidades-managed-transient-e-detached-no-hibernate-e-jpa/http://docs.jboss.org/seam/2.2.2.Final/api/

Page 49: Maverick v1.0

Escopos do JBoss Seam: EVENT → PAGE → CONVERSATION → SESSION → APPLICATION

EVENT - Este contexto é equivalente ao contexto REQUEST da Web. Recebe outro nome porque é utilizado em

outras situações além de requisições Web como, por exemplo, invocação RMI ou invocação via Seam Remoting

aos componentes Seam. Este contexto está associado ao ciclo de vida JSF. Durante o processamento do ciclo de

vida os objetos associados estarão disponíveis e serão eliminados somente ao final do ciclo de vida JSF. Inclusive

este contexto tem o tempo de vida de uma requisição Ajax realizada pelas bibliotecas de componentes visuais JSF

com suporte a Ajax. É o default em um POJO.

PAGE - Este contexto permite armazenar objetos que são criados numa tela JSF e estão disponíveis para esta

tela. Este contexto pode ser comparado com o contexto PAGE da Web. Contudo, um objeto armazenado neste

contexto estará disponível somente para a tela JSF correspondente que o instanciou. Como a documentação

sugere, este contexto é útil em alguns componentes visuais como, por exemplo, numa lista clicável de opções que

precisa de um objeto com valores específicos para esta lista e tela JSF. Objetos neste contexto estarão disponíveis

mesmo em sucessivas requisições Ajax a partir de componentes visuais a partir do browser.

Fontes:http://blog.spock.com.br/2008/07/sobre-os-contextos-do-jboss-seam.html

Page 50: Maverick v1.0

+Escopos do JBoss SeamCONVERSATION - Aqui está o verdadeiro diferencial do JBoss Seam que agrega valor no desenvolvimento de

aplicações Web com JSF. Este contexto permite armazenar objetos que terão um tempo de vida maior que uma

requisição (EVENT) e menor que uma sessão (SESSION). Com este contexto se torna possível definir um escopo

para objetos que são usados para implementar um fluxo de telas que realizam um "caso de uso" ou "história de

usuário". Em um Seam Component é possível anotar o início da conversação(@BEGIN) num método e anotar

outro para demarcar o fim da conversação(@END).

Fontes:http://blog.spock.com.br/2008/07/sobre-os-contextos-do-jboss-seam.html

Page 51: Maverick v1.0

+Escopos do JBoss SeamSESSION - Este contexto é equivalente ao contexto SESSION da Web. Este contexto define um escopo para

manter objetos como, por exemplo, o usuário logado.

APPLICATION - Este contexto é equivalente ao contexto APPLICATION da Web. Objetos armazenados neste

contexto estarão disponíveis para todas as conversações e usuários que acessam a aplicação. Este contexto é útil

ao armazenar objetos com conteúdo que não mudam com frequência para compartilhar para toda aplicação

como, por exemplo, configurações ou listas globais. Muitos objetos internos do próprio Seam são armazenados

neste contexto.

Fontes:http://blog.spock.com.br/2008/07/sobre-os-contextos-do-jboss-seam.html

Page 52: Maverick v1.0

Escopo de ConversaçãoÉ o principal conceito do JBoss Seam como dito em sua própria documentação.

É uma unidade de trabalho na visão do usuário já que permite várias interações do usuário entre vários requests

e várias transações no banco de dados, sem a necessidade de ficar fazendo merge(), sem a necessdiade de fazer

RELOAD do dados no início de cada requisição e sem ter que ficar lutando contra a LazyInitializationException.

O contexto de conversação é esculpido na sessão HTTP para formar um segmento de memória isolado e

controlado, pois armazenar tudo na session é maior fonte de vazamentos de memória de uma aplicação. Um

identificador exclusivo, conhecido como ID de conversação(CID), é gerada e associada a esta região da sessão. A

conversa tem o seu próprio ciclo de vida distinto e conversas simultâneas são mantidas isoladas.

Este contexto permite abrir várias janelas do browser para uma mesma tela JSF e cada janela representar uma

conversação diferente(contexto diferente de objetos) para execução simultânea da mesma história de usuário.

Cada janela é um contexto separado que não influência um outro contexto aberto.Fontes:https://docs.jboss.org/seam/2.2.2.Final/reference/en-US/html/concepts.html#d0e3620http://developeriq.in/articles/2012/feb/28/stateful-scope-conversaton-in-seam/http://www.coderanch.com/how-to/content/seam-in-action-excerpt.html

Page 53: Maverick v1.0

Unidade de Trabalho

Page 54: Maverick v1.0

Conversation ID – CIDCID é um identificador único que é gerado e associado a esta região da session denominada conversation. Pode

ser acessado através de EL #{conversation.id}. O CID é passado para o próximo REQUEST como um parâmetro,

ou em um campo hidden do form ou como um atributo da árvode de objetos do JSF. O Seam cuida disso de forma

transparente. Assim, o CID permite restaurar a conversação através do ID passado sendo recuperado da sessão e

associado àquele REQUEST.

Page 55: Maverick v1.0

Temporary vs Long-Running Conversations

Page 56: Maverick v1.0

Temporary vs Long-Running ConversationsTemporary → É o estado inicial de uma conversação. Uma conversação temporária é inicializada imediatamente

após a fase Restore View do JSF e é destruída após a fase Render Response. Ela mantém as mensagens do JSF

ativas após o redirect da página.

Long-Running → É a conversação que se mantém ativa entre vários requests transferindo o CID entre estes

requests. Uma conversação long-running é ativada a partir de um request anterior ou através da diretiva

@BEGIN ou da TAG <begin-conversation> no arquivo pages.xml. Por padrão, o Seam somente começa uma

conversação long-running se não houver outra já rodando. Para iniciar ou juntar-se a uma conversação já ativa

utilizamos a anotação @Begin(join = true).

Quando definimos os limites de uma conversação(@Begin e @End) não estamos iniciando-a nem destruindo-a,

mas somente transitando entre os estados de temporary e long-running.

Em resumo, cada resquest é parte de uma conversação quando utilizamos a anotação

@Scope(ScopeType.CONVERSATION). Você só tem que decidir quanto tempo quer que a conversa dure.

Page 57: Maverick v1.0

Escopo de Conversação e Contexto de Persistência

Page 58: Maverick v1.0

Concorrência@Version para OPTIMISTIC LOCKING → Atributo version é atualizado no banco de dados após o COMMIT

de uma transação. Se este atributo for diferente da versão no banco uma OptimisticLockException é lançada

fazendo com que o usuário refaça a operação tentando novamente atualizar o objeto.

Page 59: Maverick v1.0

@In e @OutInjection – É a capacidade do JBoss Seam de atribuir uma referência válida para um objeto (Seam Component -

@Name) em um atributo de outro componente. Esta capacidade é realizada através da anotação @In. Quando o

Seam encontra esta anotação em um atributo de um componente gerenciado pelo Seam - @Name, localiza um

objeto em um dos contextos - @Name("todosOsCeps") e @Scope(ScopeType.EVENT) - com o nome indicado e

injeta no atributo - @In(create=true) private TodosOsCeps todosOsCeps;

Outjection - É a capacidade do JBoss Seam de expor um objeto referenciado por um atributo de um Seam

Component - @Name em um dos contextos do Seam. Ou seja, é o movimento contrário, é colocar de volta o objeto

anotado com @Out para o contexto do Seam. Ao anotar um atributo com @Out, mesmo privado, este estará

disponível para injeção em outros Seam Components via @In ou para acesso via Expression Language (EL) em

um tela JSF.

Page 60: Maverick v1.0

@In e @Out@Name("listas")@Scope(ScopeType.APPLICATION)@Startuppublic class Listas {

@Getterprivate List<UF> ufLista;

@Out(scope=ScopeType.APPLICATION)private List<UnidadeMedida> unidadeMedidaLista;

@Createpublic void iniciar(){

ufLista = Arrays.asList(UF.values());

unidadeMedidaLista = new ArrayList<UnidadeMedida>();unidadeMedidaLista.addAll(Arrays.asList(UnidadeMedida.values()));

}

}

#{listas.ufLista}

#{unidadeMedidaLista}

Page 61: Maverick v1.0

@Name("usuario")

@Role(name="usuarioLogado",scope=ScopeType.SESSION)

@Entity

public class Usuario {

...

}

@Name("pesquisaController")

public class PesquisaController {

@In

private Usuario usuarioLogado;

}

Page 62: Maverick v1.0

@Name("verificaAcesso")public class VerificaAcesso {

@Loggerprivate Log log;

@In private Identity identity;

@Inprivate Credentials credentials;

@Inprivate StatusMessages statusMessages;

@In(create=true)AutenticacaoService autenticacaoService;

@In(required=false)@Out(required=false)private Usuario usuarioLogado;

public boolean acessar() {try{usuarioLogado = autenticacaoService.autenticar(credentials.getUsername(), credentials.getPassword());

if (usuarioLogado.getPerfis() != null) { for (Perfil perfil : usuarioLogado.getPerfis()) identity.addRole(perfil.getNome()); }

registrarLogin();return true;} catch (ObjetoNaoEncontradoException e) {

statusMessages.add(Severity.ERROR,"Credencial inválida!");return false;

}catch (LISException e) {

statusMessages.add(Severity.ERROR,e.getMessage());return false;

}}

}

Page 63: Maverick v1.0

NÃO CHORA!!!

Page 64: Maverick v1.0

“Ninguém ignora tudo. Ninguém sabe tudo. Todos nós sabemos alguma coisa. Todos nós ignoramos alguma coisa. Por isso aprendemos sempre.”Paulo Freire – Patrono da Educação Brasileira