MouseOver Studio

/* TODO */

MouseOver Studio header image 1

“Tudo o que eu sei sobre DSLs o aprendi com video games”

May 11th, 2008 · Sem comentários

Constantemente quando estou desenvolvendo software lembro desse post realizado por Phillip Calçado aka Shoes.

Confesso que quando li o título pensei “Vixi o Shoes deve ter bebido demais naqueles barzinhos em Melbourne” :P mas quando terminei de ler o post meu pensamento foi “PQP que foda!”.

O post esta em inglês mas a idéia de forma simplificada é que os video games de um tempo atrais são comparáveis com código confuso e os video games modernos com código simples de entender.

Para explicar tal comparação Shoes começa mostrando uma imagem do jogo Pong:

Pong

Ele explica que o jogo representa um tennis de mesa mas pode ser confuso identificar isso, que pode ser confundido com gol a gol ou com um jogo de naves. O mesmo acontece com alguns códigos. Quantas vezes ja vimos códigos que são muito difíceis de ser analisados e/ou podem parecer que estão fazendo uma coisa quando na realidade estão fazendo outra? Foi mostrado o seguinte exemplo:

public void sendEmailWithCsvFile(String from, String to, String subject,
		String body, List csvFileLines) {
	Properties props = new Properties();
	props.put("mail.smtp.host", "localhost");
	Session session = Session.getDefaultInstance(props);
	MimeMessage msg = new MimeMessage(session);
	try {
		msg.setFrom(new InternetAddress(from));
		InternetAddress[] address = { new InternetAddress(to) };
		msg.setRecipients(Message.RecipientType.TO, address);
		msg.setSubject(subject);
		msg.setSentDate(new Date());
		MimeBodyPart part1 = new MimeBodyPart();
		part1.setText(body);
		MimeBodyPart part2 = new MimeBodyPart();
		StringBuffer buffer = new StringBuffer();
		for (String line : csvFileLines)
			buffer.append(line + "\n");
		part2.setContent(buffer.toString(), "text/csv");
		part2.setFileName("file1.csv");
		Multipart mp = new MimeMultipart();
		mp.addBodyPart(part1);
		mp.addBodyPart(part2);
		msg.setContent(mp);
		Transport.send(msg);
	} catch (AddressException e) {
		throw new RuntimeException(e);
	} catch (MessagingException e) {
		throw new RuntimeException(e);
	}
}

A simples vista fica difícil de entender o que o código esta fazendo, o que ele representa. Esse código poderia ser bem mas claro e explicito, como o seguinte:

public void sendEmailWithCsvFile(String from, String to, String subject,
		String body, List csvFileLines) {
	StringBuffer buffer = new StringBuffer();
	for (String line : csvFileLines)
		buffer.append(line + "\n");
	Properties props = new Properties();
	props.put("mail.smtp.host", "localhost");
	MailService mailService = new MailService(props);
	mailService.newMessage()
		.from(from)
		.to(to)
		.subject(subject)
		.body(body)
		.attachTextFile("file3.csv", buffer.toString())
		.send();
}

É esse tipo de código, simples de entender, que se compara com os video games modernos, como Rockstar Table Tennis:

Rockstar Table Tennis

Ao ver aquele jogo não cabe duvida que se trata de um jogo de tennis de mesa.

Quando estou escrevendo código lembro do entendido nesse post e tento fazer meu código comparável com os jogos modernos, tentando que eles representem ao máximo a intenção deles. Quem sabe algum dia a experiência de ler meu código seja tão próxima ao domínio como a dos jogos de Wii com alguns esportes.

→ Sem comentáriosTags: ddd · programação · qualidade

Workshop sobre modelagem ágil e DDD a ser realizado em São Paulo

April 26th, 2008 · 1 comentário

De acordo com o anunciado no grupo Domain Driven Design no Yahoo! Groups vai ser realizado um workshop sobre modelagem ágil e DDD em São Paulo os dias 16 e 17 de Maio, um dia antes do Falando em Java 2008.

A descrição do workshop é:

Aprenda a modelar software de forma orientada ao negócio e utilizando técnicas de modelagem ágil, neste workshop focado em práticas e dinâmicas. Saia Planejando, Modelando e Desenvolvendo Softwares com Produtividade.

e a agenda:

  • Um passeio pela MDA (Model Driven Architecture)
  • Conhecendo a DDD (Domain Driven Design)
  • O que é DDD
  • Para que usar DDD
  • Arquitetura em Camadas (Layered Architecture)
  • Domain Objects
  • Linguagem Onipresente (Ubiquitous Language)
  • Design Flexível (Supple Design)
  • Design Estratégico (Strategic Design)
  • O Manifesto Ágil
  • Engenharia de requisitos com Scrum, XP e FDD
  • Testes Ágeis
  • Documentação Ágil
  • Explorando a visão arquitetural
  • M3-Modelagem Baseada em Mapas Mentais
  • UML em Cores
  • Uso de prototipação
  • Agile Draw
  • Um projeto do “zero”- Dinâmicas Práticas

Os instrutores são Felipe Rodrigues de Almeida, participante ativo no desenvolvimento do Struts2 e paletraste do QCon 2008 e Manoel Pimentel Medeiros, que participou do time de desenvolvimento do NetBeans e é diretor da revista Visão Agil. Os dois com muita experiência na area e coisas que um esquece depois de ler.

O preço é R$ 350,00. Mais informação aqui.

→ 1 comentárioTags: comunidade · ddd · modelagem

