Arquivo para outubro de 2012

Lendo arquivos de configuração .properties

Quem trabalha com desenvolvimento Java certamente já teve contato e/ou vez ou outra teve que configurar arquivos com a extensão .properties. Esses arquivos são muito uteis quando precisamos configurar propriedades de algum sistema de forma que não seja via banco e nem fique preso as classes Java. Quando um arquivo .properties é lido por classes Java as informações são armazenadas em um mapa de chave e valor. Dessa forma precisamos apenas jogar esses valores em algum a variável e fazermos o que bem entendermos com ela.

Numa classe de envio de emails por exemplo poderíamos armazenar alguns dados em arquivos properties como no exemplo abaixo:

    //Trecho do nosso arquivo de propriedades
    smtp=smtp.gmail.com
    porta=587
    ssl=true

A classe java abaixo é responsável por ler esse arquivo .properties

package br.com.semeru.util;

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import javax.faces.context.FacesContext;

public class PropertiesLoader {    

	//Crio uma instancia da classe properties
    private static Properties prop = new Properties();
    
	//Crio um método estático que pode ser acessado por outras classes da aplicação sem a necessidade de instanciar
    public static Properties propertiesLoader() {
		
		//Informo o caminho onde se encontra meu arquivo properties de forma dinâmica
		//Poderia fazer isso de forma estática passando o diretório completo mas obviamente isso não é muito interessante.
        String atualDir = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/")
            +"WEB-INF/classes/nome_do_arquivo.properties";
        try {   //Tento recuperar as informações do arquivo de propriedades        
            
			//Apenas para testar imprimo o diretório atual do meu arquivo properties
			System.out.println(atualDir);
			//Crio uma instância de File passando o meu arquivo .properties via construtor
            File file = new File(atualDir);  
			//Agora crio uma instância de FileInputStream passando via construtor o objeto file instanciado acima
            FileInputStream fileInputStream = new FileInputStream(file);
			//Leio o fileInputStream recuperando assim o mapa contendo chaves e valores
            prop.load(fileInputStream);
			//Fecho o fileInputStream
            fileInputStream.close();           
        } catch (Exception e) {
			//Trato possíveis exceções
        }
        return prop;
		//Retorno um objeto prop com o mapa correspondente ao meu arquivo properties
    }
    
}

Aqui acessamos as propriedades lidas do arquivo em outra classe da aplicação.

/*Agora de qualquer classe que possa importar a PropertiesLoader podemos recuperar
as informações do .properties apenas passando a chave você receberá o valor. Depois
basta converter os resultados da forma que mais lhe convier.
Para recuperar dados do tipo boolean podemos fazer assim Boolean.parseBoolean(),
Integer com um Integer.parseInt(), já uma informação do tipo String basta apenas um .toString()
*/ 
smtp = PropertiesLoader.propertiesLoader().getProperty("smtp").toString();
porta = Integer.parseInt(PropertiesLoader.propertiesLoader().getProperty("porta"));
ssl = Boolean.parseBoolean(PropertiesLoader.propertiesLoader().getProperty("ssl")); 

Bom pessoal como podem ver é muito simples ler configurações em arquivos properties. Qualquer dúvida, postem aí.

Tags: ,

Deploy de aplicações em Cloud Computing

Bom após algumas dores de cabeça com os servidores de hospedagens tradicionais decidi pesquisar alternativas no ambiente Cloud. Como resultado da pequena avalição feita vou descrever sobre cada um dos serviços e seus pontos fortes e fracos (recomendo que você volte aqui em mais alguns dias pois esse post é apenas um esboço, a medida que for testando outros serviços irei adicionando mais avaliações).

Uhuru Cloud

Um dos primeiros serviços de Cloud Computing que testei foi o Uhuru. Possui muitos pontos fortes para aplicações não Java. Apesar de oferecer suporte à Java não consegui fazer nenhum deploy bem sucedido. Já para quem trabalha com .NET, Ruby, PHP ou mesmo para aqueles que desejarem deixar apenas a base de dados na Cloud o Uhuru é uma boa pedida. Além do bom suporte a .NET o Uhuru oferece também um plugin para o Visual Studio e um ano de graça para novos usuários.

Site: http://uhurusoftware.com/

