fev 14

Por que não usar richfaces

Em um outro post meu eu vim explicar como fazer funcionar richfaces 4 com jsf2, mas simplesmente não funciona. Na verdade eu estou exagerando, funcionar funciona, porém faltam muitos componentes que quem está acostumado a utilizar a versão 3.X do richfaces sente uma falta muito grande, quem usa primefaces então, esse chora de doer.
Tudo bem que ainda não é a release final do richfaces 4, mas sinceramente está muito capenga ainda. Componentes básicos como ordenar uma tabela, filtrar, sem contar os a4j:commandButton que são um parto para funcionar, eu mesmo desisti de os usar.
No final das contas migrei tudo para primefaces, agora com a versão 2.2 estável, não tem comparação, simplesmente é o melhor framework existente para jsf2.

jan 19

Utilizando Quartz para agendamento de tarefas

O Quartz é um serviço de agendamento de tarefas com diversas funcionalidades, como agendamento por período, com data marcada, etc.

Ele é livre para utilização e está sob a licença Apache 2.0. Agora neste post vou dar uma breve noção de como se agendar uma tarefa para ser executada em uma data específica.

Primeiramente criaremos a classe Tarefa.java que irá implementar a interface Job da biblioteca Quartz como no exemplo abaixo, e no método execute você desempenha a tarefa desejada.

public class Tarefa implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        System.out.println("Trabalhando");
        //Resto das atividades

    }

}

Para se chamar essa tarefa, em algum lugar da sua aplicação é necessário agendar sua execução da seguinte maneira:

SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();

JobDetail job = new JobDetail("Nome do Job que voce quiser",Tarefa.class);

java.util.Calendar cal = new java.util.GregorianCalendar(2011, Calendar.MARCH, 17);
  cal.set(cal.HOUR, 10);
  cal.set(cal.MINUTE, 30);
  cal.set(cal.SECOND, 0);
  cal.set(cal.MILLISECOND, 0);

Date dtInicio = cal.getTime();

SimpleTrigger disparo = new SimpleTrigger("Disparo da tarefa",dtInicio);
sched.scheduleJob(job, disparo);

Pronto, agora sua tarefa será executada no dia 17 de março de 2011 às 10:30, mas é óbvio que para isso sua aplicação precisará estar rodando até lá!

jan 18

Richfaces 4 com jsf 2 e tomcat 6

Lá vou eu me aventurar a utilizar o richfaces 4, que ainda está em versão de milestone 5. Mas vamo que vamo para ver o que ele tem de melhor ou pior que o primefaces.
Primeiro problema dele é a documentação falha, pois a última versão do richfaces vem com mais jars do que a documentação diz que precisa, e além disso são necessários outros 3 jars para conseguir rodar.

Assim é necessário baixar o richfaces e também os seguintes jars cssparser-0.9.5.jar, guava-r07.jar and sac1-3.jar e adicioná-los ao seu classpath para só então conseguir rodar sua aplicação jsf 2 com richfaces. A é claro que são necessárias também as bibliotecas do jsf 2 né.

Assim que tiver novidades postarei aqui, mas só para fazer rodar já me levou um tempinho, portanto fica aí a dica.

nov 10

JSF com JSTL, utilizando tag c:if

Primeiramente, não recomendo sua utilização, prefiro usar para testar se algum componente deve ser exibido ou não o atributo rendered das tags do JSF. Mas caso seja necessário sua utilização temos que atentar para 2 pontos, primeiro que a expressão não se inicia com # como as EL do JSF, mas sim com $;  segundo isso só funciona com jstl 1.1 ou 1.2, devendo ser utilizada assim a uri “http://java.sun.com/jsp/jstl/core” ao invés de “http://java.sun.com/jstl/core”, que é da 1.0 .

Assim sendo um teste simples ficaria da seguinte maneira:

<c:if test="${MB.atributo != null}">
      ...
</c:if>

É isso, estava passando por esse problema hoje e depois de googlar um pouco achei a solução e estou aqui repassando.

nov 08

Configurando JPA com Hibernate

Neste post vou mostrar o básico para fazer funcionar o JPA  com hibernate , utilizando o hsqldb, que é um banco de dados leve e muito bom para testes de desenvolvimento.

Inicialmente precisaremos das bibliotecas do hibernate que nesta versão já vem com as do JPA 2, porém isso não influenciará muito nessa configuração básica caso esteja usando o JPA. Agora crie uma pasta lib para colocar os .jar e adicione-os ao build path do projeto.