Falando em Java 2008, eu vou!

April 24th, 2008 · 1 comentário

Falando em Java 2008

No ano passado eu não consegui comparecer mas esse ano eu vou!

Dia 18 de maio, a Caelum promoverá o evento Falando em Java 2008. Será um dia repleto de palestras sobre diversos temas atuais da área, com instrutores da Caelum como palestrantes. (…)

E, neste ano, como palestrante convidado, teremos um dos líderes da JPA 2.0 e líder da implementação JPA do Hibernate, Emmanuel Bernard, vindo direto dos EUA especialmente para o evento. Ele trará as novidades da JPA 2.0 e o Hibernate Search.

Falaram no Guj que o ano passado esgotaram os ingressos. Vou correr e comprar o meu. Ainda bem sou ex-aluno da Caelum e porem tenho desconto :D

Para mais informação podem acessar o post no blog da Caelum.

→ 1 comentárioTags: comunidade · java

Comunicação web criptografada e segura com Bouncy Castle e RSA

April 12th, 2008 · Sem comentários

Na empresa onde atualmente trabalho vou começar a trabalhar num projeto onde a seguridade é muito importante, pelo que fui instruído para aprender sobre Bouncy Castle. Nunca tinha ouvido falar aquelas palavras juntas, então vou começar do zero.

O que é Bouncy Castle?

Depois de acessar a página do Bouncy Castle, a definição no Wikipedia e a definição no Java Glossary me atrevo a dizer que Bounce Castle é uma API de criptografia para Java e também um provedor das especificações JCE e JCA da Sun.

Algo curioso sobre Bouncy Castle é que por ser um projeto australiano ele não precisa cumprir as leis de Estados Unidos que proíbem a exportação de algoritmos fortes de criptografia. Mais informação aqui.

O que é RSA?

De acordo com a Wikipedia, RSA é

um algoritmo de encriptação de dados, (…) até à data (2008), a mais bem sucedida implementação de sistemas de chaves assimétricas, e fundamenta-se em Teorias Clássicas dos Números. É considerado dos mais seguros, já que mandou por terra todas as tentativas de quebrá-lo. Foi também o primeiro algoritmo a possibilitar encriptação e assinatura digital, e uma das grandes inovações em criptografia de chave pública.

RSA é um algoritmo que cria duas chaves, uma delas sendo pública e a outra privada. Toda mensagem que for cifrada utilizando a chave pública somente vai poder ser decifrada utilizando a chave privada.

Trabalhando com RSA

Vamos por as mãos na massa e brincar um pouco. Construiremos uma aplicação web simples que utilizando RSA crie uma chave privada e mande uma pública ao cliente. A aplicação servidor depois ira decifrar mensagens que foram cifradas com a chave publica. Para cifrar a chave pública na aplicação cliente utilizaremos a biblioetaca jsbn, dos estudandes de Stanford, implementada em JavaScript.

Começarei criando uma aplicação web dinâmica no Eclipse que rodara sobre o Tomcat e adicionarei ao meu pacote uma classe serviço que fará as operações relacionadas com Bouncy Castle e RSA e uma servlet que delegara as chamadas HTTP para o serviço correspondente.

Vou começar a implementar o serviço de RSA que utilizara Bouncy Castle como implementação, pelo que terei que incluir a livraria correspondente no meu classpath. As livrarias podem ser descarregadas de aqui. Nesse caso somente precisaremos da livraria Provider e OpenPGP/BCPG.

O primeiro passo ao trabalhar com Bouncy Castle é adicionar o provedor Bouncy Castle à lista de provedores. Colocarei o seguinte código no construtor da minha classe serviço:

Security.addProvider(new BouncyCastleProvider());

Agora vou criar um gerador de chaves pares para o algoritmo RSA utilizando como provedor o Bouncy Castle (BC) e depois inicializar ele especificando que o tamanho das chaves vai ser 1024 e que o provedor de números aleatórios vai ser SecureRandom, do pacote java.security. Essas operações irão estar num método chamado generateKeys que terminara devolvendo um par de chaves. O método fica assim:

public KeyPair generateKeys() throws Exception {
	KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA",
			"BC");
	keyGenerator.initialize(1024, new SecureRandom());
	return keyGenerator.generateKeyPair();
}

O segundo método da classe serviço recebera uma mensagem cifrada junto com a chave privada correspondente à chave pública utilizada para cifrar a mensagem e retornara a mensagem decifrada.

O primeiro passo é pegar uma instância da classe Cipher. A classe Cipher é encarregada de cifrar e de decifrar arrays de bytes. Para pegar uma instância da classe Cipher chamamos o método estático getInstance da mesma. Ela recebe dois parâmetros: a transformação a ser utilizada e o provedor. Já sabemos que o provedor é Bouncy Castle, mas o que é a transformação?

A transformação é o método que foi utilizado para cifrar nossa mensagem. No nosso caso a transformação é RSA/NONE/PKCS1Padding, que define que utilizamos RSA como algoritmo de criptografia, que não utilizamos nenhuma técnica especial para cifragem em bloco e que utilizamos PKCS #1 como técnica de enchimento. Escolhi essa transformação porque é compatível com a livraria JavaScript utilizada.

Talvez agora surgiram mais dúvidas. Técnica para cifragem em bloco? Técnica de enchimento?

