6 meses depois…

December 20th, 2007 by Daniel

… e voltei a blogar. Finalmente consegui arrumar 15 minutos de bobeira para escrever alguma coisa aqui no blog. Neste tempo em que fiquei sem blogar eu mudei completamente de idéia em relação a REST e já implementei integrações usando REST em dois projetos (1 pet project e outro profissionalmente, que pretendo discorrer a respeito em breve), assumi novas responsabilidades no meu antigo projeto mas decidi que estava na hora de mudar de ares e me mudei de mala e cuia de Araraquara para São Paulo, onde agora eu trabalho em uma certa empresa do setor financeiro em um projeto com alguns desafios interessantes. Também comecei a estudar outras tecnologias (devido a fortes influências de amigos) como Mono e ErlyWeb, além de estudar mais a fundo coisas como BDD (que eu tentei implantar no último projeto em que eu estive envolvido na EDS, mas sem muito sucesso) e DSLs, depois do Shoes ficar martelando tanto a respeito deste tema. Agora que as coisas estão se tornando mais calmas (calmaria em São Paulo?!), vou tentar blogar com mais freqüência (o que não significa necessariamente que escreverei mais ainda este ano). De qualquer forma, feliz natal para você :)

Popularity: 41% [?]

IDLs para REST

June 10th, 2007 by Daniel

Como posts em forma de diálogos estão se tornando moda (1 e 2) e como eu não tenho tido muito tempo para escrever decentemente sobre coisas que eu gosto, então vou aproveitar mais um diálogo, desta vez com meu amigo cabeção, para falar sobre “IDLs para REST”, tema, aliás, que está fervendo por aqui, aqui, aqui, aqui e, claro, no GUJ.

Diego: cara, to com um monte de post pra fazer e não termino nenhum… to com uns trocentos drafts :(
Daniel: ahhh não se esqueça daquele que eu propus na semana passada para vc…
Diego: hum, qual mesmo?
Daniel: soluções caseiras são uma m&r*@… vc até gravou no celular um lembrete no seu celular…
Diego: ahhh ta aqui sim… hj tirei o dia pra organizar o pc… tinha mta coisa pendente… quero ver se faço isso hj :)
Daniel: eu ultimamente tbm não tenho tido mto tempo para escrever… to com vontade de escrever sobre muita coisa, mas não tem dado tempo… por exemplo, uma coisa que eu queria fazer era discutir sobre WADL, IDLs para REST e tal
Daniel: aliás, “IDL para REST” é a coisa mais paradoxal que existe…
Diego: IDL? o que é isso?
Daniel: interface description language… por exemplo, WSDL é uma IDL para WS-*
Diego: saquei
Daniel: acho que a gente acaba falando de “IDL para REST” por falta de um termo melhor… mas, convenhamos, não faz o menor sentido falar sobre interfaces para recursos, quando as únicas iterações que você pode ter com eles são pré-definidos pelo protocolo HTTP
Diego: ** diego se encolhe por não ter lido nada decente ainda sobre rest
Daniel: hahahah eu também não li muita coisa a respeito… li a tese do roy fielding por cima e não achei nada revolucionário…
Daniel: contudo… acho que é preciso algum mecanismo que permita que terceiros identifiquem e mapeiem todos os recursos que vc oferece, bem como quais são as possíveis representações que você pode manipular de cada recurso..
Diego: sim, tu tem que oferecer o cardápio, por mais que o cliente já conheça… como no mcdonalds: todo mundo sabe que o bigmac é o numero 1, mas tem que ter lá escrito
Daniel: touché… bom ponto este… além disso, você que tem falar do que é feito o big mac… não adianta nada um vegan chegar em uma loja do Mc e pedir um #1 achando que vai ganhar um belo hamburguer de soja
Diego: e tambem oferecer aquele monte de informações que são obrigatórias, mas que ninguém da bola, como valor calórico, etc
Daniel: exato… por isso q é importante falar sobre as possíveis representações que você pode manipular para cada recurso… não adianta nada eu querer manipular um recurso como JPEG, se as representações possíveis são XML, JSON e text/plain…
Diego: por mais óbvio que seja o “big mac engorda pra caramba”, tu tem que dizer que o negócio tem 540 kcal
Daniel: cara… isso vai virar mais um post em forma de diálogo..