O segundo passo é criar a nossa Persistence Unit, que provê a definição do contexto de persistência, contendo os metadados relativos a tal.


Para isso deve ser criado um arquivo XML chamado persistence.xml e deve ser colocado dentro da pasta META-INF dentro da sua pasta de códigos fontes, no eclipse, utilizando a configuração default ficaria :  “src/META-INF/persistence.xml” . Este arquivo ficará com a seguinte configuração :

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_2_0.xsd"
version="2.0">
    <persistence-unit name="pu" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
            <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost/nomedobanco" />
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />

            <property name="hibernate.connection.password" value="senha" />
            <property name="hibernate.connection.username" value="usuario" />

            <property name="hibernate.archive.autodetection" value="class"/>
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="show_sql" value="true" />
            <property name="format_sql" value="true" />

        </properties>
    </persistence-unit>
</persistence>

Obs.: Caso esteja utilizando o JPA  troque a linha da tag <persistence> por:

<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”>

Feito isso precisamos agora configurar como pegar o EntityManager, que é uma interface para interagir com o contexto de persistência.

Para isso criaremos um singleton que através da fábrica EntityManagerFactory pegaremos uma nova instância de EntityManager caso não tenha nenhuma aberta, ou retornará a que já está aberta. Será criada a classe JPAUtil:

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtil {
      private static EntityManagerFactory emf = null;
      private static EntityManager em = null;

      public static EntityManagerFactory getEntityManagerFactory() {
            if (emf == null)
                 emf = Persistence.createEntityManagerFactory("pu");
            return emf;
      }

       public static EntityManager getEntityManager() {
             if (em != null && em.isOpen())
                   return em;
             else {
                   em = getEntityManagerFactory().createEntityManager();
                   return em;
             }
       }

}

Isso já basta para testar se está funcionando, a conexão com o banco. Para testar agora criaremos uma classe de testes utilizando o JUnit para verificar se está tudo ok. Criaremos a classe JPATest:

import static org.junit.Assert.*;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import org.junit.Test;

public class JPAtest {
	@Test
	public void testaConexaoJPA() {
		EntityManager em = JPAUtil.getEntityManager();
		EntityTransaction transaction = em.getTransaction();
		transaction.begin();
		transaction.commit();
		boolean isconectado = em.isOpen();
		em.close();
		assertTrue(isconectado);
	}
}

Pronto, se tudo estiver correto ficará verde o teste do JUnit. Em outro post mostrarei como implementar um DAO para JPA.

nov 03

Utilizando C3p0 para resolver problemas de falha na conexão com banco

Coloquei uma aplicação no servidor da DailyRazor,  utilizando hibernate com hbm e mysql. Rodando a aplicação localmente no meu tomcat, e apontando para o banco remoto funcionava perfeitamente, porém quando rodava do servidor acessando o banco de dados local, funcionava por um minuto e em seguida a seguinte exceção era lançada: “com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure”. Procurando na internet ( lê-se google) achei vários motivos, que em nada me ajudaram, como por exemplo não permissão de acesso ao banco via TCP/IP, banco fora do ar, etc. Então preferi passar a bola para o pessoal da hospedagem e abri um ticket (Um parenteses aqui: O serviço de suporte do Daily Razor é excelente, resolvem tudo muito rápido.) e logo em seguida foi-me passada a solução: utilizar o C3p0 setando as seguintes configurações no hibernate.cfg.xml:

<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">300</property>
<property name="hibernate.c3p0.timeout">120</property>
<property name="hibernate.c3p0.max_size">25</property>
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_statement">0</property>
<property name="hibernate.c3p0.preferredTestQuery">select 1;</property>


Essa é a configuração default, a única coisa que precisei modificar foi o tempo de timeout, já que eles tem como tempo de timeout para o MySQL 300, segundo eles por questões de estabilidade.
Fica aí a dica, mesmo que não precise recomendo a utilização do C3p0 para pooling de conexão com o banco de dados, pois melhora a performance da aplicação. Nesse blog aqui tem algumas informações a mais.

out 21

Comparador de CMS

Primeiramente o que é um CMS. Segundo a wikipedia:

Um Sistema de Gestão de Conteúdo – SGC, (em inglês Content Management Systems – CMS), é um sistema gestor de websites, portais e intranets que integra ferramentas necessárias para criar, gerir (editar e inserir) conteúdos em tempo real, sem a necessidade de programação de código, cujo objetivo é estruturar e facilitar a criação, administração, distribuição, publicação e disponibilidade da informação. Sua maior característica é a grande quantidade de funções presentes.