Quando ciframos um texto utilizando RSA, partimos ele em vários blocos e cada bloco vai sendo cifrado de alguma maneira. Como os blocos se relacionam e o tamanho deles, entre outras coisas, são características que definem as diferentes técnicas de cifragem em bloco. Para aprender mais podem acessar a definição no site da Wikipedia.

Agora imaginemos que nossos blocos devem ser de 10 bytes mas ao particionar nossa mensagem o último bloco ficou de 4 bytes. Nesse caso temos que fazer alguma operação para completar esses 6 bytes restantes. Essa operação e chamada de padding e existem varias técnicas. Mas detalhes podem ser obtidos novamente na definição no site da Wikipedia.

Uma vez com nossa instância da classe Cipher nosso seguinte passo é inicializar ele indicando que vamos a realizar um processo de descriptografia utilizando tal chave privada. Finalmente realizamos o processo chamando o método doFinal do cipher passando como parámetro os bytes da mensagem criptograda. O método doFinal ira retornar os bytes da mensagem decifrada, os quais utilizaremos para criar uma string e devolver ela como retorno do método, o qual fica assim:

public String decrypt(PrivateKey key, byte[] message) throws Exception {
	Cipher decrypt = Cipher.getInstance("RSA/NONE/PKCS1Padding", "BC");
	decrypt.init(Cipher.DECRYPT_MODE, key);
	return new String(decrypt.doFinal(message));
}

Começarei agora a desenvolver a classe que atuara como servlet. A classe servlet ira ter duas funções. A primeira função e mandar o serviço criar um par de chaves, guardar a chave privada na sessão e mandar os dados necessários da chave pública para o cliente (modulus e exponente). A segunda função é receber um texto em formato hexadecimal, passar ele para uma seqüencia de bytes e chamar o método do serviço encarregado de decifrar a cadeia de bytes. Finalmente devolvera a mensagem decifrada para o usuário.

Como o código da servlet é Java de todos os dias, não tem muito para explicar. Segue o código dos dois métodos encarregados de realizar as operações:

private void decrypt(HttpServletRequest request,
		HttpServletResponse response) throws Exception {
	KeyPair keys = (KeyPair) request.getSession().getAttribute("keyPair");
	PrivateKey privateKey = keys.getPrivate();
	RSAService service = new RSAService();
	byte[] bytes = Hexadecimal.parseSeq(request.getParameter("Decrypt"));
	String decrypted = service.decrypt(privateKey, bytes);
	response.getWriter().write(decrypted);
}

private void getPublicKey(HttpServletRequest request,
		HttpServletResponse response) throws Exception {
	RSAService service = new RSAService();
	KeyPair keys = service.generateKeys();
	request.getSession().setAttribute("keyPair", keys);
	RSAPublicKey publicKey = (RSAPublicKey) keys.getPublic();
	String modulus = publicKey.getModulus().toString(16);
	String exponent = publicKey.getPublicExponent().toString(16);
	PrintWriter writer = response.getWriter();
	writer.append("{'modulus':'");
	writer.append(modulus);
	writer.append("','exponent':'");
	writer.append(exponent);
	writer.append("'}");
	writer.flush();
}

O código cliente é bem simples. Quando a página carregar, a página ira solicitar ao servidor o modulus e o exponente da chave pública. Quando o usuário acionar um botão escolhido, ira ser chamada a função sendMessage. A função sendMessage ira instanciar um objeto do tipo RSAKey que sera o encarregado de cifrar o texto escrito no devido textbox. Apos instanciar um objecto do tipo RSAKey, a função sendMessage especificara o modulus e o exponente da chave pública e logo cifrara a mensagem. Finalmente a função enviara ela pro servidor e mostrara uma alerta com a resposta. Nosso código em JavaScript fica assim:

$(document).ready(function() {
	$.getJSON("do?GetPublicKey", function(key) {
		$("#exponent").val(key.exponent);
		$("#modulus").val(key.modulus);
	})
});

function sendMessage() {
	var rsa = new RSAKey();
	rsa.setPublic($("#modulus").val(), $("#exponent").val());
	var message = rsa.encrypt($("#text").val());
	$("#encrypted").html(message);
	$.get("do?Decrypt=" + message, function(data) {
		window.alert(data);
	})
}

O código completo da aplicação, incluíndo o jQuery, a classe Hexadecimal pegada da Internet, a biblioteca jsbn, o Bouncy Castle e o web.xml pode ser descarregado de aqui.

Se tiver dito alguma bobagem, por favor me perdoem e me corrijam nos comentários ou por email.

Ate a próxima!

→ Sem comentáriosTags: Api · JavaScript · criptografia · java · livrarias · programação · seguridade

Aplicações web seguras com Apache2 e SSL

March 30th, 2008 · 2 comentários

SSL, conforme descrição na Wikipedia,

provê a privacidade e a integridade de dados entre duas aplicações que estejam se comunicando pela Internet. Isto ocorre através da autenticação das partes envolvidas e da criptografia dos dados transmitidos entre as partes. Esse protocolo ajuda a prevenir que intermediários entre as duas pontas da comunicação tenham acesso indevido ou falsifiquem os dados sendo transmitidos.

Em outras palavras, SSL evita que nossa sessão dentro de uma aplicação seja roubada por uma pessoa mal intencionada. Como ela poderia fazer isso? Simples, utilizando alguma ferramenta que capture os dados sendo transmitidos entre a aplicação cliente de Pablito e o servidor e utilizando eles para se fazer passar por Pablito.

Nesse artigo vamos configurar o servidor Apache Http para trabalhar com SSL utilizando o módulo mod_ssl. Estarei utilizando a versão 2.2.8 do servidor Apache Http.