Popularity: 83% [?]

Sobre DAOs e Repositories

June 5th, 2007 by Daniel

Diálogos sempre foram uma forma muito interessante de se ensinar alguma coisa. Platão sabia disso quando escreveu seus Diálogos para ensinar, entre outras coisas, ética. Bom, aproveitando a sabedoria grega e baseada em uma conversa real com um colega, eis um pequeno diálogo para tentar esclarecer dúvidas sobre DAOs e Repositories, tópico quente do dia no GUJ.

Gafanhoto: Olá, você viu a questão do DAO X Repository?
Mestre: Não. Onde?
Gafanhoto: No guj, sobre expor ou não a interface do DAO no obj de negocio?
Mestre: Ainda não vi.. ja vejo…
Gafanhoto: No fórum de arquitetura: http://guj.com.br/posts/list/60916.java
Mestre: hmmmm… e aí?
Gafanhoto: Ainda não saquei :(
Mestre: Exatamente o quê?
Gafanhoto: Se eu fizer uma interface UserRepositorio, com metodo save, delete, etc e fizer o meu HibernateUserDAO implementar ela, ok sem problemas. Mas se tiver meu UserDAO com save, delete, etc e o HiberanteUserDAO implementar ela não é certo.
Mestre: Não é simples assim, Gafanhoto.
Mestre: Primeiro, você precisa pensar conceitualmente. Se você tem uma clínica veterinária, você obtém as informações sobre um certo cachorro no arquivo da veterinária, que é um repositório de fichas sobre cães.
Contudo, computacionalmente, nós temos que mapear dados de um formato para outro o tempo todo: de objeto para relacional, de relacional para hierárquico, de hierárquico para objeto, tudo por causa de impedância. Então, para isso que um DAO funciona para isso: para mapear os dados de um formato para outro, que é o tal do DataMapper que o Phillip citou.
Mestre: Concorda que se você tivesse todos os seus objetos em memória, você não precisaria de um DAO? Aliás, vamos supor uma coisa bem herege: você está usando Prevayler. O seu repositório usaria o Prevayler para obter um determinado conjunto de objetos que você fosse precisar, mas, neste caso, porque você iria precisar de um DAO? Você não precisa mapear entre formatos para obter os objetos que você precisa, pois eles já estão lá.
Gafanhoto: Na prática, um DAO serve como um repository, mas nem todo repository eh um DAO?
Mestre: Na verdade, um repositório usa um DAO para mapear dados de/para um formato que o sistema em si não conhece.
Gafanhoto: Hmmmm, legal! Eu entendi o ponto de vista de vocês.

Popularity: 86% [?]

WADL (REST++, WS-* –)

May 25th, 2007 by Daniel

Há algumas semanas atrás, eu publiquei o seguinte:

Além disso, acho que WS-* tem um ponto em que é claramente superior ao REST (a) e um outro ponto em que WS-* leva uma vantagem sobre REST por causa de uma “deficiência” deste (b).

O ponto em que WS-* é claramente superior ao REST (a) é exatamente o fato de existir WSDL para descrever as interfaces dos serviços. Nem vou discutir a complexidade do WSDL em si (porque não deve existir alguém neste planeta que deva achar que WSDL simples e/ou fácil de se escrever), mas WSDL cumpre um papel muito importante neste contexto de servir outros sistemas, uma vez que existe uma maneira padrão para se descrever para outras máquinas todos os serviços que estão sendo oferecidos. Claro, isso pode ser feito para REST (talvez usando algum tipo de syndication? Não pensei muito no assunto), mas por enquanto não há nada neste sentido, pelo menos nada muito difundido ou aceito como padrão até onde eu sei. O segundo ponto (b) onde eu acho que o WS-* leva vantagem sobre REST é o fato deste último ser totalmente HTTP-oriented. Apesar de estarmos de 2007, nem todos podem/devem/querem conversar usando HTTP e a possibilidade de você usar WS-* sobre, por exemplo, JMS ou qualquer outro protocolo de transporte abre oportunidades (por exemplo, oferecer uma fila do seu estimado WebSphereMQ, responsável pelo sistema de aprovação de crédito, para dois tipos de clientes não-Java sobre os quais você não tem o menor domínio - baseado em fatos reais) que não existem com REST.

(mais em Agora é REST vs. WS-*).

Mas, agora conforme WADL vai ganhando mais atenção e se tornando o “padrão” para a descrição dos recursos oferecidos por uma aplicação Web, tudo aquilo que eu citei como sendo “um ponto em que WS-* é claramente superior ao REST” perde completamente o sentido e me faz considerar bem mais seriamente usar REST a SOAP/WSDL para expôr serviços. Mas o fato de REST ser tão acoplado com HTTP me incomoda um pouco ainda, mas isso é assunto para um post futuro (mesmo porque eu preciso trabalhar agora :) )

