Como uso Grails – a questão do código legado

De todos os frameworks web que já usei (Java ou não) de longe Grails é o meu favorito. É a plataforma Java Enterprise Edition como sempre deveria ter sido: simples, direta, fácil de usar e sem burocracia. Mas sabe de uma coisa? Adoro um Grails “mutilado”!

Eu sei: soa estranho, mas eu não uso todo o stack do Grails. Ignoro o GORM, que é a camada de persistência. E o scaffolding, razão pela qual muitos se apaixonam pelo framework eu simplesmente abomino. E quer saber de mais uma coisa? Só uso 2 plugins: jQuery e Quartz. Conforme fui me aprofundando no framework acabei desenvolvendo uma maneira própria de trabalhar com ele. E é justamente este o assunto deste post.

O que é lindo no Grails: o fato de ser Java

O mais legal é o fato de ser baseado em Groovy. A fórmula é simples: se é Groovy, é Java. Tudo aquilo que você está acostumado a fazer em Java pode ser feito quase que da mesma forma com Groovy. Na realidade: da pra fazer de formas ainda mais legais. O acesso ao código legado (o que inclui todas as suas bibliotecas e frameworks favoritos) de forma transparente funciona como se fosse uma “fonte da juventude” para todo aquele amontoado de código que muitas vezes adquire com o tempo uma certa aura de tediosidade. Como já disse antes, Grails tira a plataforma JEE do marasmo.

Lembre-se disto: Groovy é Java. Ao trabalhar com Grails, você não precisa usar só os plugins oferecidos para o framework. Você pode e deve ir além. Se quiser pular o resto deste post, tenha apenas isto em mente.

MVC como lei: o problema com Grails

No meu caso é muito comum precisar escrever uma aplicação que será executada em diversos ambientes diferentes usando a mesma lógica de negócio. Até ai, tudo bem: eu poderia centralizar minha lógica de negócios em um servidor de aplicações e em seguida simplesmente implementar uma série de clientes, certo? Infelizmente apenas em condições ideais de temperatura e pressão.

Muitas vezes um cliente quer uma versão desktop de uma aplicação web que eu já tenha desenvolvido, ou mesmo o contrário. E em um número assustadoramente grande de vezes eu sequer posso contar com um servidor de aplicações (ainda não estamos no paraíso). Nestes casos a única constante computacional que possuo (quando dou sorte) é o SGBD.  No meu caso reaproveitamento se torna uma questão de sobrevivência.

A solução que encontrei se chama Spring. Com ele tenho quase todos os recursos que obteria com EJB sem a necessidade de um servidor de aplicações e, o que é ainda melhor: tornando meu código Java realmente móvel. Basta que eu o empacote tudo o que eu preciso em arquivos jar e em seguida os reaproveite no ambiente de execução em questão: web, desktop ou seja lá o que for.

É exatamente por esta razão – a necessidade de reaproveitamento de código – que em 99% das vezes uso XML ao invés de anotações pra configurar o Spring ou o Hibernate. XML eu externalizo fácil fora dos meus arquivos .jar: anotações não.

O problema do reaproveitamento de código Grails

Grails me trás um único inconveniente: se você desenvolve algo 100% baseado no framework, o reaproveitamento do código gerado fora do Grails se mostra bem complicado. Resumindo: jogar seu código Java dentro de um projeto Grails é maravilhosamente simples: basta copiar todos os arquivos jar necessários para o diretório lib da sua aplicação. No entanto, se você escreve sua lógica de negócio usando como base componentes de infraestrutura do Grails como o GORM, por exemplo, reaproveitar seu código Groovy fora da plataforma Grails se mostra tarefa práticamente impossível.

O único modo eficiente que conheço de reaproveitar código 100% baseado em Grails é através da criação de plugins. Infelizmente seu plugin só poderá ser executado em outro projeto Grails (pelo menos por enquanto). Apesar de desde a versão 1.2 (ou seria a 1.1?) dizerem ser possível usar o GORM fora do Grails, eu nunca o consegui nem conheci alguém que tivesse obtido sucesso nesta tarefa (se você obteve, por favor, me conte como fez ok?).

