Mostrando postagens com marcador Java Programming Language. Mostrar todas as postagens
Mostrando postagens com marcador Java Programming Language. Mostrar todas as postagens

domingo, 20 de janeiro de 2013

[JPA] Conceitos Importantes

Fonte: http://tomee.apache.org/jpa-concepts.html

Se tem uma coisa que você precisa entender para usar com sucesso a JPA (Java Persistence API), é o conceito de Cache. Infelizmente o cache é uma estrutura interna, não exposta pela JPA via código.

O que você tem que ter em mente sobre o cache da JPA:
  • Um Cache é uma cópia de dados, uma cópia desconectada do banco de dados.
  • Flushing é o ato de levar as modificações feitas em cache para o banco de dados.
  • Um PersistenceContext é, essencialmente, um Cache.
  • Um EntityManager represetne um PersistenceContext (logo, um cache).
  • Um EntityManagerFactory cria um EntityManager (e todavia um PersistenceContext/Cache).

Comparando os contextos de persistência RESOURCE_LOCAL e JTA.

Com <persistence-unit transaction-type="RESOURCE_LOCAL"> você é que se responsabiliza por criar e rastrear o EntityManager (PersistenceContext/Cache).

  • Você precisa usar o EntityManagerFactory para obter um EntityManager.
  • A instância do EntityManager obtida é um PersistenceContext/Cache.
  • Um EntityManagerFactory pode ser injetado com a anotação @PersistenceUnit apenas (sem @Persistence Context).
  • Não é permitido usar @PersistenceContext para se referir a uma unit do tipo RESOURCE_LOCAL.
  • Você deve usar EntityTransaction API para iniciar/comitar todas as chamadas para seu ENtityManager.
  • Chamar ENtityManagerFactory.createEntityManager() duas vezes resulta em duas instâncias separadas de EntityManager e, é claro, dois PersistenceContext/Caches separados.
  • Não é uma boa idéia ter mais de uma instânciade um EntityManager em uso (não crie um segundo EntityManager antes de destruir o primeiro).

Com <persistence-unit transaction-type="JTA"> o container irá cuidar da criação e do rastreamento do EntityManager para você, e neste caso:


  • Você não pode usar o EntityManagerFactory para obter um EntityManager.
  • Você só pode ter o EntityManager que é fornecido pelo container.
  • Um EntityManager pode ser injetado pela anotação @PersistenceContext, somente (sem @PersistenceUnit).
  • Você não pode usar @PersistenceUnit para fazer referência a uma unit do tipo JTA.
  • O EntityManager fornecido pelo container é uma referência ao PersistenceContext/Cache associado a transação JTA.
  • Se não há transações JTA em progresso, o EntityManager não pode ser usado porque não há PersistenceContext/Cache.
  • Qualquer um com uma referência para a mesma unit na mesma transação irá automaticamente ter uma referência para o mesmo PersistenceContext/Cache.
  • O PersistenceContext/Cache é flushed e limpo a cada commit JTA.

É isso aí! Mais informações e exemplos veja em http://tomee.apache.org/jpa-concepts.html

quinta-feira, 3 de janeiro de 2013

[JSF] Usando Ajax com JSF.

The Java EE 6 Tutorial, Part II The Web Tier, Cap. 11 Using Ajax with JavaServer Faces Technology.

Visão Geral sobre Ajax.

Ajax refere-se a JavaScript e XML, tecnologias que são amplamento usadas para criar conteúdo web dinâmico e assíncrono. O foco deste tutorial está em usar JavaScript em funcionalidades baseadas em Ajax em aplicações web JSF.

JavaScript é uma linguagem orientada a objetos que permite adicionar funcionalidades à camada de apresentação para interações assíncronas com o cliente, onde é originalmente executada (também há JavaScript Side Server).

Quando uma função JavaScript envia uma requisição assíncrona para o servidor, o servidor envia de volta uma resposta usada para atualizar o DOM (Document Object Model) da página.

A resposta do servidor não precisa ser, necessariamente, em XML, também pode ser em JSON (formato de dados JavaScript).

Ajax permite atualização assíncrona e parcial da camada de apresentação, ou seja, funcionalidades Ajax podem trocar informações com o servidor sem a necessidade de submeter ou atualizar a página inteira (refresh).