Popularity: 90% [?]

Classloading e o porquê você deveria ao menos saber como isso funciona.

May 9th, 2007 by Daniel

Outro dia um colega estava fritando a cabeça com um problema que, segundo ele, não deveria estar acontecendo. “Cara, eu juro que o deploy foi feito corretamente. Corto meu braço fora se eu não tiver feito o deploy do EAR corretamente!”. Ok, acredito nele, mesmo porque ele mandou o log do appserver dele e nada de errado, aparentemente. Contudo, vendo o log da sua aplicação, pude perceber que havia uma série de linkage errors (aka java.lang.NoClassDefFoundError) quando ele tentava acessar alguns EJBs que não residiam na mesma. Certo, a vida ensina e os erros mais ainda, principalmente quando você tem um stacktrace :) . Então resolvi quebrar o galho deste meu colega e ensiná-lo algo com a qual ele nunca precisou se preocupar tanto, que é como Java faz para carregar classes.

Ele nunca provavelmente precisou (até então) se preocupar com carregamento de classes e você pode estar se perguntando porque você também deveria se preocupar com isso sendo que você tem meu email ou o GUJ e pode pedir ajuda quando precisar :) . A melhor (e mais educada) resposta para isso é que certamente, em algum momento do seu dia como desenvolvedor de aplicações Java EE, você precisa lidar com diversos class loaders, de uma maneira ou de outra. Todas as vezes que você faz uma página JSP ou escreve uma “linda” action para o Struts e faz o deploy dos mesmos no seu servidor de aplicações, este código é carregado por um class loader especial que previne que outras webapps tenham acesso a estes componentes, mesmo que elas residam dentro de uma mesma JVM. A pior (e mais mal-educada) resposta para isso é que meu email não serve para suporte técnico (pague por isso), mas para que pessoas me convidem para tomar um choppinho em algum boteco de vez em quando. Além disso, aprender nunca é demais e você já deveria estar sabendo disso (que aprender nunca é demais) :)

Antes de tudo, vamos estabelecer a diferença entre tipo e classe. Tipo (ou também Class Type se você preferir) é o nome completo de uma classe, i.e., o nome da classe junto com o nome do pacote que o contém. Por exemplo, com.acme.Foo representa um tipo. Contudo, com.acme.Foo não é exatamente uma classe do ponto de vista que queremos analisar, pois uma classe no nosso contexto é formado por um class type junto com o class loader que foi responsável por carregar e definir este tipo. Em outras palavras, uma classe é uma instância válida do tipo java.lang.Class, e esta faz referência a um class type e ao class loader que o carregou efetivamente. Muito bem, estabelecido este conceito básico, vamos às regras do jogo.