Canal no Youtube: http://www.youtube.com/user/UhuruSoftwareInc

Jelastic

De todos os que avaliei o Jelastic foi o que mais me agradou, entretanto o período trial é de apenas 2 semanas. Esse serviço é voltado especificamente para aplicações Java, oferecendo suporte aos JDK’s 6 e 7, Tomcat 6 e 7, Jetty 6 e GlassFish 3. Com relação aos SGBS suportados temos o MariaDB, MySQL e Postgree, além disso suporta MongoDB e MenCached. Pra completar a interface e a facilidade de deploy chega a ser ridícula de tão simples. O que pega mesmo é o curto período free.

Site: http://jelastic.com

Canal no Youtube: http://www.youtube.com/user/JelasticCloud

Amazon Webservices

Não avaliei esse cara por que ele exige numero de cartão no ato do cadastro, além de tudo o processo de cadastramento dá sono de tão demorado. Entretanto ele oferece seus serviços gratuitamente por um ano para novos usuários. Então para aqueles que tiverem um pouco mais de paciência tenta lá e depois posta aqui o que achou.

Site: http://aws.amazon.com/free/

Canal no Youtube: http://www.youtube.com/user/AmazonWebServices

CloudBees

O CloudBees também oferece um serviço excelente para desenvolvedores oferecendo diversos serviços free, claro que com algumas limitações a pior delas é o fato de suportar bancos de no máximo 4MB outros pontos positivos é o plugin para o Eclipse e suporte nativo ao Jenkins. Em relação ao Jelastic ele oferece maiores vantagens para o desenvolvimento e integração contínua. Possibilita ainda a criação de repositórios, sejam eles SVN ou GIT, suporta o deploy de aplicações desenvolvidas em diversos frameworks Java. O mais interessante na minha opinião é a possibilidade de fazer deploy de artefatos Maven quase que instantâneamente. Você faz o commit, o Jenkins pega o seu código no repositório SVN ou GIT, executa os testes unitários e verifica as dependências, compila e faz o deploy do .war ou .jar imediatamente. Conclusão ótimo serviço melhoraria bastante se tivesse um painel de controle similar ao do Jelastic.

Site: http://www.cloudbees.com/platform-overview.cb

Conta Freehttps://grandcentral.cloudbees.com/account/signup

Canal no Youtube: http://www.youtube.com/user/CloudBeesTV

Cloud Foundry

Sei bem pouco a respeito da Cloud Foudry. Mas de cara posso adiantar que ela é mantida pela Spring Source e que existe um plugin para a IDE Spring Source Tool Suite. Assim que pesquisar mais a respeito volto aqui e edito o post.

Site: www.cloudfoundry.org

Canal no Youtubehttp://www.youtube.com/user/CloudFoundry

Tags:

Manipulando de Exceções no JavaServer Faces (JSF) 2.x

Uma das funcionalidades mais simples e legais introduzidas pela especificação 2.0 do JSF é a possibilidade de se criar um manipulador global de exceções. Trechos de código como esse aqui abaixo tratando as exceções previstas uma a uma no web.xml se tornaram desnecessários.

<error-page>
  <error-code>404</error-code>
  <location>/404.xhtml</location>
</error-page>

Ao invés da solução acima, o JavaServer Faces nos permite implementar um manipulador global de exceções de forma relativamente simples para todas as exceções que podem ocorrer na aplicação. Para isso, você precisa apenas de criar duas classes que estendam as classes:
ExceptionHandlerWrapper – Que fornece uma implementação simplificada da ExceptionHandler permitindo por exemplo que os desenvolvedores possam fornecer um comportamento especializado para uma instância ExceptionHandler.
ExceptionHandlerFactory – Essa classe por sua vez atua como uma Factory responsável por criar e retornar, quando necessário, uma nova instância de ExceptionHandler.
Por fim você precisa apenas algumas linhas ao arquivo “faces.config.xml” responsáveis por registrar a classe de tratamento no FacesServlet.

	
<factory>
  <exception-handler-factory>
     br.com.semeru.exceptions.CustomExceptionHandlerFactory
  </exception-handler-factory>
</factory>