Como resolvo a questão

Simplesmente não uso o GORM. Ao iniciar um novo projeto em Grails que vá usar meu código legado, a primeira coisa que faço é desinstalar o plugin do Hibernate. Assim não tenho sequer a tentação de criar uma ou outra classe de domínio que seja persistida com o GORM. Na prática,  a única vantagem do GORM – ao menos pra mim – sempre foi a criação de finders dinâmicos e o modo como as classes de domínio são mapeadas para o banco de dados.

Mas sabe de uma coisa? Percebi que raramente uso finders dinâmicos! Sendo assim, no meu caso vale muito à pena sacrificar uma funcionalidade que eu raríssimas vezes uso por uma maior mobilidade do meu código fonte.

Toda a minha camada de negócio é implementada fora do Grails. Normalmente é escrita usando Java, Groovy ou, mais recentemente, Clojure. Sempre sem qualquer dependência direta com qualquer componente de infra-estruura do Grails.

Resumindo: o Grails deixa de ser um framework full stack no meu caso e passa a ser o responsável apenas pela camada de visualização e controle.

Mas sem o GORM, o que Grails tem de bacana? Tudo!

Mesmo sem ser usado como um framework fullstack, Grails ainda se mostra o meu framework web favorito. GSP é uma das tecnologias mais bacanas com as quais já trabalhei. Isto porquê diversas das tarefas chatas de serem feitas na plataforma JEE se mostram ridiculamente simples em Grails. Só para citar algumas: criação de tags customizadas e implementação de filtros.

Além disto, o modo como criamos controladores com Grails é o mais elegante que já encontrei. Muito mais fácil de se trabalhar do que com JSF ou Struts por exemplo. É direto, simples, sem burocracia. Eu posso me focar só no que o controlador tem de fazer e o que é ainda mais interessante: dentro deste tratar meu código Java como se fosse Groovy!

Scaffolding

Muita gente se apaixona pelo Grails ao ver o scaffolding em funcionamento. O problema é que muitos acabam se esquecendo de um fato básico: scaffolding em inglês significa andaime. O que é um andaime? É uma estrutura que usamos como apoio ao construir alguma coisa, não é o objetivo buscado.

Vejo muitos iniciantes acharem que só podem executar determinada tarefa em Grails se o scaffolding oferecer recurso para tal. Bom: sendo assim sua aplicação só poderá incluir, editar, excluir e listar registros no banco de dados. Se este é o objetivo do seu projeto, vá fundo! O problema é que sua aplicação corresponde a apenas 0,01% dos casos reais. Ainda bem, pois caso contrário desenvolver sistemas seria tarefa executada por macacos.

Como não sou um macaco e o CRUD básico gerado pelo scaffolding do Grails no meu caso é desnecessário – pois sempre estou reaproveitando meu código legado – simplesmente o ignoro, mutilando assim mais um membro do Grails.

Plugins

A idéia do plugin é maravilhosa. É o reaproveitamento de código no qual “nada pode dar errado“, visto que, ao menos em teoria, trata-se de um projeto já bastante testado, com qualidade excelente e que lhe poupará um tempo enorme, pois te livra do trabalho de precisar reinventar a roda. Infelizmente nem tudo são flores.

De todos os plugins não desenvolvidos por mim ou pela minha equipe, acabei ficando com apenas dois: jQuery e Quartz. Antes de construir uma aplicação lotada de plugins, sempre levo em consideração o seguinte:

Aumento acidental do déficit técnico – Sejamos honestos: quantas vezes você chegou a ler (e entender) o código fonte dos plugins que usa em seus projetos? Caso encontre um bug no seu plugin favorito e seu deadline esteja curto, você tem certeza de que conseguirá em tempo hábil resolver o bug deste componente ou encontrar uma solução alternativa de qualidade?  Minha solução para este problema é simples: se for para usar um plugin, só opto por ele se já tiver um bom histórico por trás, ou seja, ignoro qualquer plugin que ainda esteja na sua primeira revisão e que tenha sido pouco usado pela comunidade.