Um CMS facilita muito a vida de quem tem que criar e administrar websites, por ser de fácil utilização e possuir muitas funcionalidades agregadas. Porém nem todos tem tantas funcionalidades assim, por isso venho neste post divulgar um site muito interessante que possui informações sobre diversos frameworks CMS, onde você escolhe os que tiver interesse e os compara. Lá contém informações como de qual banco de dados o CMS utiliza, se é pago ou não, qual a linguagem que ele utiliza, se possui aplicações pré-instaladas, como blogs, chats, etc. Além de n-outras informações. Para isso acesse o site do CMS matrix e escolha o que  melhor se encaixa no que você está procurando para o seu trabalho.

out 15

Java básico – Convenções de código Java (Parte 1)

Vou começar agora uma série de posts sobre como devemos escrever programas em java, tudo que eu escrever está baseado na Code Conventions para a linguagem de programação Java, ou seja, nada que eu tenha inventado.

Mas é sempre bom ter mais uma fonte de informação sobre um assunto, e em português também!

Comecemos com a seguinte pergunta: Porque programar padronizado?

Primeiramente, padrão é um “como se fazer alguma coisa”, logo quanto mais pessoas fizerem da mesma maneira, mais fácil fica a manutenção desta coisa. Um exemplo prático é: programas duram bastante tempo, desde a etapa de desenvolvimento, testes, homologação e produção. E nem sempre a mesma equipe que começou o desenvolvimento continua até o final da vida de um software, logo, quanto mais padronizado estiver, mais fácil para se dar manutenção e para se entender o que foi feito, ganhando-se assim tempo, e como tempo é dinheiro…


Agora vou falar um pouco dos padrões de arquivo e a estrutura de um arquivo.

Todos os programas em Java contém 2 tipos de sufixo:

  1. .java  – arquivos de código-fonte
  2. .class – arquivos de bytecode java, ou seja, os arquivos fontes compilados.

Um arquivo fonte java deve conter seções de código separadas por linhas em branco e opcionalmente conter comentários que identifiquem cada seção. Não é recomendado que um arquivo fonte tenha mais de 2000 linhas de código.

Este arquivo se estrutura da seguinte maneira:

  • Início dos comentários – deve conter o nome da classe, informação de versão, data, e notas de direito de cópia
/*
 * Nome da classe
 *
 * Informações de versão
 *
 * Data
 *
 * Nota de direitos de cópia
 */
  • Declarações de pacotes e imports – necessariamente nesta ordem.
package java.blah;