No trecho de código abaixo temos a classe “CustomExceptionHandlerFactory” que é responsável por fabricar uma instância da classe “CustomExceptionHandler” que é responsável por capturar e tratar a exceção.

package br.com.semeru.exceptions;

import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;

public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {
    private ExceptionHandlerFactory parent;

    public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        ExceptionHandler handler = new CustomExceptionHandler(parent.getExceptionHandler());
        return handler;
    }

}

Já no trecho abaixo temos a classe “CustomExceptionHandler” que pode tratar a exceção da forma que você julgar mais apropriada. Você pode simplesmente imprimir a StackTrace e retornar uma página de erros, ou tratar as exceções que mais ocorrem e retornar uma página personalizada para cada uma delas. Outra coisa que pode ser interessante é enviar a StackTrace via e-mail para a equipe de desenvolvimento.

package br.com.semeru.exceptions;

//import java.io.PrintWriter;
//import java.io.StringWriter;
import java.util.Iterator;
import java.util.Map;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.application.NavigationHandler;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;

//Inicialmente devemos implementar a classe CustomExceptionHandler que extende a classe ExceptionHandlerWrapper
public class CustomExceptionHandler extends ExceptionHandlerWrapper {

    private ExceptionHandler wrapped;

    //Obtém uma instância do FacesContext
    final FacesContext facesContext = FacesContext.getCurrentInstance();

    //Obtém um mapa do FacesContext
    final Map requestMap = facesContext.getExternalContext().getRequestMap();

    //Obtém o estado atual da navegação entre páginas do JSF
    final NavigationHandler navigationHandler = facesContext.getApplication().getNavigationHandler();

    //Declara o construtor que recebe uma exceptio do tipo ExceptionHandler como parâmetro
    CustomExceptionHandler(ExceptionHandler exception) {
        this.wrapped = exception;
    }

    //Sobrescreve o método ExceptionHandler que retorna a "pilha" de exceções
    @Override
    public ExceptionHandler getWrapped() {
        return wrapped;
    }

    //Sobrescreve o método handle que é responsável por manipular as exceções do JSF
    @Override
    public void handle() throws FacesException {

        final Iterator iterator = getUnhandledExceptionQueuedEvents().iterator();
        while (iterator.hasNext()) {
            ExceptionQueuedEvent event = iterator.next();
            ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();

            // Recupera a exceção do contexto
            Throwable exception = context.getException();

            // Aqui tentamos tratar a exeção
            try {

//                // Aqui você poderia por exemploinstanciar as classes StringWriter e PrintWriter
//                StringWriter stringWriter = new StringWriter();
//                // PrintWriter printWriter = new PrintWriter(stringWriter);
//                // exception.printStackTrace(printWriter);
//                // Por fim você pode converter a pilha de exceções em uma String
//                String message = stringWriter.toString();
//
//                // Aqui você poderia enviar um email com a StackTrace
//                // em anexo para a equipe de desenvolvimento
//
//                // e depois imprimir a stacktrace no log
//                exception.printStackTrace();

                // Coloca uma mensagem de exceção no mapa da request
                requestMap.put("exceptionMessage", exception.getMessage());

                // Avisa o usuário do erro
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage
                    (FacesMessage.SEVERITY_ERROR, "O sistema se recuperou de um erro inesperado.", ""));

                // Tranquiliza o usuário para que ele continue usando o sistema
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage
                    (FacesMessage.SEVERITY_INFO, "Você pode continuar usando o sistema normalmente!", ""));

                // Seta a navegação para uma página padrão.
                navigationHandler.handleNavigation(facesContext, null, "/restrict/home.faces");

                // Renderiza a pagina de erro e exibe as mensagens
                facesContext.renderResponse();
            } finally {
                // Remove a exeção da fila
                iterator.remove();
            }
        }
        // Manipula o erro
        getWrapped().handle();
    }
}

No bloco try-finally você pode converter o Throwable em qualquer exceção específica e dar um tratamento especial a cada uma delas. Um simples problema de ViewExpiredException, por exemplo, pode ser redirecionado para uma página informando que a “sessão expirou” já, no caso de uma exceção do tipo NullPointerException podemos usar uma página padrão apenas dizendo algo como “Ocorreu um erro inesperado, por favor, tente novamente mais tarde.”
Um detalhe muito importante a se lembrar é que ao lidar com exceções em desenvolvimento web, você deve garantir que não está compartilhando informações indesejadas e/ou sensíveis ao retornar o erro para a página web.

