Pular para o conteúdo

ActiveJdbc, uma boa opção para trabalhar com ActiveRecord em Java

Para aqueles que me acompanha no twitter e um pouco nesse blog, sabem que sou um admirador da simplicidade e produtividade do Ruby On Rails um framework web em ruby.

Quero deixar bem claro que não tenho nada contra o java e por isso mantenho meus trabalhos com ele quando necessário, mas acredito muito que a programação poliglota está ai para que seus problemas sejam resolvidos independente da linguagem. Saber identificar o problema e mais que tudo saber escolher a ferramenta certa para resolve-la é o que o faz um bom arquiteto.

Durante um projeto no qual tenho trabalhado ou melhor passado a maior parte do meu tempo, esse tempo que posso dizer que não é muita coisa já que não é um projeto que estou trabalhando fulltime, eu tenho escolhidos frameworks que facilite a minha vida e atrapalhe menos. Como eu também desenvolvo projetos com Rails carrego pra os outros projetos seja qual for a sua tecnologia a necessidade de coisas que o Rails me deram como ferramenta para facilitar meu trabalho e uma delas foi o componente de persistencia ActiveRecord.

Active Record is the base for the models in a Rails application. It provides database independence, basic CRUD functionality, advanced finding capabilities, and the ability to relate models to one another, among other services.

Nesse projeto no qual foi preciso utilizar o java por questões contratuais que não vem ao caso explicar, percebi que seria uma boa opção aplicar algo parecido. Logo fiz algumas buscas no google e conheci um projeto chamado ActiveJDBC (AJ) criado pelo Igor @ipolevoy. Gostei muito do que vi, trazia a simplicidade e produtividade que eu precisava. ( como diz o próprio ipolevoy, uma especie de “java lightway” )

Um dos problemas que complica a utilização do ActiveRecord em java é devido as próprias restrições da linguagem, no qual o AJ utiliza-se de alterações do bytecode para gerar os metodos estáticos necessários.

Já utilizo o AJ tem 5 meses e já passei por diversas situações nos quais ele não dá suporte e muito do core dele eu alterei para atender as minhas necessidades. Conversando com o Igor (ipolevoy) venho pedindo a ele para hospedar o AJ no Github ( se você não conhece o github, é melhor dá uma pesquisa no google e conhecê-lo ). Mas para ele ainda não é prioridade essa migração.

Algumas anotações e metodos do core eu alterei/criei e ainda devo gerar um path para ele analisar.

Prefiro não exemplificar sobre o funcionamento do ActiveJDBC, para isso recomendo ler o wiki do projeto e conhecê-lo melhor. Convido você também a participar da lista de discurssão do grupo e postar dúvidas e melhorias.

Não fiz nenhum tipo de banchmark sobre performace do AJ, mas minha aplicação se comporta muito bem e ate mesmo melhor que utilizando o hibernate ( não posso afirmar isso sem dados concretos , mas conversando com o Igor (ipolevoy) ele tem dito que o AJ se comporta ate 40% mais rápido que o hibernate ).

Vale a pena dá uma olhada pra esse framework se você está precisando utilizar AR com java. Ele pode ser uma boa opção.

Anúncios

Trabalhando com o poder do git em repositórios svn

Durante os projetos que tenho trabalhado para um cliente, é preciso ainda manter o triste contato com o péssimo controle de versão chamado SVN. Claro, você pode não concordar comigo, mas definitivamente eu não consigo pensar diferente desde que comecei a utilizar o git em meus projetos.

Desde que eu conheci o git eu já sabia que tinha uma opção para você trabalhar com ele em projetos que usam o SVN, fazendo com que você possa usar todo o poder do git em projetos que estão utilizando o svn, Mas eu nunca tinha parado para estudá-lo e testá-lo. Até não suportar mais o svn. Então resolvi blogar aqui uma forma simples e que está resolvendo minha vida: git-svn.