import java.blah.blahdy.BlahBlah;
  • Declaração de classes e de interfaces
    • Começamos com os comentários de documentação da classe, contendo a descrição, versão, data e nome do autor.
    • /**
       * Descrição da classe.
       *
       * @versão e data 1.82 18 Mar 1999
       *
       * @autor Nome Sobrenome
       */
    • Em seguida a declaração da classe ou da interface
    public class Blah  {
    • Caso necessário, um comentário sobre a implementação, quando este  não puder ser explicitado no comentário de descrição, por exemplo.
    <em>/* Comentário sobre a implementação da classe */</em>
    • Declaração das variáveis da classe que são as static, onde primeiro se declaram as variáveis public, depois as protected, por conseguinte as de nível de pacote(sem a declaração do modificador de acesso), e por fim as private.
    • /**
      *  comentario de documentacao da varClasse1
      */
      public static int varClasse1;
      
      /**
      *  comentario da varClasse2 que possui
      *  mais de uma linha
      */
      private static Object varClasse2;
    • Declaração das variáveis de instância, seguindo o mesmo padrão das de classe.
    • /**
      * comentario de documentacao da varInstancia1
      */
      public Object varInstancia1;
      
      /**
      * comentario de documentacao da varInstancia2
      */
      protected int varInstancia2;
      
      /**
      * comentario de documentacao da varInstancia3
      */
      private Object[] varInstancia3;
    • Construtores da classe
    • /**
      * comentario de documentacao do contrutor Blah
      */
      public Blah() {
      
      // ...implementação aqui...
      }
    • Métodos – é recomendado agrupar os métodos por funcionalidade, não por escopo ou acessibilidade.
    • /**
      *  comentario de documentacao do metodo fazAlgo
      */
      public void fazAlgo() {
      
      // ...implementação aqui...
      }

É isso por enquanto, no próximo post pretendo abordar as convenções para identação, indentação ou endentação, como preferir, já que esta palavra não existe no português.

out 14

Biblioteca de componentes para JSF 2

Venho aqui neste post recomendar apenas, para quem quer utilizar JSF 2, e estava acostumado a utilizar richfaces, que para a versão 2 do JSF não está ainda com versão estável, recomendo o primefaces , que é uma suite de componentes muito completa, de muito fácil utilização. Bastando apenas baixar o jar do primefaces, e adicionar a suas páginas o namespace xmlns:p=”http://primefaces.prime.com.tr/ui”. No site, há um livedemo, que mostra cada componente, e o código de sua utilização.


Um problema apenas que eu tive em utilizá-lo, foi quando tive que usar outro componente que utilizava jquery em mesma página que estivesse utilizando o primefaces, pois como ele utiliza o jquery embutido no jar, ele acaba referenciando o arquivo jquery errado, o que faz com que os componentes não funcionem.

Mas se você não for usar outro componente que utilize jquery também, é uma ótima pedida o primefaces.

out 11

Tratar exceção de unique constraint com JPA 2 e Hibernate

Em uma aplicação simples de cadastro, quando se tem campos únicos, como por exemplo cadastro de usuários, onde o nome do usuário não pode se repetir é interessante mostrar para o usuário qual o erro resultante do não cadastramento dos seus dados. No código abaixo eu tenho uma transação que persistirá um objeto do tipo usuário.

em.getTransaction().begin();
em.persist(usuario);
em.getTransaction().commit();

Porém a exceção lançada pelo JPA 2 é apenas PersistenceException, o que não diz muita coisa. Porém ela contém a cadeia de exceções lançadas desde o provider do banco de dados. Logo, uma alternativa para se descobrir qual a causa raiz da exceção é iterar pela causa da exceção, até chegar a BatchUpdateException, que é a exceção que contém uma SQLException como nextException. Esta SQLException é necessária para se extrair o nome da restrição que gerou a exceção.

catch (PersistenceException e) {

			 Throwable lastCause = e;
			 String constraintName =null;
			 while (lastCause != null){
		    	     if(lastCause.toString().startsWith("java.sql.BatchUpdateException")){
		    		     BatchUpdateException bu = (BatchUpdateException) lastCause;
		    		     constraintName = PersistenceUtil.getViolatedConstraintNameExtracter().
                                                      extractConstraintName(bu.getNextException());

		    	     }
		    	  lastCause = lastCause.getCause();

			  }

			   if(constraintName !=null){
		               throw new ConstraintViolationException("Mensagem",
                                     new SQLException(), constraintName);

		          }
        }

Para se extrair o nome da restrição é necessário utilizar o seguinte código.

public static ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {

        return EXTRACTER;
   }

	private static ViolatedConstraintNameExtracter EXTRACTER =
           new TemplatedViolatedConstraintNameExtracter() {

	      /**
	       * Extract the name of the violated constraint from the given SQLException.
	       *
	       * @param sqle The exception that was the result of the constraint violation.
	       * @return The extracted constraint name.
	       */
	      public String extractConstraintName(SQLException sqle) {
	         String constraintName = null;

	         int sqlError = Integer.valueOf(JDBCExceptionHelper.extractSqlState(sqle));

	         if(sqlError == 23505){

	            constraintName = extractUsingTemplate("violates unique constraint \"","\"",
                                      sqle.getMessage());
	         }	         

	         return constraintName;
	      }

	   };

Onde ViolatedConstraintNameExtracter é uma interface do pacote org.hibernate.exception e TemplatedViolatedConstraintNameExtracter é a classe abstrata que implementa esta interface.
É necessário implementar o método extractConstraintName(SQLException sqle) herdado da interface.
Nele eu verifico qual o código de erro, utilizando o JDBCExceptionHelper do pacote org.hibernate.exception. No meu caso eu estou utilizando PostgreSQL, e neste endereço: http://www.postgresql.org/docs/8.1/interactive/errcodes-appendix.html temos todos os códigos de erro gerados.
Dependendo do código de erro eu utilizo o método extractUsingTemplate da classe TemplatedViolatedConstraintNameExtracter, passando como parâmetros o padrão da mensagem até o início do nome da restrição, o padrão da mensagem após o nome da restrição e a mensagem da SQLException.

Está um pouco confuso, mas realmente é bem chato tratar essa exceção usando JPA 2, mas basicamente utilizando esses códigos e fazendo as devidas personalizações para a sua aplicação, você conseguirá resolver esse problema.