Tecnologia a serviço do homem…

Poliglotismo

Desde sempre trabalho com Java, e de empresa em empresa, de projeto em projeto, sempre estive mexendo com uma sopinha de letras diferente, me empenhando em conhecer detalhes de Web frameworks like Action, Hibernate’s e Spring’s da vida… Legal, mas chega uma hora que você pensa “quero fazer algo do zero”, sozinho, sem ninguém (forever alone :P ) , e ai você descobre o quanto será árdua sua missão. E não falo apenas na plataforma Java! .NET, PHP também tem sua robustez e que, muitas vezes, te faz pensar em várias coisas menos no que você talvez deveria, em sua idéia

Seus fontes virão códigos heróicos e você,  programador confiante, pensa consigo mesmo: “Sou eu que estou fazendo, não vai falhar, o teste é a aplicação funcionando.” Ledo engano: você percebe que talvez você não estará enfrentando seu chefe (que sabe o que é um “if”, um “for”) , mas sim um cliente, que só sabe o que é resultado :)

Enfim, participando de alguns eventos ultimamente ( especialmente  o Linguágil 2011 ) vim a refletir sobre como ser produtivo, utilizando boas práticas (TDD, Convention over Configuration) e outros coisas legais que todo mundo quer aplicar no dia a dia mas muitas vezes só vê na faculdade e em palestras e uma frase me cativou: “Seja poliglota, aprenda mais de uma linguagem” .

Mas não seria melhor eu entrar na “Academia Brasileira de Letras” da linguagem que eu conheço? Talvez… Pode ser que você não vá usar aquele “idioma” tanto quanto seu “idioma nativo”, mas será que aprender um novo idioma não o fará utilizar melhor seu “idioma nativo”?

Tenho estudado Ruby nos últimos dias e, mesmo sendo um Javeiro confesso, tenho me encantado com as possibilidades que a linguagem te dá. Criação de getters e setters (que adoramos criar via Eclipse :P ) sendo gerados por você em uma linha de código:

class Usuario
   attr_accessor :nome, :cpf, :idade
end

Maps que comportam qualquer objeto, iterações simplificadas e acima de tudo, grandes possibilidades de metaprogamação e criação de DSL’s, execução de script’s pra situações específicas, etc etc etc…

Mas o mais importante pra mim foi perceber que não utilizamos bazuca pra matar formiga, e sim

genki-dama

genki-dama

…uma verdadeira Genk-dama ! Achamos tão normal e obrigatório criar getters/setters e nossos loops pra cálculo baseado em listas de elementos fortemente tipados, que temos menos tempo do que deveríamos pra testar nossas lógicas,  fazer nosso software realmente confiável.

Na pior das hipótese, ao enfrentar um “idioma” desconhecido como o Ruby, você perceberá o quanto pode ser bom orientar seu desenvolvimento aos cenários que sua solução deve atender, além de dar o braço a torcer e perceber que pra muita coisa não precisamos de uma genk-dama. Você é experiente, é bom, mas ao invés de ser humano não poderia ser automatizado? Será que não é possível convencionar todo código que você escreve (ainda que seu “idioma” não te dê isso prontinho) ? Será que aquela lógica que você precisa executar não poderia estar escrita numa linguagem de script que roda em sua VM  ?

Não quero mais a “Academia Brasileira de Letras”….

Hoje estou trabalhando em um projeto interessante, cujo alguns módulos possuem interface gráfica escrita utilizando Rails( e mais umas abstrações num framework interno). Eu já vinha na minha tentativa de praticar o poliglotismo programático a fazer umas pequenas brincadeiras com Rails, utilizando o Ruby padrão, e eis que me deparei com o seguinte cenário: deveria utilizar o JRuby e não o interpretador Ruby padrão. Mas eu queria manter ambos em meu ambiente de desenvolvimento. Pensei comigo mesmo “tal qual o Java vou instalar um novo ‘Jdk’, configurar o JAVA_HOME’ e pronto, posso manter ambas convivendo”, até que alguém me disse: “ai é mais caro”.

Pois é, ao trabalhar com ambos Jruby e Ruby instalados juntos, a gestão dos gems gerava conflitos. Na verdade não eram conflitos, eu simplesmente queria utilizar JRuby, mas os gems instalados iam para o Ruby. A primeira solução, e a mais simples naquele instante, foi colocar no PATH  a pasta %JRUBY_HOME%/bin antes de referenciar %RUBY_HOME%/bin , solução análoga a instalações de Banco Oracle que colocavam uma JRE bem antiga como preferencial no PATH. Existia também a solução zero, eliminar o Ruby e manter apenas o JRuby, mas como eu adoro um desafio,  resolvi ir à diversão :)