O primeiro passo e ir no arquivo /conf/httpd.conf e nos assegurar de que existam as seguintes linhas:

LoadModule ssl_module modules/mod_ssl.so
Include conf/extra/httpd-ssl.conf

SSLRandomSeed startup builtin
SSLRandomSeed connect builtin

A primeira linha carregara o modulo encarregado de fazer o Apache trabalhar com SSL dando pra ele o nome de ssl_module. A segunda linha dirá ao apache que tem que ler o arquivo conf/extra/httpd-ssl.conf, onde teremos algumas configurações exclusivas do trabalho com SSL. A terceira linha é um comando condicional que ira executar os comandos dentro dele no caso que o módulo especificado tenha sido carregado. A quarta e quinta linha definem a fonte que ira oferecer o PRNG (Pseudo Random Number Generator) utilizado para a conexão SSL. Builtin é um método próprio do Apache para gerar o PRNG e nesse caso estamos dizendo que queremos utilizar ele no momento de levantar o servidor (startup) e no momento de ser criada uma conexão SSL (connect).

Sinceramente não entendo a fundo os últimos dois comandos, mas para mais informação podem visitar a documentação sobre SSLRandomSeed na mesma página do mod_ssl. Se alguem tiver uma explicação boa, seja bem vinda nos comentários. Se aprender mais, irei colocar o aprendido num post.

Talvez tenham se perguntado por que existem configurações relacionadas a SSL no arquivo httpd.conf se tínhamos combinado que todo o relacionado a SSL ia ser configurado num arquivo aparte. O arquivo do Apache vem assim por possivelmente algum motivo que eu desconheço e por isso eu deixei assim, mas se preferirem acho que não daria nenhum problema mover aquelas linhas para o nosso arquivo de configurações do SSL.

Atualmente estou trabalhando num ambiente Windows, pelo que vou ter que descarregar e instalar o OpenSSL, que se encarregara de criar as chaves e o certificado necessário para poder autenticar uma conexão. Em sistemas Linux me parece que o OpenSSL vem junto com o Apache. Chegando na minha maquina com meu querido Ubuntu farei um teste.

Os arquivos binários do OpenSSL para Windows podem ser baixados de aqui.

Uma vez instalado o Apache e o OpenSSL, vamos realizar nossas configurações.

O primeiro passo é configurar nosso host virtual no arquivo httpd-ssl.conf .

O segundo passo é criar nosso certificado. Para saber como criar o certificado podem ler parte do excelente artigo de Leonardo Calado também sobre SSL em Apache. Leonardo descreve como criar o certificado na seção Criar o certificado de teste.

Após isso somente falta testar nossa aplicação. Para isso basta inciar nosso servidor Apache e acessar https://domínio:porta
onde domínio e porta correspondem ao configurado no host virtual.

→ 2 comentáriosTags: Tutoriales · apache · seguridade · ssl

Decompilando Java com Eclipse e JAD

March 8th, 2008 · 2 comentários

Por motivos X que não devem acontecer, o código fonte de uma livraria Y foi perdido, ficando somente o Java Archive (JAR).

Ouvi que existe um método de recuperar um código fonte, utilizando decompiladores. Possivelmente não se consiga recuperar o código das classes em um 100%, mas muita coisa deve dar para recuperar, dependendo do caso.

Pesquisei um pouco e ao parecer o melhor decompilador e o mais popular é o Jad. Existem muitos outros mas parecem estar bem desatualizados e somente dão suporte ate a versão 1.3 do Java. Mesmo o Jad sendo o mais atualizado dos que encontrei, a noticia mais nova no site e do dia 2 de Julho de 2006.

Uma coisa que me fez pegar confiança no Jad é que existem um monte de ferramentas com interface gráfica que utilizam o Jad por detrás e também existe um plugin do Jad para o Eclipse chamado JadClipse, que é o que vou utilizar agora. A última versão é para o Eclipse Europa e foi lançada em Maio do 2007.

Baixei o plugin, coloquei ele na pasta plugins da minha instalação do Eclipse e abri o mesmo.

Ao abrir o Eclipse não apareceu nada diferente, mas sim nas preferências. No menu Java foi adicionado um submenu JadClipse, com muitas opções para configurar o plugin. Eu deixei as preferências no padrão. Em General > Editors > File Associations da para apreciar que existe uma asociação entre os arquivos .class e o JadClipse Class File Viewer.

Num dos projetos que estavam atualmente no Working Set tinha um que utilizava algumas livrarias do JBoss. Naveguei dentro de um arquivo .jar ate achar um arquivo .class e dei duplo click nele. Parece que nesse momento o Jad decompila o arquivo e deveria mostrar o resultado, mas ele mostrou para mim o seguinte:

DECOMPILATION REPORT

Decompiled from: /home/dcrec1/workspace/jboss-4.2.2.GA/server/default/lib/mail.jar
Total time: 2 ms
Jad reported messages/errors:
Exit status: 0
Caught exceptions:
java.io.IOException: java.io.IOException: jad: not found
at java.lang.UNIXProcess.(UNIXProcess.java:148)

Parece que por algum motivo o programa Jad não esta sendo encontrado. É obvio, não instalei ele!

Baixei a ultima versão do Jad e coloquei o arquivo jad dentro da pasta /usr/bin . Repeti o processo e o resultado foi o mesmo.