Para fazer um clone do projeto que se encontra no svn utilize o comando: git svn clone url_do_projeto_no_svn -T sources -t tags -b branches

url_do_projeto_no_svn – não preciso comentar.
sources – pasta onde fica a trunk do do seu projeto no svn.
tags – pasta onde fica as tags do seu projeto no svn.
branches – pasta onde fica as branches do seu projeto no svn.

Utilizando o git para gerar branches no svn repository

Agora com um projeto em ambiente git conectado com o repositório do svn você pode utilizar o comando:
git svn branch -m ‘nova branche’ nova_branch para criar uma nova branch no svn baseado no codigo atual.
Logo após fazer isso gere também uma branch local no git: git checkout –track -b nova_branch remotes/nova_branch .

Para comitar as alterações do seu codigo para o svn repository utilize: git svn dcommit ( lembrando que esteja tudo devidamente comitado através dos passos normais quando se está utilizando o git )

Com isso você consegue utilizar o poder do git gerando branches locais, usando stashes, etc… trabalhando em repositórios svn remotos.

Com esses passos básicos você já pode começar a deixar de usar o svn e ter o git como uma verdadeira ferramenta de controle de versão :). Para conhecer melhor esses e outros comandos que você irá precisar no dia-a-dia, veja esse tutorial no qual foi baseado tudo que expliquei acima: http://trac.parrot.org/parrot/wiki/git-svn-tutorial

Utilizando cucumber com selenium em seus projetos java

Algum tempo venho utilizando o cucumber para escrever meus testes de aceitação em projetos em ruby, especialmente em projetos rails. Acho que essa situação é um bom exemplo de mostrar que vocês devem mesmo aprender pelo menos uma linguagem pro ano. Em projetos java me sentir um pouco desconfortado em desenvolver meus testes apenas com o Selenium. Escrever as features e cenários diretamente em metodos e classes em java doia muito e textualmente me dava mais liberdade a criatividade e até mesmo melhor compreensão dos testes a serem executados. Então resolvi utilizar o projeto cuke4duke! Uma versão para rodar o cucumber em diversas linguagem em cima da JVM.

Em meus projetos utilizo o ant e junto com o Cucumber o Selenium. Basicamente irei explicar os passos básicos para rodar o cucumber + o selenium com uma build do ant em uma aplicação web.

Estrutura de arquivos do Projeto

Para executar o cucumber em nosso projetos vamos montar a estruutra de arquivos necessários para isso. Basicamente temos a seguinte estrutura:

temos o package main onde temos o codigo de produção, o package test com a parte onde irá conter as classes de teste. Temos também a pasta features onde ficará todos os testes de aceitação escritos , a pasta lib contendo bibliotecas necessárias para rodar o projeto, ex. ( jetty, jruby, cuke4duke, etc) . e o WebContent a parte dos recursos web da aplicação.

Criando as tasks do ANT

Abaixo mostrarei apenas as tasks referentes ao cucumber, o build completo pode ser encontrado no github.

<!-- instala as gems necessarias para rodar os testes de aceitacao pelo cucumber. -->
 <target name="-install-gems" depends="-define-paths" if="gems">
 <taskdef name="gem" classname="cuke4duke.ant.GemTask" classpathref="tests.classpath" />
 <gem args="install cuke4duke --version 0.3.2 --source http://gemcutter.org/" />
 </target>

<!-- executa os testes de aceitação  -->
<target name="acceptance-test" depends="compile,-install-gems, start-jettys" description="Run Cucumber">
<taskdef name="cucumber" classname="cuke4duke.ant.CucumberTask" classpathref="acceptance-test.classpath" />
<cucumber args="--require target/test-classes --color --format pretty -f junit --out target/junit-report features" objectFactory="spring">
<classpath>
<path refid="acceptance-test.classpath"/>
</classpath>
</cucumber>
</target>
a Task install-gems, instala as gems ( biblotecas em Ruby )  necessários para rodar o cucumber. Veja que ele só será executado se existir o argumento gems. Para isso, execute a task com argumentos: ant acceptance-test -Dgems=true.
Na target do acceptance-test em suas dependências temos o start-jettys. ele inicializa o container web levantando assim a aplicação web. necessária para que o selenium possa executar os passos dos testes.