A primeira regra que você precisa saber sobre carregamento de classes em Java é que os class loaders são organizados de maneira hierárquica, conforme a figura abaixo:

Todas as vezes que você inicia uma JVM, um class loader é instanciado e responsável por carregar todas as classes do JRE e extensões. Este é o famoso o Bootstrap Class Loader e é a raiz da sua hierarquia de class loaders. Em seguida, um segundo class loader, o System Class Loader, é responsável por carregar todas as classes listadas na variável de ambiente CLASSPATH ou passadas como argumentos na inicialização da JVM através do parâmetro –classpath. por sua vez. A partir deste ponto, você pode organizar outros class loaders da maneira que você quiser, mas sempre tendo em mente que seus class loaders residem dentro da hierarquia desenhada acima, onde alguém é sempre pai de alguém (implicitamente, todo mundo é filho de SystemCL). Além disso, é preciso lembrar-se também de outra regra muito importante e que rege o comportamento geral da maioria dos class loaders, que é como funciona o processo de carregamento de classes em si. E por carregar uma classe entende-se o processo de ler, byte por byte, o bytecode de uma classe, criar uma instância de java.lang.Class que defina aquela classe e mantê-la em cache dentro do class loader.

Você sabia que o class loader que inicia o carregamento de uma classe não é necessariamente aquele que carrega/define a classe de fato? Isso ocorre pois a regra geral (que você pode ler no Javadoc da java.lang.ClassLoader) de relacionamento entre class loaders é a seguinte: a menos que você precise muito, você deve delegar o carregamento de uma classe para um class loader que resida em um nível hierárquico acima do seu class loader. Isso significa que, quando o seu class loader quiser carregar uma classe, ele deve delegar este processo para seu class loader pai primeiro e apenas se este não conseguir encontrar a classe desejada, então assumir a responsabilidade de tentar carregar o recurso desejado. Esta é a segunda regra do jogo mas pode haver exceções. A exceção é exatamente quando você precisa muito que seu class loader seja o responsável por carregar e definir uma classe qualquer. Isso acontece sempre que você precisa reduzir o escopo de uma determinada classe dentro da sua JVM e o melhor exemplo disso são os servlet containers como o Tomcat, que nunca delegam a definição de uma classe que pertença a uma webapp para o seu class loader pai.

Esta exceção implementada nos servlet containers (e nos EJB containers também) é conseqüência da terceira regra do jogo: um class loader pode ter apenas uma única representação de um tipo carregada. Isso significa, por exemplo, que você só pode ter um único class type com.acme.Foo dentro de um mesmo class loader. Logo, se sua JVM não possuir múltiplos custom class loaders, sinto muito, apenas uma representação de com.acme.Foo poderá residir na sua JVM, já que esta já deve ter sido carregada pelo SystemCL. Vale lembrar também que, dada a segunda regra do jogo, a menos que você precise muito, você deve delegar o carregamento e a definição de uma classe para um class loader pai, o que, se levado a sério por todo mundo, nos leva a ter apenas uma única representação do class type com.acme.Foo na nossa JVM, o que, por conseqüência, tornaria os servlet containers impossíveis de existirem. Por isso que você só vai violar a regra 2 quando você precisar muito.

E sabendo destas 3 regras do jogo e sabendo como os EJB containers funcionam e porquê funcionam do jeito que funcionam, meu colega descobriu que ele não poderia acessar um EJB de uma outra aplicação usando uma Local interface e que ele precisaria descobrir como obter uma Home interface (J2EE 1.3 não tem LocalHome interfaces :( ) para fazer o trabalho sujo dele. E antes que você me diga que eu simplesmente deveria ter simplesmente dito a ele que “para obter referência a EJBs que não residem em sua aplicação ele deveria usar uma Home Interface” e encurtado a história, eu respondo: o que resolveria dar a solução sem ele entendê-la? ;)