Voltei nas configurações do JadClipse e nelas existe um campo chamado Path to decompiler. Escrevi /usr/bin/jad como valor, apliquei as mudanças e repeti o processo de decompilação. A nova mensagem foi a seguinte:

DECOMPILATION REPORT

Decompiled from: /home/dcrec1/workspace/jboss-4.2.2.GA/server/default/lib/mail.jar
Total time: 25 ms
Jad reported messages/errors:
/usr/bin/jad: error while loading shared libraries: libstdc++-libc6.2-2.so.3: cannot open shared object file: No such file or directory
Exit status: 127

O erro se deu porque faltam livrarias no meu ambiente. Resolvi o problema no Ubuntu instalando o pacote libstdc++2.10-glibc2.2.

Repeti por terceira vez o processo e funcionou uma beleza! O código decompilado apareceu rapidamente e no final do código apareceu o seguinte texto como comentário:

DECOMPILATION REPORT

Decompiled from: /home/dcrec1/workspace/jboss-4.2.2.GA/server/default/lib/mail.jar
Total time: 45 ms
Jad reported messages/errors:
The class file version is 48.0 (only 45.3, 46.0 and 47.0 are supported)
Exit status: 0
Caught exceptions:

Ao parecer aconteceu algum erro mas não da para ser identificado a simples vista. Me parece que não daria para descobrir que o código gerado foi decompilado, os nomes das variáveis não apresentam caracteres estranhos nem as propriedades ou algum método.

Agora somente falta fazer testes para ver que tão parecido fica o código decompilado com o pre-compilado. Mesmo podendo não recuperar a classe em um 100%, acho que o JadClipse vai me ajudar bastante quando utilize ele na segunda-feira com a livraria mencionada no começo do post.

→ 2 comentáriosTags: Tutoriales · eclipse · java · programação

Nomeação “Diz que até não é … Um mau blog”

February 20th, 2008 · 5 comentários

Cid Andrade, do Tecnologia da Informação - Desenvolvimento e Educação, nomeou este blog como uma de suas referências de reconhecido mérito.

Agradeço profundamente a nomeação e espero poder tornar-me à altura da indicação.

Eu nomeio para nomeação como blogs de referência merecida os seguintes:

JEP - Java e Produtividade, de Felipe Coury
JulioGreff, de Julio Greff
ajaxBox, de Otávio Nogueira e Felipe Olivaes
B.O.R.G, da Bruna Griebeler
Blog de Baixo Acoplamento, de Luiz Ávila
El Micox, de El Micox
Grupo de Usuárias de de Programadores, de Cintia Viana, Aline Roque e Lady Clementine

Regras para nomeação:

1. Este premio deve ser atribuído aos blogs que considerem serem bons. Entende-se como bons os blogs que vocês costumam visitar regularmente e onde deixa comentários.
2. Só e somente se recebeu o “Diz que até não é um mau blog”, deve escrever um post:
1. Indicando a pessoa que lhe deu o premio com um link para o respectivo blog
2. A tag do premio
3. As regras
4. E a indicação de outros 7 blogs para receberem o premio.
3. Deve exibir orgulhosamente a tag do premio no seu blog, de preferência com um link para o post em que fala dele.
4. (Opcional) Se quiser fazer publicidade ao blogger que teve a idéia de inventar este prêmio, ou seja – Skynet - pode fazê-lo no post.

→ 5 comentáriosTags: comunidade

Profiling em Java com JProfiler

February 17th, 2008 · 2 comentários

Um profiler é uma ferramenta que informa sobre o comportamento de uma aplicação em tempo de execução.

Depois de pesquisar sobre diversos profilers para analisar uma aplicação Java, cheguei na conclusão que o JProfiler é o melhor. O único problema do JProfiler ate agora é que ele é pago.

Vamos instalar uma versão trial dele e ver o que podemos fazer com ele. Para descarregar o trial do JProfiler primeiro temos que acesar essa pagina e preencher o formulário. Um key para poder testar a ferramenta por dez dias será enviado. Seguidamente podemos entrar na área de downloads e baixar a versão desejada. A versão que eu estarei baixando é a 5.1.2, versão instalação executável.

A descarga finalizou e também chegou meu key, agora vou instalar. Vou ir no console na pasta onde descarreguei o arquivo e dar um ./jprofiler_linux_5_1_2.sh. Seguidamente é aberto um wizard onde aceitamos os termos do programa e indicamos onde queremos instala-lo.

Ao abrir o programa pela primeira vez é apresentado outro wizard, dessa vez uma wizard de configuração. Nesse wizard devemos inserir nossa key, escolher a VM que desejamos utilizar, indicar se queremos integrar o JProfiler com algum IDE e escolher nosso browser, é um processo bem simples.

Uma vez terminado o segundo wizard aparece um terceiro onde podemos indicar qual aplicação queremos que o profiler analise. Podemos também configurar para fazer que esse wizard apareça toda vez que abrirmos o programa ou não. Eu escolhi para aparecer toda vez porque é um wizard muito simples e faz que em um tempo muito pequeno tenhamos um profiler trabalhando com nossa aplicação escolhida.