@StepDefinitions

Em nosso projeto definimos que o cuke4duke deve procurar metódos em java que identificam o passos das features através do StepDefitnions:
Para isso criamos em src/test/resources o arquivo cucumber.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="com.couggi.integration">
<context:include-filter type="annotation" expression="cuke4duke.spring.StepDefinitions"/>
</context:component-scan>
</beans>
Definimos que ele deve procurar classes anotadas no diretório: com.couggi.integration.

Criando uma Feature Exemplo

Na task do ant definimos que todas as features devem está na pasta features/ do nosso projeto. Criaremos então um arquivo de nome: login.feature ( Ignore a dúvida se essa é uma boa feature/cenário )

Feature: Login

Scenario: Logando em meu site
Given Eu esteja na pagina de login da aplicacao
When eu tento logar com o login “verto” e senha “123”
Then devera apresentar a pagina incial como logado

Para gerar os metodos necessários para executar os passos acima execute a task do acceptance-test e o cucumber irá apresentar para você os metodos necessários para que o teste funcione.

Para o cuke4duke identificar os metódos que serão executados ele utiliza Anotações:

@StepDefinitions para anota as classes nos quais contém os metódos.
@Given @Then @When , identifica os metodos referente aos passos de suas features.

No exemplo acima, criei a classe: LoginSteps com o conteúdo: http://github.com/vertocardoso/java-cucumber/blob/master/src/test/integration/com/couggi/integration/LoginSteps.java

Através desse exemplo, conseguimos integrar os nossos projetos com testes de aceitação utilizando o cucumber, criando assim um documento no qual seja mais descritivo para todos e totalmente executável.  Para maiores informações acesse o site do projeto: http://cukes.info/ . O projeto explicado acima está no meu github: http://github.com/vertocardoso/java-cucumber

Viaje leve, O cliente agradace!

Estive lendo esses dias o livro de Extreme Programming de Vinicius Teles , já tinha lido ele em 2006, mas acredito que é sempre bom reler um livro quando se tem uma maior visão/experiência sobre o assunto, acho que só tende a somar. Logo não consegui controlar a minha vontade de expressar meu total sentimento sobre um fator que eu acho de suma importância nas práticas do desenvolvimento de software: Feedback.

Um dos maiores problemas que eu costumo enfrentar em equipes é o foco no qual o serviço foi solicitado pelo cliente. Desenvolver seu software como principal objetivo lhe trazer lucros e benefícios. O que ocorre na prática são excessivos artefatos na tentativa de garantir que foi especificado e construído exatamente o que o cliente solicitou. Esquecem o objetivo trivial e com isso criam diversas formas de garantir com que a equipe não seja o responsável pelo retrabalho (não seria mudanças?), ser o responsável pelo fracasso de não atender exatamente o que o cliente precisa. (mas foi ele mesmo que pediu isso!).

Abraçe as Mudanças! Sim, diversas equipes criam contratos afim de garantir que as mudanças devem ser evitadas e que se ocorrerem, não será ela que irá pagar por isso! precisamos garantir isso, pois no final de tudo será preciso culpar alguém pelo erro. Devemos mesmo culpar quem errou? Ou melhorar afim de evitar o erro?  O ponto em questão é que na prática o cliente não sabe o que quer, e não adianta você tentar especificar e mostrar seus “prototipos” afim de que o cliente confirme: “É isso mesmo que você quer?”. Ok, isso reduz o ruído de interpretar um requisitos de forma errada, mas não acaba com o problema. Assim como a atividade de escrever um código, não basta a teoria , será preciso praticar e ter feedback dela para saber se exatamente isso lhe trás o retorno esperado.