Update: O Rodrigo postou uma ótima continuação sobre class loaders em seu blog. (E os malditos trackbacks do meu blog pararam de funcionar :P )

Popularity: 91% [?]

Coisas que algumas empresas deveriam saber

May 6th, 2007 by Daniel

Mangar me indicou isso. Pena que nem todas empresas sabem disso.

Popularity: 100% [?]

Imes.java

May 5th, 2007 by Daniel

Dia 2 de junho, em São Caetano. Ótima oportunidade de falar sobre tecnologia e rever os amigos. Eu vou :)

Popularity: 86% [?]

A História é cíclica

May 3rd, 2007 by Daniel

Pelo menos é o que diz o Hinduísmo. E lendo este tópico no GUJ, nota-se que realmente isso faz sentido.

(Há 30 anos atrás…)
- Uia, tem um lance chamado linguagens orientadas a objeto, dizem que vai revolucionar…
- Naaahhhh pra que organizar um sistema em forma de objetos? Que complicação! Coisa de EMO isso. Além disso, porque eu vou querer fazer um programa que é mais lento e ocupa mais memória se eu faço a mesma coisa usando ASM com pouco mais de 200 linhas de código?

(10 anos atrás…)
- Uia, agora estão falando de botar os sistemas OO para serem executados em ambiente gerenciado, em cima de um treco que chamam de Virtual Machine. Parece que traz um monte de coisas legais, tipo portabilidade, sistema comum de objetos…
- Este papo de emo de novo? Ok, sistemas OO podem até ser legais, interessante aquele lance lá de polimorfismo que eu li no livro do “Aprenda OO em 21 dias“. Mas, porra, ambiente gerenciado é pra este bando de newbahs que não sabem desalocar gerenciar memória decentemente. Sem falar que Virtual Machine vai deixar meu programa sempre mais lento. Vai por mim, eu sei do que to falando. Além disso, vc viu aquele lance de Java? Cara, onde já se viu um mero Hello World ocupar 8mb de RAM? Ahhh não, pára!!!

(5 anos atrás…)
- Cara, vc ta ocupado?
- Hmmm, só me divertindo aqui com este tal de Java 2 EE. Vi uma palestra de um tal de Homem do Java, parece que isso vai bombar!
- Hmmm, é… eu já uso… mas, meu… vc já viu estas linguagens de tipagem dinâmica? São bem legais. Tava dando uma olhadinha em Ruby/Python/… Poxa, é OO, tem uma VM e runtine único e outras coisas bem interessantes, como closures e mixins…
- Ihhh Já falei para você parar de ouvir My Chemical Romance, não? Porra, pra que isso tudo? O lance agora é J2EE, mano! Cara, grandes empresas por trás: IBM, Sun, Oracle. Oracle, mano! Você acha que estes caras vão investir em algo que não tem futuro?
- Não não, eu não disse que J2EE não tem futuro, mas é que…
- É que você é um emo! Sem falar q este lance de mixins é coisa de quem gosta de ficar brincando de mixin com o coleguinha de escola. Por favor…

E por aí vai, nos levando até a discussões sobre o futuro das linguagens funcionais hoje. O que será que vamos discutir no ano que vem? ;)

Popularity: 79% [?]

Netbeans, parte 2b

April 26th, 2007 by Daniel