Usando Ajax com JSF.

Funcionalidades Ajax podem ser adicionadas a aplicações JSF de uma das duas maneiras seguintes:
  • Programando a funcionaliade Ajax em JavaScript diretamente na página.
  • Usando uma biblioteca com funcionalidades Ajax embutidas.
A plataforma JEE 6 suporta Ajax por uma biblioteca JavaScript embutida. Logo, os componentes UI JSF respondem a funcionalidades Ajax. Você também pode carregar esta biblioteca JavaScript e usar diretamente seus métodos dentro dos Managed Beans.

A tag JSF específica para Ajax é f:ajax e seus atributos serão explicados a seguir.

Atributo Tipo Descrição
disabled javax.el.ValueExpression retorna um Boolean Se true o comportamento Ajax não deve ser renderizado, se false, o comportamento Ajax deve ser renderizado, o default é false.
event javax.el.ValueExpression retorna uma String Uma String que identifica o tipo de evento em que a ação Ajax será aplicada. Se especificado, deve ser um dos eventos suportados pelo componente. Se não especificado, o evento default (o evento que dispara a requisição Ajax) é determinado para o componente. O evento dafult é action para componentes ActionSource e valueChange para componentes EditableValueHolder.
execute javax.el.ValueExpression retorna um Object Uma Collection que identifica uma lista de componentes para ser executada no servidor. Se uma literal é especificada, deve ser uma String delimitada por espaços de identificadores de componentes e/ou uma das palavras chave. Se uma ValueExpression é especificada, deve referenciar uma propriedade que retorna uma Collection de String objetos. Se não especificada, o valor default é @this.
immediate javax.el.ValueExpression retorna um Boolean Um Boolean que indica se a entrada é para ser processada antes do ciclo de vida.
listener javax.el.MethodExpression O nome do método listener que será chamado quando um AjaxBehaviorEvent for disparado.
onevent javax.el.ValueExpression retorna uma String O nome da função JavaScript que irá manipular os UI events.
onerror javax.el.ValueExpression retorna uma String O nome da função JavaScript que irá manipular os erros.
render javax.el.ValueExpression retorna um Object Uma Collection que identifica uma lista de componentes a serem renderizados. Se uma literal é especificada deve ser uma String delimitada por espaços de identificadores de componentes e/ou de palavras-chave. Se uma ValueExpression é especificada, deve referenciar uma propriedade que retorna uma Collection de objetos String. Se não especificada, o valor default é @none.

Palavra-chave Descrição
@all Todos os componentes identificados
@form Os componentes do formulário
@none Nenhum componentes identificado
@this O elemento que disparou a requisição

Exemplo de uso da tag f:ajax

<h:inputText value="">
   <f:ajax />
</h:inputText>

Note que quando você usa a tag f:ajax em uma página Facelets, a biblioteca JavaScript que suporta Ajax que já vem no J2EE 6 é carregada implicitamente. Este recurso também pode ser carregado explicitamente, veja mais detalhes em Loading JavaScript as a Resource no The Java EE 6 Tutorial.

No próximo post veremos como enviar uma requisição Ajax e receber uma resposta. Até lá.

segunda-feira, 31 de dezembro de 2012

[JPA] Melhorando a performance de aplicações JPA com cache de segundo nível.


O cache de segundo nível é um repositório local, gerenciado pelo mesmo mecanismo de persistencia responsável pelo ORM da aplicação, para melhorar a performance da mesma.

A intenção é melhorar a performance reduzindo as conversações entre aplicação e banco de dados.

É suportado pela especificação JPA e pode ser configurado para os seguintes modos de trabalho (Cache Mode):

ALL Todas as entidades declaradas na unidade de persistência irão para o cache.
NONE Nenhuma entidade da unidade de persistência irá para o cache.
ENABLE_SELECTIVE Habilita o cache para entidades que forem declaradas para tal com a anotação @Cacheable.
DISABLE_SELECTIVE Habilita o cache para todas as entidades da unidade de persistência, exceto para aquelas que estiverem anotadas com @Cacheable(false).
UNSPECIFIED Adota o comportamento default do mecanismo de persistência JPA utilizado.