Nessa oportunidade, vou utilizar o profiler com uma aplicação web minha que estou fazendo. A aplicação e muitos simples e possivelmente não vamos poder descobrir picos de garrafa, mas vamos poder obter uma idéia do que podemos fazer com o JProfiler. Justamente pelo que vou analizar uma aplicação web vou escolher no wizard a opção An application server, locally or remotely. Vou dar next e seguidamente vou escolher a versão do servidor de aplicação que vou utilizar, JBoss 4.x no meu caso. Next novamente, escolho que o servidor de aplicação esta nessa máquina e dou next novamente. Agora vou indicar qual é o arquivo que levanta o servidor. No meu caso ele se encontra na pasta /bin/ e se chama run.sh. Passos seguintes são escolher a máquina virtual a utilizar, a porta desejada para a conexão do profiler e decidir se queremos que nosso servidor de aplicação espere por uma conexão do profiler antes de inicializar ou não. Vou escolher a opção Wait for connection from the JProfiler GUI que quer dizer que quero que espere e avançar para o próximo passo. No seguinte passo é visualizado um resumo do que foi configurado e no ultimo temos a opção de escolher se queremos inicializar o servidor agora ou deixar isso para mais tarde. Vou escolher que quero inicializar agora escolhendo a opção Yes, start the application server for profiling.

Uma vez finalizado o wizard apareceu para mim uma janela indicando que minha versão e de evaluação. Tenho a opção de inserir uma key pagar. Vou fazer click em Evaluate para evaluar somente porque não comprei nada.

Antes de iniciar o servidor aparece uma janelha onde podemos fazer umas ultimas configurações. Também é indicado o nivel de CPU e memória que o JProfiler precisara de acordo com o configurado. Eu quero que tudo seja gravado então vou escolher as opções Record CPU data on startup e Record allocations on startup que vão a analizar quando cpu e quanta memória o servidor utiliza para inicializar.

Vou mudar a configuração do meus filtros porque não quero que todas as classes sejam analisadas, somente as classes do pacote com.mouseoverstudio . Na seção Filter settings vou fazer click em Edit. Por default, nos filtros ja vem configura um filtro para excluir do analise um monte de classes. Vou deixar as coisas mas simples apagando esse filtro e incluindo um novo do tipo inclusivo com o valor com.mouseoverstudio .

Seguidamente ok na janela e ok novamente na outra janela.

É aberto uma console com o debug do JBoss onde podemos ver que ele esta inicializando.

Durante a inicialização podemos ir no JProfiler na opção VM Telemetry Views e ver a memoria ram que esta sendo consumida em tempo real e ao longo de tempo de vida do nosso servidor:

Na parte inferior aparecem umas abas. Se fizermos click na aba Recorded Objects podemos visualizar a quantidade de objetos que residem na memória. Nas outras abas podemos analisar a quantidade de objetos criados e liberados da memória (Recorded Throughtput), a atividade do Garbage Collector (GC Activity), a quantidade de classes sendo analisadas pelo profiler (Classes), os Threads (Threads) e a carga do cpu (CPU Load).

Vou navegar um pouco na minha aplicação, vou selecionar uma funcionalidade pesada e durante sua execução vou me dirigir no JProfiler. Na opção Memory Views podemos ver o numero de instâncias existentes na memória, agrupadas por classes, pacotes ou componentes e quanta memória esse número de instâncias estão utilizando. Num primeiro momento é mostrada informação sobre todas as classes do sistema.

Como eu quero ver somente informação sobre minhas classes, vou me dirigir para View Filters e digitar com.mouseoverstudio . Ao dar enter são filtradas as classes que não pertencem ao pacote com.mouseoverstudio .

Essa funcionalidade é muito legal. Nessa semana estava analisando a aplicação de um cliente quando vi que ao acessar uma funcionalidade x, eram criadas muitas instâncias de um objeto o qual não deveria ter mais de uma por usuário. Depois de analisar o código com os desenvolvedores a gente percebeu que estava sendo criada a instância de um classe dentro de um loop, quando deveria ser fora de acordo com a lógica do negocio.

Eu sabia que estavam sendo criadas muitas instâncias de um classe, mas como saber onde eram criadas estas instâncias? Na seção CPU Views podemos visualizar uma árvore de chamadas sendo realizadas na VM. Dentro da informação se encontra o peso de aquela chamada em relação as outras, o tempo que demorou e o numero de invocações que teve. Podemos agrupar as chamadas novamente por métodos, classes, pacotes ou componentes, filtras informação de certo pacote ou de certa thread.

Na aba Hot Spots temos informação parecida, mas partindo de outras fontes, chamadas Hot Spots. Eu estou na dúvida sobre se sei corretamente o que é um Hot Spot e o que representa mas sei que a informação apresentada parte deles.

Se fizermos click direito numa classe dentro da árvore e selecionarmos Show Call Graph vamos poder visualizar a informação desejada mas de um modo gráfico, podendo escolher um layout hierárquico, ortogonal ou orgânico. Nesse gráfico é apresentada a mesma informação e podemos ir navegando por ele e abrindo conexões, podendo apreciar como as classes estão se relacionando entre sim.


Foi assim que no caso do cliente eu escolhi uma classe de partida que eu sabia que a requisição tinha passado por ali e fui navegando ate achar a classe que criava aquela quantidade enorme de instâncias.

JProfiler tem muita outra informação a oferecer, mas como eu sou ainda novato com a ferramenta, não entendo toda ela corretamente e poderia confundir as pessoas se tratasse de explica-las. Porém, com o que eu tenho aprendido e tentado explicar nesse post ja da para fazer muito análise de uma aplicação e tirar uso da ferramenta. Justamente com aquele uso e que se vão aprendendo novas coisas e conforme eu for aprendendo vou ir postando aqui.

Qualquer informação a mais por favor deixar-las nos comentários.