Bom é isso e espero que gostem do post.

Editado para responder ao comentário do André

Olá gravei uma vídeo aula explicando de forma clara como adotar o exception handler em um projeto JSF.

Tags: , , , , ,

Instalação e configuração do Archiva

O que é e para que serve


Normalmente empresas de desenvolvimento encapsulam classes e trechos de código, comuns em várias aplicações, em bibliotecas ou frameworks próprios e é justamente aí que entra a dupla Apache Archiva e Apache Maven. Ambos são soluções para gerenciamento de dependências. Sendo que o Apache Maven se encarrega, diretamente de acessar repositórios externos e baixar dependências necessárias a um determinado projeto. O Apache Archiva, por sua vez, é um poderoso gerenciador de repositórios, ele pode ser usado tanto para criar repositórios de bibliotecas próprias quanto para servir de cache entre os desenvolvedores e os repositórios externos, minimizando assim tráfego em rede. Dessa forma podemos dizer que o Apache Archiva é um complemento e tanto aos serviços oferecidos pelo Apache Maven. O objetivo deste post é demonstrar como instalar o Apache Archiva em ambiente semeru.

Apache Archiva instalação

1. Download do Apache Archiva

 Acesse o site official do projeto Apache Archiva, Click no link de download link, escolha o arquivo Archiva 1.3.5 Standalone, clique no link sugerido.

Por padrão esse arquivo já vem com o container web Jetty.

2. Extraia o arquivo

Extraia o arquivo zip em um diretório qualquer  Ex: “D:\apache-archiva-1.3.5\”

3. Instalando como serviço do Windows

Pelo prompt do DOS acesse o diretório /bin do pacote recem extraído e execute o commando “archiva install” para registrar como um serviço do Windows.

D:\apache-archiva-1.3.5\bin>archiva install
wrapper  | Apache Archiva installed.

4. Inicializando Archiva

1. Para inicializar o Archiva digite o comando “archiva start”.

D:\apache-archiva-1.3.5\bin>archiva start
wrapper  | Starting the Apache Archiva service...
wrapper  | Apache Archiva started.

5. Archiva web admin

Abra seu navegador e acesse o Apache Archiva web admin pela seguinte URL http://semeru:8080/archiva/.

OBS: A versão standalone do  Apache Archiva usa o Jetty como contêiner web padrão e 8080 é a porta default.

6. Concluído

Pós Instalação

Caso você prefira mudar a porta padrão do Apache Archiva para evitar conflitos com o Tomcat por exemplo basta seguir os procedimentos a seguir.

1. Arquivo de configuração do Archiva

Localize no Apache Archiva web container o arquivo de configuração chamadojetty.xml. Ex: “D:\apache-archiva-1.3.5\conf\jetty.xml

2. Alterando o número da porta

Encontre o seguinte padrão

<Call name="addConnector">
   <Arg>
      <New class="org.mortbay.jetty.nio.SelectChannelConnector">
         <Set name="host">
            <SystemProperty name="jetty.host"/>
         </Set>
         <Set name="port">
            <SystemProperty name="jetty.port" default="8080"/>
         </Set>
         <Set name="maxIdleTime">30000</Set>
         <Set name="Acceptors">2</Set>
         <Set name="statsOn">false</Set>
         <Set name="confidentialPort">8443</Set>
         <Set name="lowResourcesConnections">5000</Set>
         <Set name="lowResourcesMaxIdleTime">5000</Set>
      </New>
   </Arg>
</Call>

Altere as configurações  jetty.port para outra porta  como por exemplo a “8888″.

<Set name="port">
   <SystemProperty name="jetty.port" default="8888"/>
</Set>

3. Reinicialize o Apache Archiva

Pare o Apache Archiva através do comando “archiva stop” e inicialize novamente com “archiva start”, para que as novas configurações tenham efeito. Se preferir você pode simplesmente utilizar o comando “archiva restart”. Agora acesse o Apache Archiva web admin pela URL http://semeru:8888/archiva/.

Tags: , , , , ,