Um problema comum do uso do cache de segundo nível é quando os dados mudam no banco mas não mudam no cache. É o que se chama de stale read. Stale reads podem ser resolvidos com a estratégia adequada de configuração do modo de trabalho do cache e outras configurações possíveis. Por isso, é muito importante conhecer profundamente o cache de segundo nível do mecanismo de persistência que você pretende adotar.

No modo ENEABLE_SELECTIVE, as subclasses das entidades anotadas com @Cacheable também serão cacheadas a menos que a anotação seja sobrescrita com @Cacheable(false).

Especificando as configurações de cache mode para melhorar a performance.

Para ajustar o cache mode para uma unidade de persistencia, especifique um dos modos possíveis como valor do elemento shared-cache-mode no persistence.xml.

<persistence-unit name="examplePU" transaction-type="JTA">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <jta-data-source>jdbc/__default</jta-data-source>
  <shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode>
</persistence-unit>

Ou então, programaticamente:

EntityManagerFactor emf = 
    Persistence.createEntityManagerFactory(
        "myExamplePU", new Properties().add(
            "javax.persistence.sharedCache.mode", "ENABLE_SELECTIVE"));

OBS: Se o mecanismo de persistencia adotado não suportar cache de segundo nível, as configurações acima não produzirão qualquer efeito na aplicação.

Configurando cache retrieval e store modes.

Se o cache de segundo nível estiver habilitado na unidade de persistência pela configuração do shared cache mode, o comportamento do cache de segundo nível poderá ser modificado configurando as propriedades javax.persistence.cache.retrieveMode e javax.persistence.cache.stroreMode. Estas propriedades podem ser configuradas no nível do contexto de persistência, passando o nome e o valor da propriedade para o método EntityManager.setProperty, ou configurando uma operação per-EntityManager, ou seja, por entidade (EntityManager.find ou EntityManager.refresh) ou no nível per-query, ou seja, por query.

Cache Retrieval Mode

O modo de recuperação de dados a partir do cache, configurado pela propriedade javax.persistence.retrieveMode, controla como os dados são lidos do cache por chamadas ao método EntityManager.find e a partir de queries.

A propriedade retrieveMode pode ser configurada com uma das constantes definidas pelo enum javax.persistence.CacheRetrieveMode (USE que é o default ou BYPASS). Quando configurada para USE, os dados são recuperados a partir do cache, se disponíveis. Se o dado não estiver no cache, o mecanismo de persistência irá buscá-lo no banco. Quando configurada com BYPASS, o mecanismo de persistência ignora o cache e os dados são recuperados diretamente do banco de dados.

Cache Store Mode

O modo de salva dos dados do cache, configurado pela propriedade javax.presistence.storeMode, controla como os dados serão salvos no cache.

A propriedade storeMode pode ser configurada por uma das constantes definidas pelo enum javax.persistence.CacheStoreMode, podendo ser USE, que é o default, BYPASS ou REFRESH. Configurada como USE, o dado no cache é criado ou atualizado na primeira vez que for lido do banco de dados ou gravado (commited) no mesmo. Se o dado já estiver no cache, o modo USE não irá forçar um refresh quando o dado for lido do banco.

Quando configurada para BYPASS, os dados lidos ou gravados no banco não serão inseridos no cache. É isso! O cache será imutável.

Quando configurada para REFRESH o dado é salvo no cache toda vez que for lido ou gravado no banco. Se o dado já estiver no cache, será atualizado (refreshed) no cache.

Configurando o Cache Retrieval ou o Store Mode.

Para configurar o cache retrieval ou store mode, basta chamar o método EntityManager.setProperty do contexto de persistência e passar como parâmetro o par {nome, valor} da propriedade:

EntityManager em = ...;
em.setProperty("javax.persistence.cache.storeMode", "BYPASS");

Para configurar o cache retrieval ou store mode quando chamar os métodos EntityManager.find ou EntityManager.refresh, primeiro crie uma instância de Map<String, Object> e adicione os pares nome, valor conforme a seguir:

EntityManager em = ...;
Map<String, Object> props = new HashMap<String, Object>();
props.put("javax.persistence.cache.retrieveMode", "BYPASS");
String personPK = ...;
Person person = em.find(Person.class, personPK, props);