Não satisfeito que sou, procurei uma solução mais elegante para permitir a dupla convivência de interpretadores diferentes. E eis que existe uma solução: o Ruby Version Manager (RVM) . Resumindo um pouco a ópera, com ele é possível instalar versões diferentes de Ruby, e determinar qual versão específica será utilizada, atualizar um único gem pra uma dada versão, ou pra todas as versões instaladas. Uma coisa muito legal é a possibilidade de testar uma mesma aplicação para várias versões de Ruby instaladas de uma só vez.  Para tal o comando é :

rvm tests

Se eu quiser limitar por uma versão específica:

rvm 1.8.6,1.8.7,1.9.1 tests

No meu caso o RVM só tem um probleminha, é pra ambientes Unix, conforme FAQ :( Mas o próprio FAQ dá  a solução de minha questão, o projeto pik.

O pik atua de forma análoga ao RVM, só que para Windows. A documentação dele é mais pobre, mas não é nada muito diferente do RVM. Para listar os interpretadores disponíveis, é só executar:

pik list

Esse comando trará a lista dos interpretadores, basicamente tal qual o exemplo abaixo:

161: jruby 1.6.1
*187 ruby 1.8.7

indicando que o padrão é o ruby 1.8.7, e não o jruby 1.6.1. Para utilizar o Jruby como padrão, é só executar o comando:

pik use 161.

Desta forma, apenas o JRuby será reconhecido  como interpretador. Hoje ainda não tenho a real necessidade de manter essa convivência dupla entre interpretadores(nem demanda pra isso),  mas quem disse que temos tempo pra pensar nessas coisas quando um cenário desse aparece? :)  Pensar sempre à frente pode/poderá ser seu maior trunfo para estes momentos….

De volta..

Andei sumido…acho que os motivos não são mais importantes do que a possibilidade de estar na ativa de novo. Na semana passada ocorreu o Linguágil 2011 em Salvador, e pude perceber o quanto é bom não perder a paixão e a vontade em fazer o que se gosta. Ouvi de muitas pessoas coisas que já senti na pele, como querer fazer algo e sentir que você está sozinho, me frustrar pelos que não fizeram, e porque não contar com os que querem realizar? Os que querem interagir em comunidade?

Eu sempre amei estudar, pesquisar, programar, mas me falta algo mais, falta fazer público às vezes um pouco do que sei, falar sobre tecnologia, programar ! :) Assim como faltam começar muitas coisas…e pq não começar de novo? Eis que estou aqui, motivado a escrever de novo… ! Este post é muito mais pessoal do que técnico, e espero postar algumas coisas de novo em breve..vamo que vamo !

Dia 02 deste mês foi anunciado no site do SpringSource a disponibilidade da versão 1.5.0.M1 do Spring Blaze DS Integration. Pra quem não conhece este projeto, ele é responsável por abstrair a configuração de aplicações flex/air que utilizem o projeto BlazeDs como middleware de integração com backend java para invocações remotas, mensageria e serviços de push providos pela própria arquitetura da Adobe.

O BlazeDS é extremamente popular por ser um subset free do poderoso Adobe LiveCycle Data Services ES2 da Adobe, que apesar de bem mais limitado (vide quadro comparativo), oferece o mínimo necesário para desenvolvimento de uma aplicação. Até a hora que você decide utilizar alguma solução ORM em seu projeto…

Utilizando a versão 1.0.x do Spring Blaze DS, lá vamos nós tentar retornar uma entidade que possui uma coleção não carregada , em um típico mapeamento 1:N: um grupo que possui uma coleção de usuários, e quando vem o callback..o clássico e demoníaco “Session is closed”. Mas se eu não tentei acessar a coleção de usuários em momento algum, por que cargas d’água essa exceção está sendo lançada??? Maldita serialização de objetos !!

Simplesmente queremos recuperar o nome do grupo pra exibir em um Accordion na interface flex, e assumamos um cenário onde Open Session In View não é bem vindo. O livro Professional Blaze DS de Shashank Tiwari  fala sobre dois adapters Blaze DS open-source para cenários ORM: dpHibernate e Gilead. Ambos permitem carregamento tardio na camada flex(via geração de proxy’s Action Script), mas ferem brutalmente seu modelo de negócio por forçarem ao uso de herança nos POJO’s de seu domínio. Outra solução seria utilizar o GraniteDS

Voltando à exceção, o que acontece é que ao tentar serializar o POJO na camada Java e enviá-lo ao flex, o objeto que será convertido em Action Script é iterado atributo a atributo para que seja feita a sua criação. Mesmo que você queira acessar apenas o bendito nome, ele vai invocar o método getUsuarios do objeto Grupo, e como o proxy do mesmo continua lá após fechada a sessão..pow!

Problema bastante chato, resolvemos lá no trabalho criando um aspecto que itera pelo objeto após o fechamento da sessão do Hibernate( e antes da serialização do BlazeDS), que faz o papel sujo de desconsiderar os objetos proxiados pelo Hibernate..

Com o upgrade para esta versão 1.5 esse problema não será mais ocorrente pois foi incorporada uma solução elegante para este problema(após muitos pedidos da comunidade), conforme documentação .