Viaje leve! Como fazer isso?  Atentativa de especificar em diversos aterfatos o desenvolvimento do software afim de garantir as desejadas qualidades e garantias que aquilo está bem feito, são tão focadas que esquecem de entregar algo que realmente gere LUCRO  (sim, o cliente precisa de um software que lhe resolva seu problema afim de retornos lucrativos sempre!). E é isso que no final o software terá que atender. Agora vejamos em nosso “processo perfeito” esquecendo suas práticas ágeis, seu desenvolvimento waterfall e seus certificados de qualidade, O cliente deseja mesmo que tudo isso seja feito? Ou você está pegando o “suado” dinheiro dele e torrando com coisas que no final não irá lhe dá retorno algum?

Vamos falar um pouco sobre seus artefatos, você muito aficionado pela qualidade do serviço prestado, irá gerar uma ótima especificação a base de milhares de documentos onde guardam tudo o que o cliente falou e claro, não podemos esquecer de que ele assinou por isso! “SIM é isso mesmo que eu quero e vou pagar exatamente por isso”. Depois de uma garantia que nossas “bundas” estão protegidas podemos então partir para o nosso lado e desenvolver o produto com “a mais alta qualidade dos serviços prestados”, Então muito preocupado com essa qualidade passamos meses afim de encontrar a arquitetura perfeita, as melhores forma de reutilizar código (já vi muito framework caseiro saindo disso), montar aquelas coisas genericas que futuramente irão precisar e claro, isso tudo tem que está documentado! código? não basta! é preciso um documento que não seja necessário um desenvolvedor entender de código para codificar o projeto (WTF?).  O processo será rígido e terá fases bem definidas e tudo será bem controlado a base de horas, afinal de contas, Desenvolver software é tudo a mesma coisa, todo mundo irá fazer da mesma forma não importa o estado ou situação da equipe.

Quando o feedback estragou nosso sonho! Tudo muito lindo, muito bem documentado e com o reconhecimento de que estamos garantindo a qualidade que o cliente “merece”. Quando nos deparamos com o tempo… não temos um stop/play para isso, o cliente está olhando para seu relógio e torcendo para que a equipe entregue logo seu software e assim possa comecar a lhe trazer seu desejado retorno.

Hora de codificar! Começa a fase onde tudo vem a tona, a equipe começa a codificar tudo aquilo que foi especificado, mas começa a entrar o principal fator para saber se algo realmente funciona: O feedback , a equipe começa a ter feedback por parte do código que não foi a melhor solução escolhida para sua arquitetura e então será preciso mudar. (Mudar? mas nosso contrato foi definido afim de não ocorrer as mudanças!), Mas isso não pode ocorrer pois as horas estão contando! horas,  aquelas as quais o cliente está pagando e “doido” que passe logo para ter seu software. E o ciclo em alterar artefatos afim de atender o feedback do código é constante e muitas vezes percebe-se: Ou paramos de atualizar artefatos ou entregamos o software no seu prazo (ou atrasado). E lá se vai mais dinheiro descendo pela ralo, dinheiro que o cliente poderia ter investido de uma maneira mais lucrativa ou não?!

No final a equipe consegui entregar o projeto com todos os problemas ocorridos e um razoável atraso da entrega prevista, o cliente já pode ter o feedback de tudo que foi planejado desde o inicio. Feedback? isso mesmo, e no final o projeto acaba não gerando o retorno esperado pelo cliente, pois ele viu com o feedback que poderia ser feito de uma forma mais eficaz e até coisas que pareciam úteis já não fazia mais sentido após utilizá-lo. Esse é um dos pontos que costuma acontecer no fracasso dos projetos de TI e não sou eu que estou afirmando isso.