OBS: O cache retrieve mode será ignorado na chamada do método EntityManager.refresh, pois as chamadas para refresh resultam sempre em dados lidos do banco e nunca do cache.

Para configurar o retrieval ou store mode quando for usar queries, chame o método Query.setHint ou o método TypedQuerie.setHint, dependendo do tipo de query:

EntityManager em = ...;
CriteriaQuery<Person> cq = ...;
TypedQuery<Person> q = em.createQuery(cq);
q.setHint("javax.persistence.cache.storeMode", "REFRESH");
...

OBS: Configurar o store ou o retrieval mode em uma query ou chamando os métodos EntityManager.find ou EntityManager.refresh sobrescreve as configurações do entity manager.


Controlando o cache de segundo nível programaticamente.

A interface javax.presistence.Cache define métodos para interagir com o cache de segundo nível programaticamente. A interface Cache define métodos para checar se uma entidade particular tem dados salvos no cache, para remover uma entidade particular do cache, para remover todas as instâncias (inclusive de subclasses) de qualquer classe de entidade do cache e para limpar o cache de todos os dados das entidades.

OBS: Se o cache de segundo nível for desabilitado, chamadas aos métodos da interface Cache não terão qualquer efeito sobre a aplicação, exceto para o método contains, que sempre irá retornar false.

Checando se os dados de uma entidade estão no cache.

Chame o método Cache.contains para achar ou simplesmente para verificar se uma entidade está no cache de segundo nível. Este método retornará true se os dados da entidade estiverem em cache e false em caso contrário.

EntityManager em = ...;
Cache cache = em.getEntityManagerFactory().getCache();
String personPK = ...;
if (cache.contains(Person.class, personPK)) {
  // the data is cached
} else {
  // the data is NOT cached
}

Removendo uma entidade do cache.


Chame um dos métodos Cache.evict para remover uma entidade em particular ou todas as entidades de um dado tipo do cache de segundo nível.

Para remover uma entidade em particular chame Cache.evict passando a classe da entidade e o Id (chave primária).


EntityManager em = ...;
Cache cache = em.getEntityManagerFactory().getCache();
String personPK = ...;
cache.evict(Person.class, personPK);

Para remover todas as instâncias de uma classe de entidade, incluindo suas subclasses, chame evict e especifique a classe:

EntityManager em = ...;
Cache cache = em.getEntityManagerFactory().getCache();
cache.evict(Person.class);

Todas as instâncias da classe Person serão removidas do cache. Se Person tiver subclasse, chame o método evictAll para remover suas instâncias também.


Removendo todos os dados do cache.


Chamar o método Cache.evictAll irá limpar completamente o cache de segundo nível:


EntityManager em = ...;
Cache cache = em.getEntityManagerFactory().getCache();
cache.evictAll();

E é isso! Este post é o resultado da tradução, com poucas adaptações, do The Java EE 6 Tutorial, Part VI Persistence, Chapter 38 Improving the Performance of Java Persistence APIApplications by Setting a Second-Level Cache.


Fonte: http://docs.oracle.com/javaee/6/tutorial/doc/gkjjj.html
Tradução: Mauricio da Silva Marinho
Ao copiar, dê crédito ao autor.

sexta-feira, 9 de novembro de 2012

[VRaptor] Melhorando Hash MD5 com Salt

Vamos utilizar uma técnica chamada Salt, para adicionar melhor segurança à estratégia de guardar o hash das senhas no banco.

Esta técnica consiste em atribuir um valor aleatório, por cadastro, para que somado a senha, gere um hash.

O objetivo é impedir que existam senhas fracas no banco, suscetíveis a ataques de força bruta baseados em dicionários.

Alguns sites undergrounds oferecem dicionários com mais de 8 bilhões de entradas. O Linkedin sofreu um ataque desta natureza há algum tempo e como resultado, vazaram cerca de 6 milhões de senhas.

Espero que você goste:



O salt pode ser modificado de tempos em tempos, automaticamente, atualizando os hashes. E pode ser mantido em um local diferente. Você ainda pode guardar o salt cifrado em um algoritmo diferente.