→ 2 comentáriosTags: Tutoriales · java · otimização · performance

Protegendo nossos data sources no JBoss com senhas criptografadas

February 14th, 2008 · 2 comentários

Normalmente quando trabalhamos com aplicações que acessam o bancos de dados temos um arquivo xml com a configuração do nosso data source (usuário, senha, ip do banco, nome do schema, …), algo assim:

<datasources>

  <local-tx-datasource>

    <jndi-name>UnknowDS</jndi-name>

    <connection-url>

        jdbc:mysql://localhost:3306/unknow

    </connection-url>

    <driver-class>com.mysql.jdbc.Driver</driver-class>

    <user-name>unknow</user-name>

    <password>desconhecido</password>

    <exception-sorter-class-name>

        org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter

    </exception-sorter-class-name>

    <metadata>

       <type-mapping>mySQL</type-mapping>

    </metadata>

  </local-tx-datasource>

</datasources>

O problema com data sources como o do exemplo é que a senha da base se encontra explicitamente no arquivo xml. Se por algum motivo alguma pessoa não desejada ler o arquivo, ela vai descobrir a senha da base sem o mínimo esforço. Felizmente, o JBoss possui uma classe chamada SecureIdentityLoginModule que consegue criptografar uma senha e posteriormente ao reconhecer que a senha no data source é criptograda, descriptografar ela automaticamente para fazer o login na base, tudo isso de maneira muitos simples.

O primeiro passo é criptografar a senha. Para isso vamos ir no console na pasta home do JBoss e rodar o seguinte comando (substituindo *senha* pela senha desejada) :

java -cp lib/jboss-common.jar:server/default/lib/jbosssx.jar:server/default/lib/jboss-jca.jar org.jboss.resource.security.SecureIdentityLoginModule *senha*

O console respondera com uma mensagem similar a essa:

Encoded password: 3edbf2d83a1d270c795cf4eabe7274d2

O segundo passo é abrir o arquivo login-config.xml situado na pasta conf do server em uso e adicionar o seguinte dentro do nodo policy, colando a senha criptografada na tag module-option com parametro name igual a password:

<application-policy name="MySecurityDomain">

    <authentication>

        <login-module flag="required"

code="org.jboss.resource.security.SecureIdentityLoginModule" >

            <module-option name="username">

                unknow

            </module-option>

            <module-option name="password">

5dfc52b51bd35553df8592078de921bc

    </module-option>

            <module-option name="managedConnectionFactoryName">

jboss.jca:name=UnknowDS,service=LocalTxCM

    </module-option>

        </login-module>

    </authentication>

</application-policy>

O último passo é ir na configuração do nosso data source e substituir

<user-name>unknow</user-name>

<password>desconhecido</password>

por

<security-domain>MySecurityDomain</security-domain>

Agora temos uma senha criptografada e mais segura.

Somente umas coisas para lembrar no caso que aconteça algum erro: o valor da tag security-domain no data source tem que ser igual ao valor do parametro name na tag aplication-policy no arquivo login-config.xml. Na tag module-option com name igual a managedConnectionFactoryName, o valor name do jboss.jca deve ser igual ao nome do nosso data source e o service compativel com o tipo do mesmo. Em outras palavras, se nosso data source for xa, o service devera ser XATxCM . No nosso caso o data source e local então o service fica como LocalTxCM .

Para mais informação, pode acessar a página no wiki do JBoss.

→ 2 comentáriosTags: criptografia · jboss · seguridade

Aprendendo a desenvolver com JRuby (Parte 1: Configurando o ambiente)

February 4th, 2008 · 4 comentários

Vou começar a mexer com JRuby nesse momento.

Depois de pesquisar sobre o melhor IDE para trabalhar com JRuby cheguei a conclusão que o melhor é o NetBeans 6. O NetBeans é da Sun e os desenvolvedores do JRuby trabalham para a Sun então tem lógica. Para saber mais sobre NetBeans e Ruby/JRuby ingressar aqui.

Baixando NetBeans 6.0 Installer for Linux/English (en) netbeans-6.0-linux.sh (168.6 MB) MD5: 6b072e5e4baba945f48b7837cb944d93 …

O NetBeans baixou, fui no console e rodei ./netbeans-6.0-linux.sh , logo next next next. Foi criado um atalho no meu escritório, dois clicks e o NetBeans esta aberto.

Dentro do NetBeans, File > New Project . Na janela aberta escolhi Ruby como categoria e Rails Project como projeto.


Fiz click em Next. Apareceu uma janela perguntando sobre qual interpretador queria utilizar. Escolhi JRuby e depois de dar ok escolhi um nome de projeto, a base de dados com a qual ia trabalhar e novamente click em next. A janela mostrou que tinha a versão 1.2.5 do Rails. Fiz click no botão Update Rails para atualizar o Rails.

Atualizando Rails …

Opa! deu um erro: Exception in thread “main” java.lang.OutOfMemoryError: Java heap space . Vou dar click em close e tentar de novo.

Atualizando Rails …

A segunda tentativa deu erro também. Vou instalar na mão. No console mandei gem install rails –include-dependencies e vixi: The program ‘gem’ is currently not installed. You can install it by typing: sudo apt-get install rubygems . Esta bom então, mandei sudo apt-get install rubygems e seguidamente gem install rails –include-dependencies novamente.

Bulk updating Gem source index for: http://gems.rubyforge.org

Ahhh como assim, apareceu o erro ERROR: While executing gem … (Gem::GemNotFoundException) Could not find rails (> 0) in any repository . Google agora!