Problemas de compatibildiade – Quem trabalha com Grails tem de estar preparado paraa atualizar o framework sempre que seja lançado um novo release. Convenhamos: apesar de ser um framework maravilhoso, ainda possui um BOM número de bugs. É vital que seu projeto esteja com a última versão do Grails. Agora: e se o seu plugin for incompatível com o último release o que você faz? Chora? Espera que o autor do plugin encontre uma solução para o problema?

Aumento do número de dependências - É fato. Seu projeto agora depende de código que só estará sob seu domínio se, e somente se, você tiver conhecimento completo sobre seu funcionamento. Ao optar pelo uso de um plugin, tenha sempre em mãos o código fonte usado e, ainda mais importante: compreenda-o.

Resumindo: plugins são uma das boas coisas da vida. Sendo assim você precisa tratá-lo como tal, ou seja, com EXTREMA moderação. Não estou sozinho na minha opinião sobre plugins. DHH tem uma visão bastante similar.

(e antes que digam: não estou dizendo que os únicos plugins bons são o jQuery e o Quartz)

Concluindo

Grails é maravilhoso. Este framework revitalizou meu código legado de uma forma que até então eu não podia sequer sonhar. Quando Ruby on Rails surgiu e se tornou popular, ficou claro que o modo como estavamos desenvolvendo aplicações para a plataforma JEE tinha algo de muito errado. O problema é que muitos desenvolvedores – como eu – já tinham uma quantidade significativa de código legado de qualidade, ou seja, testado e funcionando perfeitamente (ou quase :) ) e não podiam se dar ao luxo de ter o retrabalho de  implementar novamente em outra linguagem. Legado só é negativo quando é de má qualidade e você é obrigado a conviver com ele.

Quando conheci Grails foi um alívio imenso porque de repente eu podia escrever aplicações como em Ruby on Rails dentro da plataforma Java sem precisar reescrever nada do que já estava pronto. E o que era melhor: de uma forma muito produtiva, porque até a minha curva de aprendizado era menor. Afinal de contas, eu ainda podia contar com as mesmas bibliotecas com as quais adorava trabalhar, como por exemplo as do projeto Apache Commons.

Meu conselho para quem estiver inicando em Grails é o seguinte: se for um projeto novo, criado a partir do zero e que só será executado em um ambiente computacional, no caso, web: use e abuse dos recursos oferecidos pelo framework. Se puder sempre contar com um servidor de aplicações para este projeto e seus derivados não se assuste com os problemas de mobilidade de código que mencionei acima: você pode implementar interfaces REST ou baseadas em WS com Grails de uma maneira maravilhosamente simples.

Agora: se você possui código legado de qualidade, ou sabe que alguns componentes do seu projeto deverão ser executados em ambientes diversos, implemente-os de forma completamente independente do Grails.

De uma forma ou de outra você sairá ganhando porque a produtividade do Grails – mesmo mutilado – é simplesmente fantástica. O mais importante a ser lembrado é o seguinte: você não programa em Grails, mas sim em alguma linguagem de programação executada na JVM. Sua plataforma não é – nem deve ser – o framework, mas a JVM. Tire proveito disto!

Leitura complementar

Joel Spolsky tem um artigo chamado “Things You Should Never Do – Part I” que é justamente sobre o perigo de se reescrever código do zero, e como isto pode destruir a sua empresa. Concordo com o autor, cujo texto pode ser lido aqui: http://www.joelonsoftware.com/articles/fog0000000069.html