Outras estratégias podem auxiliar a sofisticar mais ainda o processo, como gerar o hash do hash com diferentes algoritmos em várias iterações e por aí vai...

OBS: Esta técnica ajuda defesas contra ataques no banco de dados. Não elimina a necessidade da adoção de senhas fortes, uma vez que existem ataques direto a formulários e que exploram as fragilidades do protocolo http.

Espero ter te ajudado, apreciarei todas as críticas, dúvidas e sugestões.

Forte abraço,

Mauricio da Silva Marinho.

quinta-feira, 8 de novembro de 2012

[Java] Thread X Runnable

Threads está entre os assuntos mais difíceis do exame SCJP/OCJP. O que podemos dizer sobre elas...

Basicamente, temos dois tipos de ambiente de execução (em se tratando de execução):

  • Execução de segmentação única. Onde as ações são executadas em fila, uma após a outra, necessariamente. 
  • Execução concorrente. Onde várias ações disputam a atenção dos recursos de forma independente.

Neste último caso, em Java, as ações concorrentes são threads concorrentes. É o que chamamos de threads de execução. Dispomos deste recurso quando precisamos que alguma ação ocorra independente de outra(s), quando não podemos ficar esperando uma ação terminar para continuar executando uma tarefa ou uma sequencia de tarefas.

Em Java, uma thread é uma instância de java.lang.Thread. As execuções de aplicações Java, ocorrem em pilhas de chamadas. Cada pilha de chamadas reside em uma única Thread. Logo, ao criar uma Thread, estamos criando uma nova pilha de chamadas, no mesmo processo.

Um processo é um conjunto de tarefas, que em um SO multitarefa, pode executá-las concorrencialmente. Exatamente, as Threads!

Como a VM tratará a execução das threads dependerá da implementação da VM. Isso mesmo! Não espere garantir que uma aplicação que crie várias instâncias de Thread tenha o mesmo comportamento em VMs diferentes. Então, se este for o caso, não se pode basear a implementação em uma VM específica, a menos que saiba que a aplicação só será executada naquela VM.

A classe java.lang.Thread expõe alguns métodos para gerenciar as threads:

  • start()
  • yield()
  • sleep()
  • run() - chame aqui o código que será executado pela thread.
Cria-se uma Thread de duas formas:
  • Estendendo java.lang.Thread, ou
  • implementando java.lang.Runnable.

Estender Thread pode parecer mais fácil, mas certamente não é a solução mais elegante!

Por que? Simplesmente pelo fato de que a herança, em OO, é um recurso para se especializar uma classe, para que se faça algo novo.

Então se você precisa apenas criar uma execução em uma thread separada, não há necessidade de especializar Thread. Lembre-se que ao estender Thread, não poderá estender mais nada! Neste caso, o mais lógico, seguindo princípios de OO, seria implementar Runnable.

Implementar Runnable vai permitir que sua classe estenda outra classe de negócio, além de dispor dos comportamentos de Thread (ou de Runnable. Thread implementa Runnable, sabia?!).

Dizemos que estender Thread é mais simples porque por este caminho, para criar uma nova thread, basta instanciar a subclasse de Thread que você criou:

public class minhaThread extends Thread{
  public void run(){
    //Chama a execucao da nova thread aqui.
  }
}

MinhaThread novaThread = new MinhaThread();

Implementando Runnable (recomendável na esmagadora maioria dos casos), ficaria assim:

//Cria a classe que implementa Runnable
public class MinhaRunnable implements Runnable{
  public void run(){
    //Chama a execucao da nova thread aqui.
  }
}

//Instancia MinhaRunnable
MinhaRunnable minhaRunnable = new MinhaRunnable();

//Cria uma instancia de Thread, passando sua Runnable para executar
Thread novaThread = new Thread(minhaRunnable);

A classe Runnable que passamos para a Thread, tecnicamente chama-se destino (target).

Até o momento, a thread foi criada, mas não foi executada, dizemos que o estado dela é new. Para executar a thread, basta chamar .start() e a thread passará de new para running:

//Para iniciar a thread
novaThread.start();

Sacou?

Espero ter te ajudado. Críticas, dúvidas e sugestões são bem vindas.

Forte abraço e até o próximo post.

Mauricio da Silva Marinho