Atualização de dependências para o Spring 3, BlazeDS 4 são itens relevantes para o upgrade da versão do Spring Blaze DS Integration em seu projeto, mas sugiro fortemente a adoção desta nova versão considerando o cenário exposto. Ufa, um motivo a menos pra não ser obrigado a adotar o LiveCycle Data Services :) Até o próximo post !

Pra inaugurar de fato este blog, meu amigo Maven.

O Maven é  um gerenciador de projetos de software, e não apenas um “simplificador de build” ou “ant melhorado”, como algumas pessoas chegam a dizer. Entre muitas de suas possibilidades de uso(além de definir pastas padrão para sources java, resources, testes unitários, etc etc etc..) , a que mais se destaca , especialmente a princípio, é a gestão de dependências. É muito legal,  quando você precisa usar JSF em seu projeto web e, ao invés de incluir 10 jar’s no classpath de seu projeto, simplesmente incluir uma ou duas dependências no seu pom(a famosa dependência transitiva).

Mas e quando o projeto começa a virar projeto de fato, encorpar, como simplificar um pom.xml que pode possuir dezenas de dependências agrupadas??? Ai é mais caro :)

Pra grande parte dos casos no maven, há sempre uma convenção que define um diretório ou valor de uma configuração, caso a mesma não esteja definida. Vamos falar especificamente de um elemento importante neste post, o elemento packaging ! O packaging é responsável por definir como será o empacotamento do artefato em questão, o que corresponderá ao elemento type para um outro projeto que faça uso do mesmo. Isso significa que um artefato xpto.xptoUtil, com packaging  jar, poderá ser usado como dependência em outro projeto, com o type jar.

Em geral, considerando uma estrutura muti-modular como no exemplo abaixo:

projetoRaiz

E o pom.xml do projetoRaiz:

projetoRaizPom

Detalhe para o valor do elemento packaging: pom! Como é que eu vou explicar pra meu chefe que o meu projeto gera um pacote pom, e não um jar, ear, war! :D Pois é, este tipo de packaging funciona como um arcabouço, um projeto onde você pode configurar propriedades, versões padrão de dependências, e outras coisas que você quer que os seus módulos filhos maven assumam (Isso é assunto pra outros post’s). Neste caso, apenas estou usando o projetoRaiz pra orquestrar o conjunto de módulos que preciso gerar, em que o principal de fato é o projetoWAR. Mas Silvio, você ainda não respondeu, como esse packaging pom vai me ajudar a organizar melhor meu pom.xml principal??

Ok, ok, eu conto :) Vamos utilizar o cenário do projetoRaiz, em que estou usando um conjunto de dependências relacionadas ao Spring Portfolio, e meu projeto principal dependa delas(neste caso, o projetoWAR). Quero usar 3 dependências ao mesmo tempo: spring-context, spring-orm, spring-webmvc na versão 3.0.0.RELEASE. Será uma dependência pra cada artefato, e, mesmo deixando de incluir o elemento type(já que por padrão o type é jar), ainda sim terei facilmente um pom muito extenso caso venha a incluir mais artefatos.

Vamos construir um artefato, que é nada mais que um artefato com packaging pom, e chamá-lo de springDependencies. Qual seu papel?  Simplesmente possuir as dependências mapeáveis explicitamente no pom.xml do projetoWAR, e ser utilizada no lugar das mesmas. E funciona isso? Funciona, e é uma boa prática! A seguir os dois pom’s, o do módulo SpringDependencies, e o do módulo principal:

springDependenciesPom

projetoWARPom

Você pode ter versões diferentes de projetoWAR para utilizar Spring 2.0, 2.5 e 3.0.0.RELEASE por exemplo. Fazer o war gerado utilizar a dependência correta, é tão simples quanto criar versões diferentes para o springDependencies(de preferência análogas a versão do próprio Spring), e assim o pom.xml do projetoWAR estará conciso e bem organizado.

Esse tipo de agrupamento é bastate interessante para casos em que seja possível organizar logicamente um conjunto de dependências. Ou pra ajudar em processos de build mais complexos (ACM que o diga :) ).

Então é isso, pra quem não conhece muito a respeito do Maven, sugiro o artigo publicado no GUJ pelo Mauricio Linhares, ou a própria documentação original.

Hello post!

Olá pessoALL,

A pedidos, resolvi tirar um pouco do peso da minha cabeça e escrever um pouco do que vivo no dia a dia (ou não!) . Dizem alguns que programar é uma arte, por isso que acredito que ensinar a programar pode ser poético :) Bobagens à parte, vou tentar falar um pouco sobre tecnologia, um pouco daquela sopa de letrinhas que todo mundo ama e odeia no Java,  e mais um conjunto de coisas correlatas. Spring, JEE, Flex, Maven, Integração contínua, JVM , Groovy, Grails serão alguns dos principais atores. E como toda novela/série que quase não tem fim, outros personagens vão aparecendo. To be continue…

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.