21 thoughts on “Como uso Grails – a questão do código legado

  1. Muito bom o texto. Sou iniciante em Grails e é sempre bom ler sobre as experiencias de quem está a mais tempo no mercado de trabalho.

    Responda

    admin Reply:

    Oi Renato, fico feliz que tenha gostado. Valeu!

    Responda

  2. Ótimo post! Precisamos exatamente desse tipo de visão para que o grails se popularize, pois a parte “VC “do MVC de grails é realmente pra lá de simples, sem mencionar a falta de necessidade de restart do servidor, um verdadeiro entrave para quem tem que usar servidores pesados como o jboss ou websphere, como eu.

    Responda

    admin Reply:

    Que bom que gostou Oziel! Valeu!

    Responda

  3. Muito interessante o post, e a parte que se refere aos plugins é muito portante.
    Não tinha me atentado para esses pontos.

    Parabéns.

    Responda

    admin Reply:

    Oi Gregory, valeu!

    Responda

  4. Muito Bom!!! Muito interessante o post, estou engatinhando no mundo groovy/grails e assim como o Renato Ramiro mensionou, é muito importante para o nosso aprendizado em uma nova tecnlogia observar como os mais experientes lidam com ela!
    Parabéns!

    Responda

    admin Reply:

    Oi Luiz, fico feliz que tenha gostado. Valeu!

    Responda

  5. Uma regra geral que tenho utilizado: GORM quando o projeto é puramente Grails, e JPA quando o projeto se integra com outros ou fazer parte de um sistema maior. Grails é Java, por isso ele é melhor que Rails na maior parte dos cenários corporativos onde já existem centenas de bibliotecas e domínios prontos.

    A beleza do Grails é que ele te entrega um pacote completo (full-stack), que agiliza o time-to-market, mas não engessa nada. Você usa aquilo que te atende. =)

    Go Grails Go!

    Responda

    admin Reply:

    Eu vejo Grails como uma “cola embelezadora” :). Ele integra varios componentes que eu já tenho prontos e ao mesmo tempo da uma “renovada” naquilo que já estava pronto graças ao Groovy.

    Concordo 110% com a sua regra geral. Quando o projeto é puramente Grails, tem mais é que usar e abusar do stack completo mesmo. Afinal de contas, um dos fatores que o tornam produtivo é justamente este.

    Mas eu ainda prefiro o meu “mutiladinho” =)

    Responda

  6. Muito bom.
    Gostaria de entender um pouco mais essa parte aqui: “Toda a minha camada de negócio é implementada fora do Grails”.
    Seus objetos de domínio são em Java? O mapeamento Hibernate vc faz com XML? As queries vc usa HQL? Vc usa Named Queries? E as transações? Você usa as classes de serviço do Grails para demarcar as transações? Fazendo toda esta parte fora do grails, como vc monta sua arquitetura? Você tem uma camada DAO? Você usa Active Record? Como você passa (ou pega) a Hibernate Session aberta pelo Grails no seu código fora do grails?
    Desculpe tantas perguntas, mas é que o tema me interessa muito e acho que muita gente pode gostar de discutir mais os detalhes deste mundo.

    Abcs
    Felipe

    Responda

    admin Reply:

    Oi Felipe!

    Bom: o que faço é o seguinte: toda a lógica de negócio, assim como os componentes que acessam a base de dados (classes de domínio, gerenciamento de transações, ORM, resumindo: infra-estrutura etc.) é normalmente implementado em Java puro ou qualquer outra linguagem que não acesse diretamente qualquer componente de infraestrutura do Grails OU simplesmente já existia como legado. Então todo este controle é feito por esta camada que uso como núcleo dos sistemas.

    Dentro desta mesma camada de negócio uso o Spring para orquestrar tudo. É com ele que configuro o Hibernate e defino quais os beans no meu código legado que deverão ser gerenciados, além de controle de transações, integrações, etc. Neste caso, como o objetivo é reaproveitamento total de código, anotações são vistas como algo a ser evitado, porque não é possível externalizá-las fora do código fonte, tal como é feito no XML.

    Feito isto, com esta camada toda bem montada (novamente: normalmente ela já está pronta), inicio um novo projeto em Grails no qual desinstalo o plugin do Hibernate (consequentemente, o GORM), porque ele passa a ser desnecessário e uso o Grails apenas como Controle e Visualização: ou seja: ele apenas usa as classes que disponibilizo para o projeto Grails, o framework não se torna mais responsável por gerenciar transações. Este trabalho já é normalmente feito pela camada de domínio (99% das vezes o Spring já está fazendo isto pra mim neste componente)

    O mapeamento com Hibernate normalmente é XML puro, porque assim, caso eu precise fazer deploy do meu código em uma estrutura de banco de dados ligeiramente diferente, tudo o que preciso fazer é alterar arquivos XML, ao invés de recompilar código, tal como seria necessário usando anotações.

    Se uso HQL ou não. Olha: em consultas muito simples, HQL cai como uma alternativa interessante, mas para casos mais coplexos, ele sofre o mesmo problema do SQL tradicional: a necessidade de concaternar texto na consulta. Sendo assim, raríssimas vezes uso HQL e na esmagadora maioria uso Criteria. Como as criterias só começaram a ser implantadas de fato no JPA2, ainda uso em diversos projetos Hibernate puro mesmo.

    Como pego a SessionFactory do Hibenrate pelo Grails: pelo container do Spring presente na camada de modelo. É por lá mesmo que acesso tudo. Como mencionei, Grails fica só responsável pela camada de controle e visualização. O Grails nem sequer abre uma sessão com o Hibernate, porque eu desinstalo este plugin.

    E como trabalho com os dois projetos ao mesmo tempo: o núcleo e a visualização com Grails. Simples: crio um script em ant ou gradle que compile meu código fonte do núcleo e em seguida o copie para o diretório lib do projeto Grails.

    Basicamente, são dois projetos: um com o núcleo, que não tem contato com qualquer tipo de interface gráfica e o projeto Grails, que é responsável pela GUI do sistema.

    Responda

  7. Cara parabéns pelo post,

    dá gosto de ler postagens como essa,
    Eu adoro o Grails, acho muito legal tudo que ele oferece, mas que nem você disse, deve se considerar quando é necessário utilizar tudo ou só parte.
    Eu tenho também minha infraestrutura toda escrita em java que já utilizava em outros projetos, ainda tenho que pegar as manhas do Spring para poder integrar bem o Grails com o meu código legado. Tua postagem abriu bem meus olhos e mostra porque o Grails é um dos melhores frameworks que existem, simplesmente porque ele te oferece tudo que você precisa, mas também não impõem nada, conceito similar ao do Spring.

    Responda

    admin Reply:

    Opa, valeu Mayko!

    Responda

  8. Muito bons os textos sobre Grails. Mas eu ainda não encontrei a resposta pra minha dúvida:

    – É possível trabalhar com Grails sem Groovy ? Se sim, vale a pena, ou tem sentido ?

    Responda

    admin Reply:

    Oi Roberto, legal que tenha gostado.

    É possível trabalhar com Grails sem Groovy? Depende do que queremos dizer com isto.

    Se for apenas usando código legado, como mostro neste post, sim, é possível, e faz sentido quando você quer reaproveitar o que já possui.

    Agora, programar em Grails de cara só com Java não vale à pena nem faz sentido, porque você estaria forçando a barra com o framework e este não te daria os ganhos de produtividade que você esperaria obter. Neste caso, seria até mais interessante trabalhar com algum outro framework Java mesmo, como Wicket, Roo ou até mesmo o JSF.

    Em casos nos quais vejo o pessoal trabalhando com Grails assim (usando só Java) é garantida a tragédia nem muito tempo depois.

    Responda

    Roberto Reply:

    Entendi, é que eu estou ainda na faculdade, e onde faço estágio usamos Java Struts2, meu chefe comentou sobre grails, eu dei uma pesquisada e tals, li seus artigos, e queria saber se seria possível, não para grandes aplicações, mas para ver como funciona e tals, apenas usando java mesmo.

    Obrigado pelas dicas.

    Responda

  9. Eu sou um estudante do curso de informatica e pretendo saber como posso aplicar os botoes radio e checkbox na interface principal (home)..
    Obrigado

    Responda

    Kico (Henrique Lobo Weissmann) Reply:

    oi Anathol, duvidas como esta eu reapondo apenas pelo.Grails Brasil por ser o local mais apropriado. http://www.grailsbrasil.com.br

    Responda

  10. Como faxo o tratamento deste erro kuando tento criar um projecto em grails no netbeans:

    Error occurred during initialization of VM
    Could not reserve enough space for object heap

    Responda

    Kico (Henrique Lobo Weissmann) Reply:

    Ola, vomo disse na resposta anterior, duvidas sobre Grails só respondo no Grails Brasil por ser o local mais apropriado para isto. :)

    Responda

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>