Abdul Qabiz falou que se rodar sudo gem update meu problema estaria resolvido, então vamos la. sudo gem update, seguido de gem install rails –include-dependencies novamente (terceira vez) e esperando.

Taráaaa! Agora sim:

Successfully installed rails-2.0.2
Successfully installed activeresource-2.0.2
Installing ri documentation for activeresource-2.0.2…
Installing RDoc documentation for activeresource-2.0.2…

Vou fechar o NetBeans, entrar de novo e repetir o processo. Antes disso, vou tunar um pouco o NetBeans mexendo no arquivo /etc/netbeans.conf, seguindo a lógica descrita nesse post.

Abri o NetBeans, fiz o processo novamente e continuava aparecendo uma versão antiga do Rails. Ao tentar atualizar acontecia o mesmo erro relacionado a memória. Depois de mexer por aqui e por la e pesquisar um monte descobri que o erro se dava por causa de um bug do NetBeans. A resolução do ticket estava como fixed então fui no trunk do NetBeans e puxei a ultima versão, lançada hoje. Instalei, executei, repeti o processo e dessa vez tudo saiu bem, a versão de Rails registrada era a 2.0.2 . Dei click em finish e projeto criado. :D

Fiz um click direito no nome do meu projeto e selecionei Run para ver se tudo estava funcionando perfeitamente. Foi aberta uma aba no output do NetBeans para o servidor WEBrick (que é o que vem por default) e apareceu o seguinte erro: rubygems.rb:379:in `report_activate_error’: Could not find RubyGem ActiveRecord-JDBC (>= 0) (Gem::LoadError).

Não tenho muito interesse agora em tentar concertar o erro porque não quero utilizar WEBrick, quero utilizar Mongrel porque em tudo lugar vejo falar que é muito bom e uma das melhores coisas que o Ruby tem.

Acessei Tools > Ruby Gems e percebi que existiam gems instalados desatualizados, assim que antes de fazer outro movimento, atualizei. Agora vou tentar instalar o Mongrel. Me dirigi na aba New Gems e procurei mongrel na lista gigante que apareceu. Seguidamente selecionei ele e click em Install. Escolhi para incluir as dependências e click em Ok.

INFO: `gem install -y` is now default and will be removed
INFO: use –ignore-dependencies to install only the gems you list
Successfully installed gem_plugin-0.2.3
Successfully installed mongrel-1.1.3-java
2 gems installed

Mongrel instalado, click em Close.

Acho que o Mongrel não esta instalado ou não corretamente. Fiz o processo de criar um novo projeto para ver se aparecia Mongrel na combo de servidores e não aparecia. Tentei rodar mongrel_rails no console para ver o que dava e o que deu foi um command not found. :) Vou instalar o Mongrel na mão mandando executar sudo gem install mongrel. Para variar um pouco, apareceu o seguinte erro:

Building native extensions. This could take a while…
ERROR: Error installing mongrel:
ERROR: Failed to build gem native extension.

/usr/bin/ruby1.8 extconf.rb install mongrel
extconf.rb:1:in `require’: no such file to load — mkmf (LoadError)
from extconf.rb:1

Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/fastthread-1.0.1 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/fastthread-1.0.1/ext/fastthread/gem_make.out

Felizmente consegui achar a solução rapidamente aqui. Segui o processo especificado no post e depois o console ja estava reconhecendo o comando mongrel_rails. Mongrel instalado agora sim!

Reiniciando NetBeans …

Fiz o procedimento de criar um novo projeto e Mongrel apareceu nas opções de servidor.


Isso é bom, esta instalado corretamente e o NetBeans reconheceu ele. O problema é que não sei como fazer para que meu projeto rode no Mongrel e não mais no WEBrick. Fiz um click direito no nome do meu projeto e vi que tinha uma opção chamada Find, acessei ela e procurei por webrick, esperando que exista um arquivo de configuração onde e definido o servidor. Efetivamente parece que existe este arquivo, chamado private.properties, que tem uma propriedade chamada rails.servertype. Vou mudar o valor de WEBRICK para MONGREL, rodar o projeto e ver que acontece.


A boa noticia é que o projeto iniciou sobre o Mongrel. A ma noticia é que deu o erro Could not find RubyGem ActiveRecord-JDBC. Imagino que não tenho o gem ActiveRecord-JDBC na minha maquina então vou fazer um sudo gem install ActiveRecord-JDBC e ver que rola.

Instalou corretamente :D, versão 0.5. Vou tenta rodar novamente minha aplicação. Não deu certo. Acessei Tools > Ruby Gems e vi que ActiveRecord-JDBC não estava na aba Installed. Fui na aba New Gems, procurei ele e dei click em Install. Ou output da janela de instalação foi o mesmo do output do console, quando tentei instalar por ali. A diferença e que agora sim ActiveRecord-JDBC apareceu na aba Installed. Vou tentar rodar minha aplicação de novo.

Agora sim deu certo! A janela do output não apresentou nenhum erro e ao acessar http://0.0.0.0:3000/ foi apresentada uma pagina com o título:

Welcome aboard
You’re riding Ruby on Rails!


A página diz que ainda tenho que fazer algumas coisas, mas ficara pro próximo post. O preview do WordPress não esta funcionando e não sei se o texto esta muito longo ou não.

De qualquer jeito, ate a próxima parte!

→ 4 comentáriosTags: Tutoriales · java · jruby · mongrel · netbeans · rails · ruby