Só um pequeno detalhe e relato de outra experiência ruim com o Netbeans (prometo que tento parar por aqui). Esta semana eu instalei o Ubuntu 7.04, depois de todo mundo falando que ele está legal, rápido, fácil de usar (mais ainda?), bonito e super integradinho com Java. Realmente, esta versão está tudo isso mesmo. Contudo, olha que coisa mais chata: o conteúdo da janela do Netbeans não é renderizado. Pensei que poderia ser algum problema de renderização do Swing, troquei as versões de JVM (de 6.0 para 5.0, e de volta para a 6.0), mas eis que resolvo testar o JDiskReport e percebo que este é corretamente renderizado, independente da versão da JVM. Noto também que qualquer outra aplicativo Swing, como o JConsole, é corretamente desenhado, exceto o NetBeans. Estranho, não?

UPDATE: Problema resolvido! Ontem a noite, fuçando no Google, descobri no Bug Database da Sun que já existia um issue relatando o mesmo problema, que foi resolvido no Update 1 do JDK 6.0. Feito o update da JVM e tudo voltou à normalidade. Agradeço também aos leitores que comentaram no blog com sugestões de como resolver o problema :)

Popularity: 93% [?]

Netbeans, parte 2

April 25th, 2007 by Daniel

Na segunda parte da minha avaliação do NetBeans, eu resolvi avaliar seu editor de código, uma vez que a maior parte do tempo eu passo escrevendo código Java. Para tanto, eu resolvi implementar uma pequena aplicação que faz conversão entre colour spaces, mais exatamente entre RGB e HSV. Ou seja, nada de editor gráfico, nada de wizards, apenas código puro. E, minha nossa, trabalhar com o NetBeans neste contexto me fez lembrar quando eu estava começando com Java há uns 9 anos atrás, usando emacs ou Notepad. O editor de código do Netbeans 5.5 é ruim. Quer um exemplo?

  1. crie uma lista: List a = new ArrayList();
  2. preencha-o da maneira como você quiser: a.add(”oi”); a.add(”tchau”); …

Agora, vamos supor que eu queira pegar o primeiro item da minha lista. Se eu estivesse usando Eclipse, eu simplesmente digitaria “a”+”.”+”g” (esperaria pelo autocomplete que é rapidamente apresentado e escolheria o método “get”)+”0″+”;”. Daí, eu simplesmente usaria a combinação ALT+SHIFT+L (Refactor > Extract Local Variable) e, pronto!, o retorno da chamada a.get(0) seria atribuída a uma nova referência. Simples assim. Além disso, se eu quiser implementações prontas (e corretas) para os métodos hashCode e equals, é simplesmente Source > Generate hashCode() e equals(). Entre várias outras facilidades. MAS O EDITOR DE CÓDIGO DO NETBEANS NÃO FAZ ISSO!!! Como pode? Bem, pelo menos, o editor de código do NetBeans organiza meus imports corretamente e consegue fazer alguns refactorings mais simples como “extract method”, “extract interface”, “pull up” e “push down”. Além disso, o auto-complete para código é lento no começo, embora se torne melhor conforme você vai usando a ferramenta.

Outra coisa que eu senti muita falta no Netbeans é o esquema de compilação incremental do Eclipse. Eu gosto muito de fuçar e testar as classes enquanto eu as codifico. Isso significa que eu mudo muito a interface de classes enquanto eu as desenvolvo, para buscar a melhor solução para as minhas necessidades. E isso também significa que eu posso quebrar muito código que eu gero. Contudo, o Eclipse permite que eu teste estas classes, mesmo tendo quebrado meu projeto. Já no Netbeans… Enfim, se eu mudar a interface de um método e quebrar outras classes que usem este método, eu vou ter que consertar classe por classe antes de testar minha alteração. Se, por algum motivo, eu não gostar do que eu fiz ou simplesmente não funcionar, eu vou ter q voltar todo meu código ao estado anterior (um monte de CTRL+Z em todas as classes em que eu mexi). E ISSO É MUITO IMPRODUTIVO!.
Em resumo: nesta segunda avaliação, o NB deixou muito a desejar. Muito mesmo. Dizem que a próxima versão pretende melhorar isso tudo, mas até lá, vamos de NB 5.5 mesmo.

Popularity: 86% [?]