Results tagged “java” from JEP - Java e Produtividade

jfilehelpers.png
Depois de um bom tempo só promovendo o uso da biblioteca JFileHelpers através de um post neste blog, decidi fazer o website do projeto.

Embora ainda esteja no seu começo, pelo menos é um lugar comum para os usuários poderem ter uma referência de como usar a biblioteca. A outra grande vantagem é ter um versão em inglês. Assim, os gringos também podem conferir e quem sabe consigo algum novo colaborador.

jfilehelpers-website.png

Se você tem vontade de participar de um projeto Open Source em Java, que faz uso de tecnologias interessantes como Refactoring, Annotations e muito mais, visite a página de contatos do projeto e me mande seus dados!

Mesmo se você acredita que não pode ajudar com o código, você pode fazer testes, ajudar no website ou mesmo sugerindo novas funcionalidades. Não deixe de deixar seu comentário se você testar a biblioteca! Este é aquele tipo de projeto "movido a comentários" :-).





Links:

log5j

|
log5j-picture.jpgNuma das minhas andanças atrás de novidades, me deparei com o log5j. Primeiramente, pensei que fosse uma atualização do famoso framework para logging ou algum novo framework que trouxesse novidades em relação ao já famigerado log4j.

Na verdade, não é nada disso. Trata-se apenas de um face-lift para o log4j, trazendo uma implementação mais atual. Esta biblioteca - que, diga-se de passagem, só tem uma classe - tem dois principais objetivos:

Permitir logs no estilo do comando printf:

Antes:
log.error(
   "Houve um erro: " + foo + 
   " por causa disso: " + bar + 
   " nisso: " + car );
Depois:
log.error(
   "Houve um erro: %s por causa disso: %s nisso: %s", 
   foo, bar, car);
Além de prováveis ganhos de performance, acredito que o código fique bem mais limpo.

Acabar com o inconveniente Logger.getLogger(NomeDaClasse.class):

Antes:
private static final Logger log = 
   Logger.getLogger(NomeDaClasse.class);
Depois:
private static final Logger log = new Logger();
E é isso, simples assim... Eu gostei bastante porque é extremamente simples e despretensioso, mas agrega duas funcionalidades que há tempos eu gostaria de ver no Log4J.

Vocês acham que vale a pena usar essa lib? Porque? Mandem comentários!



Links:
lightweight-1.jpg Poucas pessoas sabem, mas a versão 6 do JDK da Sun vem com um HttpServer light nativo. Não é necessário mais escrever http sobre socket ou utilizar alguma biblioteca externa. Mas atenção: esta classe está em um pacote da sun e não há garantias que outras implementações java terão estas classes.

De qualquer forma, é muito fácil utilizar a classe para resolver problemas onde seja necessário um HttpServer out-of-the-box.

Tudo o que deve ser feito é criar uma nova instância da classe HttpServer (pacote com.sun.net.httpserver) através do método estático create, passando o IP e a porta aos quais o servidor irá ouvir, além do backlog, que é o tamanho da fila que o servidor irá armazenar com requests que estão esperando para serem atendidos.
HttpServer server = 
	HttpServer.create(new InetSocketAddress(8088), 0);
Depois disso, você deve criar uma classe que implemente a interface HttpHandler para atender suas requisições. Nela é colocada a regra de negócio do que deve ser feito e o que deve ser respondido ao cliente.

A cada novo request, o método handle é chamado, tendo um HttpExchange como parâmetro. Esta classe tem uma série de propriedades que facilitam a interação com o servidor.

Por fim, você deve criar um contexto no qual este handler irá ser utilizado. O contexto nada mais é do que uma espécie de virtual folder para sua URL. Por exemplo, se você utilizar o contexto "/exemplo", o handler irá responder quaisquer requisições para http://seuservidor:8088/exemplo (incluindo arquivos dentro desta pasta, parâmetros e sub-pastas). Veja este exemplo:
public static void main(String[] args) throws IOException {
	// cria um novo servidor que vai ouvir a porta 8088 local
	HttpServer server = 
		HttpServer.create(new InetSocketAddress(8088), 0);

	// cria um contexto com um HttpHandler dinâmico
	server.createContext("/exemplo", new HttpHandler() {

		@Override
		public void handle(HttpExchange xchg) 
			throws IOException {

			// corpo da resposta
			StringBuffer response = new StringBuffer();

			// o corpo da resposta será apenas uma indicação
			// de qual foi o método do request (GET / POST)
			response.append("<html><body>");
			response.append("Request method: ");
			response.append(xchg.getRequestMethod());
			response.append("</body></html>");

			// envia uma resposta de código 200 (OK) para 
			// o cliente e com o Content-Length, que é o 
			// tamanho da resposta
			xchg.sendResponseHeaders(200, response.length());
			
			// recupera o stream de saída
			OutputStream os = xchg.getResponseBody();
			// imprime nele a resposta
			os.write(response.toString().getBytes());
			// e fecha o stream (com try..finally talvez?)
			os.close();
		}
		
	});
	
	// por fim inicializamos o servidor
	server.start();
}
Se você rodar esta classe e apontar seu servidor para o endereço mencionado, você vai ver a mensagem conforme abaixo:

httpserver-screenshot.jpg Porém se você for mais além, e tentar abrir várias requisições em paralelo, verá que a aplicação começará a responder de forma bem lenta. Para resolver o problema, precisamos criar uma thread para cada requisição. No meu caso criei uma classe que estende thread para atender cada uma das requisições:
public class HandleThread extends Thread {
    public HttpExchange xchg;
    
    public HandleThread(HttpExchange xchg) {
        this.xchg = xchg;
    }
    
    @Override
    public void run() {            
        try {
            // corpo da resposta
            StringBuffer response = new StringBuffer();

            // o corpo da resposta será apenas uma indicação
            // de qual foi o método do request (GET / POST)
            response.append("<html><body>");
            response.append("Request thread: ");
            response.append(Thread.currentThread().getId());
            response.append("</body></html>");

	    // o resto continua igual (...)
        }
        catch (Throwable t) {
            t.printStackTrace();
        }
    }
}
Finalmente, alteramos a classe principal para criar uma thread a cada nova requisição:
// (...)
// cria um contexto com um HttpHandler dinâmico
server.createContext("/echo", new HttpHandler() {

    @Override
    public void handle(HttpExchange xchg) throws IOException {
        HandleThread ht = new HandleThread(xchg);
        ht.start();
    }
    
});
// (...)
Vale a pena salientar que existe suporte nas APIs também a HTTPS (veja Javadoc nos links abaixo).

Estes exemplos têm apenas um caráter didático. Em uma aplicação séria, não seriam criadas threads a esmo: usaríamos um pool de threads e técnicas mais apuradas para controle de requisições.

Mas acho que a idéia era esta: dar um apanhado geral de como usar estas novas classes, oferecidas pelo JDK 6.

Aguardo seus comentários sobre o que você pensa destas idéias.



Links:
text.jpgUma coisa que eu sempre gostei de trabalhar é com conversão de dados. Sempre achei desafiador pegar dados em um formato proprietário de uma aplicação e tranformá-lo em algo interessante para outra aplicação.

Durante minha carreira como Analista Desenvolvedor, já participei de diversas migrações de dados, já criei softwares para automação de conversão de interfaces, já utilizei toolkits prontos, como o Data Transformation Services do MS SQL.

Foi esta experiência que me levou a conhecer um excepcional toolkit para importar, exportar e trabalhar com arquivos texto, mais conhecidos como flat files. Trata-se do FileHelpers, escrito pelo argentino Marcos Meli. O toolkit se aproveita de annotations para descrever o arquivo e transformá-lo de texto para um objeto ou vice-versa. O grande problema, para mim, deste toolkit é que ele está escrito em C# e eu utilizo Java no meu dia-a-dia. Então veio a idéia de fazer um port desta biblioteca. Nasceu então o JFileHelpers. A idéia inicial é ter as mesmas funcionalidades do FileHelpers, em Java.

Mas chega de lero-lero, vamos às funcionalidades. Veja que interessante como fica um bean anotado pelo JFileHelpers:
@FixedLengthRecord()
public class Customer {
	@FieldFixedLength(4)
	public Integer custId;

	@FieldAlign(alignMode=AlignMode.Right)
	@FieldFixedLength(20)
	public String name;

	@FieldFixedLength(3)
	public Integer rating;

	@FieldTrim(trimMode=TrimMode.Right)
	@FieldFixedLength(10)
	@FieldConverter(converter = ConverterKind.Date, 
		format = "dd-MM-yyyy")
	public Date addedDate;
	
	@FieldFixedLength(3)
	@FieldOptional
	public String stockSimbol;	
}

Neste exemplo, estamos trabalhando com um arquivo de texto com delimitação, por exemplo:

1   Antonio Pereira     10012-12-1978ABC
2   Felipe Coury          201-01-2007
3   Anderson Polga       4212-11-2007DEF

Tudo o que é necessário fazer, para ler este arquivo seria:
FileHelperEngine<Customer> engine = 
	new FileHelperEngine<Customer>(Customer.class);	
List<Customer> customers = 
	new ArrayList<Customer>();

customers = engine.readResource(
	"/samples/customers-fixed.txt");

E voilá: você tem um um ArrayList devidamente preenchido com objetos do tipo Customers, com todas as regras que você definiu. Note que a conversão do campo addedDate foi feita de forma transparente, usando as anotações de formatação:
@FieldTrim(trimMode=TrimMode.Right)
@FieldFixedLength(10)
@FieldConverter(converter = ConverterKind.Date, 
	format = "dd-MM-yyyy")
public Date addedDate;

Além destas funcionalidades, o JFileHelpers permite que você faça o caminho inverso, ou seja, se você tem objetos anotados, ele pode fazer a persistência de forma extremamente fácil, veja no nosso exemplo:
O arquivo para este exemplo ficaria:

   2        Felipe Coury  201-01-2007   
   3      Anderson Polga 8212-11-2007APR

Isto é apenas o começo. Existem muito mais funcionalidades fantásticas no JFileHelpers (como por exemplo, trabalhar com arquivos delimitados, entre outros). Porém, sou suspeito para falar porque sou o pai da criança. Então sugiro que, se você quiser fazer alguns testes e conhecer melhor esta biblioteca, faça o download dos binários dos arquivos fontes.

Agora, se você se empolgar e quiser contribuir para o projeto, entre na página do SourceForge e cadastre-se como desenvolvedor, você será muito bem vindo. Em caso de dúvidas, entre em contato comigo, que eu terei prazer em ajudar.



Links:
Clicky Web Analytics