Viajar leve é isso, fazer com que você evite dolorosos trabalhos aparentemente útil porém pouco necessário quando se precisa. Em minhas experiências em diversos projetos pude perceber que nunca voltavamos a olhar para todo aqueles documentos criados para “auxiliar” o desenvolvimento. Muito desses artefatos que cria uma falsa qualidade para o software acaba gastando tempo e na maioria das vezes ficando defasado após o constante feedback que o código gera para a equipe.

Mantenha-se simples, entregue releases curtos, mantenha o feedback continuo, procure entregar sempre o VALOR REAL para o cliente. Quando for construi um software pense bem nisso, pense se está gastando corretamente o dinheiro do seu cliente e se o que você está fazendo irá mesmo lhe dá retorno do seu investimento. O cliente agradace!

Graphviz uma boa opção para gerar gráficos!

Algum tempo estive trabalhando com o Graphviz para gerar diagramas para um projeto. Desde então trabalhei com um projeto em ruby onde encontrei uma ótima opção para interface desse software: http://github.com/glejeune/Ruby-Graphviz ,

Para quem ainda não conhece o graphviz ele é muito simples e não tem dificuldade em entendê-lo. Vejamos um simples hello world:

digraph G {Hello->World}

utilizando o dot geramos a saida em png:

~$ echo “digraph G {Hello->World}” | dot -Tpng >hello.png

Em meus projetos tive a necessidade de utilizar uma interface pra gerar a  estrutura do arquivo dot deixando assim de se preocupar com a parte tecnica e focando em nodes edges, graphs..

Com o projeto http://github.com/glejeune/Ruby-Graphviz vejamos o exemplo do hello world.

# Create a new graph
g = GraphViz.new(:ER,:type => :digraph)
hello = g.add_node(“hello”)
world = g.add_node(“world”)
g.add_edge(hello,world)
g.output( :png => “helloworld.png” )
Atualmente temos outras alternativas como o http://github.com/Sobe/IoGraphViz para Io e o http://github.com/vertocardoso/java-graphviz para java no qual eu criei.
Vejamos o mesmo exemplo usando o javagraphviz:

import com.couggi.javagraphviz.Digraph;
import com.couggi.javagraphviz.Graph;
import com.couggi.javagraphviz.GraphvizEngine;
import com.couggi.javagraphviz.Node;

public class HelloWorldSample {

  public static void main(String[] args) {

    // define a graph with the Digraph Type.
    Graph graph = new Digraph("G");
    // create nodes with names
    Node hello = graph.addNode("Hello");
    Node world = graph.addNode("World");
    // create a edge with hello node and world node.
    graph.addEdge(hello, world);
    // create the Graphviz engine to the graph
    GraphvizEngine engine = new GraphvizEngine(graph);
    // define the type of the output
    engine.type("png");
    // define the file name of the output.
    engine.toFilePath("helloworld.png");
    // generate output.
    engine.output();

  }
}
Sem dúvida o graphviz merece sua devida atenção! Quem tiver interesse em contribui, os projetos são de código aberto e estão disponíveis no github!

Pra que “modinha”? prefiro meu “martelo”!

Uma vez estavamos conversando na mesa sobre uma situação de um profissional, que hoje sofre com a situação de não ter o mesmo “padrão de vida” que tinha há um tempo atrás. Nessa epóca ser um Representante Comercial lhe dava bons frutos, a renumeração era gorda e garantida, porém com o tempo ela foi se perdendo, recursos para aproximar o cliente final com os produtos estavam cada vez mais, virando realidade e ser um Representante Comercial no estilo “passado” estava cada vez mais escasso, o ROI tendia a baixar cada vez mais. Muitos acompanharam a evolução e se adequaram a esse novo estilo, outros.. talvez fecharam os olhos para a situação e mantiveram sua estratégia. O resultado? Acho que você já sabe onde isso irá chegar certo?

Essa história talvez não seja a ideal para tentar passar o meu sentimento sobre o tão quanto importante é se adequar as mudanças do mundo tecnológico e as ferramentas que nascem todos os dias, para tentar sempre facilitar o nosso trabalho do dia-a-dia. Linguagens, frameworks, IDEs, redes sociais, metodologias… temos aos montes e você acha isso ruim? Eu não! Acho que essa variedade de opções que temos só vem para somar, hoje temos a facilidade de escolher a melhor linguagem para resolver um determinado problema, recursos fantátiscos de comunicação como o twitter nos dá maior proximidade de um mundo no qual você gostaria de está envolvido. Como hoje é simples acompanhar as novidades da nossa área através do twitter?! Como hoje é dificil você precisar escrever uma nova API para uma resolver uma situação do seu dia-dia?! A Comunidade cada vez mais se beneficia dos projetos Opensource e muito delas um dia foi modinha.

Há quem diga que temos ter cuidado com o uso das “modinhas” que surge todos os dias! Eu sou mais radical, O problema em usar as “modinhas” para facilitar seu dia-a-dia é saber como e onde usá-la e é ai que entra um verdadeiro programador pragmático. É preciso sim se dedicar e focar nas tecnologias que podem/devem te ajudar. Compre livros, escreva códigos, leia blogs, participe de eventos! Participe de um dojo, comunique-se com as pesssoas envolvida no projeto. Opções para se manter a maturidade suficiente em usuflir dos recursos das “modinhas” são várias.

Não existe Bala de Prata, a consequência de estatísticas pessimistas quando se fala em desenvolvimento de software são criadas justamente pela falta de profissionalismo daqueles que atuam nele. Encarar a atividade de desenvolver software como apenas bater um prego todos os dias em seu horário comercial e voltar para casa é uma verdadeira falácia. Sabemos que isso não basta e quando percebe-se.. está defasado! Quem hoje desenvolveria um projeto web em java apenas com Servlet e JSP ( Não estou me referindo a projetos de pequeno porte) ? Seria uma péssima escolha diante tamanhas opções que temos atualmente.  Esqueca seu martelo favorito, foque em sua caixa de ferramentas e tente cada vez mais adicionar novos recursos para ela! As “modinhas” da atualidade pode fazer seu martelo virar um canivete suiço.

Quando e onde devo refatorar?

Não basta apenas escrever um código que funcione!


Atualmente, Estive exaustivamente trabalhando em um projeto resolvendo problemas de erros e falhas do modelo em cascata no qual já conhecemos. Sempre muitas pessoas são questionadas quando elas devem refatorar. Muitas desculpas do tipo, “Meu chefe não aceita que eu use horas de trabalho reconstruindo o projeto” são normalmente dadas. Mas, a resposta é muito fácil: a todo momento sim, Devemos refatorar e melhorar o projeto. Contudo, Isso não significa que você tenha que parar seu projeto e reconstruí-lo. Nem as práticas de refatoração recomenda isso.

As oportunidades de melhorar o nosso código são constantes. Uma delas é bugs do projeto. Para resolve-lo, você necessita entender o código, uma boa idéia de fazer isso é: Refatorando! Analisando o código, você perceberá que aplicando alguns metódos de refatoração as coisas começam a ficar mais legíveis.

Refatorar também não siginfica que você só irá aplicar em projetos com erros ou quando estiver resolvendo problemas! (não que desenvolvimento de novas funcionalidades não siginifica resolver um problema), Mas, é muito importante que ao longo da escrita de seu código, você volte, olhe para ele e veja se está realmente legível. Aplicando metódos de refatoração para melhorá-lo, Caso seja necessário.

Refatoração é uma coisa realmente que todo desenvolvedor deve aplicar, o difícil é saber quando deve parar.

Relembrando que nunca é tarde para melhorar seu projeto, Mesmo que ele seja uma “Bomba Relógio”. Existe sempre um modo de melhorá-lo, mesmo que seja uma pequena parte dele.