Desenvolvimento Ágil na Web com Seam

Bem, nem só de Scrum vive esse blog! O propósito deste post é falar um pouco da nova arquitetura que adotamos para o projeto Hotmotors. Desde que publiquei aqui no Débito Técnico o artigo “UML não é documentação”, onde disse que a arquitetura (Struts 1 + Hibernate) de 2006 não me dava muito orgulho, várias pessoas entraram em contato para ajudar no desenvolvimento de uma nova arquitetura Seam. O Rafael Benevides foi o cara que topou a parada e começamos o trabalho.

Pra falar a verdade fiquei até surpreso como a conversão de uma arquitetura para outra foi rápida. O Rafael me entregou a primeira iteração em 2 dias (OK, talvez ele seja um code hose). O trabalho dele foi portar o Hibernate para JPA, passar todos os JSP para xhtml e retirar o Struts de cena implantando o JSF/Seam. Segundo o próprio Rafael, o fato de termos um bom design ajudou bastante, principalmente o fato de nosso Domain Model estar bem fundamentado.

Por que o Seam Framework?

Eu já trabalho com sistemas baseados em web a bastante tempo. A evolução que esse tipo de sistema foi desde escrever vários servlets na mão que cuspiam html, seguido a inclusão de JSPs, as infinitas Tag Libraries, a introdução de composite-views (como o Tiles), o Struts e a segunda geração de frameworks (WebWork, Spring MVC, VRaptor, Mentawai, só para citar alguns). Correndo meio que por fora disso temos o JSF. O JSF é controverso. A idéia do JSF era ter em Java a mesma idéia que existe no Web Forms do ASP.Net. Um event-based framework que melhorasse a produtividade na construção da view (junto com muitas outras coisas mais). Por que ele é controverso? Bem, primeiramente o JSF é um tipo de tecnologia que visava uma dependência de ferramenta (como uma boa IDE). Muitas outras coisas foram discutidas numa longa, mas muito longa thread do GUJ (note que ela iniciou em 2005).

http://www.guj.com.br/posts/list/29623.java

Um outro fato é que JSF-based tem várias implementações alternativas (ADF Faces, RichFaces, MyFaces só pra citar alguns). Se você usar a reference implementation da Sun você não terá coisas muito interessantes e ainda sofrerá de “configuration hell” com XML, mas usando essas alternativas você ganha uma view limpa e uma grande facilidade em fazer RIAs com Ajax.

O SeamFramework inicialmente era bem baseado no RichFaces, porém, atualmente na versão 2.x, ele é mais independente do framework web que você escolheu. De qualquer forma, o Seam é uma excelente alternativa para integrar sua camada view em JSF à sua camada de aplicação, oferecendo uma consistente implementação para ligar tudo isso. Como falei, eu já passei em vários frameworks web, principalmente os Action based. Usando o Seam, basicamente os benefícios que ví foram:

1. Convention Over Configuration (não é necessário configurar nada em XML – tenho nojo de XML)
2. Component-based e não Action-based (de fato, não há uma boa definição sobre essa diferença)
3. Boa integração entre JSF e EJB3.
4. Conversation Model (não ví nenhum framework web resolver isso da maneira que o Seam faz)
5. Menos Javascript para coisas banais
6. Injeção de Dependências via anotações
7. Integração com outras coisas como o JBpm.

Muitas outras razões você pode ver no site www.seamframework.org. O SeamFramework foi uma das razões para eu voltar a gostar de fazer aplicações web em Java. Faz mais ou menos 2 anos que estou utilizando o Seam, algumas coisas já estão no ar e realmente são aplicações confiáveis.

[photopress:app_seam.JPG,full,pp_image]

Algumas coisas que me incomodam… e outras que resolví.

Aos 4 ventos eu promovo o Seam como uma boa arquitetura de caixinha em JEE. Mas nem tudo é um mar de rosas. O Seam é um monstro. É um framework muito grande e precisa de uma infraestrutura no lugar para que ele possa rodar. Desde que iniciei com o framework tive dificuldades em fazer DI fora de um ambiente JEE. Isto é um problema quando você quer tomar uma estratégia TDD de verdade. Como exemplo, para fazer um SeamTest rodar você precisa ter um Embeddable Jboss. Isto é, você precisa de um JNDI, um EntityManager Factory e toda parafernália JEE no ar. Numa máquina mediana isso pode tomar de 20-50 segundos para subir. É irritante aplicar TDD com o Jboss Seam. Para falar a verdade, só para subir um EntityManager JPA com umas 100 entidades já toma aproximadamente 15 segundos. Isso é uma coisa para o pessoal do Hibernate pensar a respeito.

Esse “peso” para usar o Seam num ambiente “plain JSE” é uma das coisas que tinha me decepcionado muito no framework, isso foi bom pois me empurrou para estudar Rails/Ruby mais a fundo. Uma das coisas que encanta no Rails é a leveza. Tudo é leve! Desenvolver é leve, subir um WEBrick para desenvolvimento não toma mais que 2 segundos (é isso mesmo, 2 segundos). Você pode fazer o que quiser e não precisará reiniciar o servidor quase nunca. No PHP também é assim. Até no ASP é assim. Isso é chamado de development turnaround time. O turnaround do Ruby, PHP e outros citados é baixo. O Java causa uma cegueira técnica nesse sentido: qualquer coisinha que você mexa na implementação o Java chia que você tem que reiniciar o servidor para “pegar” as novas classes, anotações ou configuração que você fez. Nós nos acostumamos a perder tempo com isso e não reclamamos! Muito se discute, mas pouco se faz na prática.

Como o berço do Seam é a Jboss, não ví uma iniciativa por parte deles para melhorar isso (eles tem uma tendência a usar todos os outros produtos Jboss). Nesse ponto, usar o Jetty é algo que evolue pouco nas discussões da comunidade Seam e não consta em documentação. O Jetty é uma implementação leve de um servlet container que é muito usado para desenvolvimento (e também para produção). Olhando para o Seam, desde o início ví que teria uma maneira de usar o Jetty, mas não tive tempo de implementar isso. Vasculhei até achar um blog que dizia como fazer o Seam rodar no Jetty. Foi uma vitória, e além disso, este post ainda tinha esse projeto Seam Mavenizado (não sei se outras pessoas usam essa palavra).

A única pedra agora é que este projeto estava integrado com o Spring. Nada contra o Spring (fora o fato dele sofrer de configuration hell com XML, já falei que tenho nojo disso?), mas o ponto é que nossa aplicação Hotmotors seria simplesmente Seam. Bem, inicialmente coloquei o Maven para rodar dentro do Eclipse e depois, tratei de ver documentação e desplugar o Spring dessa implementação (e contornar alguns probleminhas do Jetty no Windows, meu MacBook Pro só vai chegar no final de agosto pra piorar minha vida miserável de programador).

Depois de tudo isso eu pude dormir mais contente: tenho uma referência do Seam Mavenizado e rodando no Jetty. Isso já melhorou muito o turnaround time em desenvolvimento. Creio que isso deixará mais alguns outros programadores felizes. Finalmente revivemos o Hotmotors! As próximas iterações vêm aí e nosso próximo passo é integrar as ferramentas de teste automatizado (provavelmente Fit e Selenium) e ver alternativas para o TDD. Aguardem!

Para baixar esse release, acesse a página do HotMotors.

O Seam é comparável com o Rails em produtividade? A comunidade Seam se posiciona como concorrente do Rails. Essa resposta eu não tenho ainda, mas minha idéia é reimplementar tudo em Rails para tirar essa dúvida.

Queria agradecer muito pela colaboração do Rafael para a comunidade. Valeu!

Obs. Veja mais informações de como rodar este release no blog do Rafael.

About The Author

rodrigoy

Instrutor e Consultor Sênior - ASPERCOM

Deixe sua opinião!

19 Comments

  • Muito bom o post e os comentários.

    Fiquei bastante interessado na integração Seam / Jetty / Maven. Irei tirar um tempinho para fazer alguns testes similares.

    Parabéns

  • Felipe Guerra

    Reply Reply 08/07/2008

    Parabéns, pelo Post!

    Eu gostaria de aprender mais sobre o SEAM, na realidade gostaria de participar de um projeto que utilizasse todas as tecnologias supra-citadas (exceto Ruby/Rails, por enquanto)…

    Um abraço!

  • Rodrigo Yoshima

    Reply Reply 08/07/2008

    Felipe, baixe o código e veja a aplicação exemplo Hotmotors. Isso será um bom começo. O Seam é bem fácil. Se você quiser tentar ajudar no projeto é só entrar em contato usando o fórum do projeto.

    Rodrigo Yoshima

  • Vinicius

    Reply Reply 08/07/2008

    Oi Rodrigo, já tentou rodar o Seam no Tomcat? Eu estou começando a usar o Seam agora com o Tomcat e foi bem fácil colocar para rodar e o tempo de subida total normalmente é abaixo de 15 segundos (com 5 entidades configuradas no persistence.xml, por enquanto…). Eu estou usando o Seam 2.0.2.

  • Rodrigo Yoshima

    Reply Reply 08/07/2008

    Sim, anteriormente eu rodava no Tomcat, mas mesmo assim quando o número de “Seam Components” sobe assim como os itens da JPA (entities, queries) esse tempo fica bem maior.

    O Jetty é mais leve. Um tomcat puro demora 12-15 segundos pra subir. Um Jetty é 5-8 segundos.

  • Rodrigo Yoshima

    Reply Reply 08/07/2008

    Sim João! Mas tem muitas limitações IMHO. Nem sequer um método de Entity é hotdeployable. Melhorou, mas não chega nem perto do Rails!

  • Rafael Rocha

    Reply Reply 12/07/2008

    Olá Rodrigo, parabéns pelo relato. Realmente interessante esta migração, no qual vi, outros projetos com a mesma motivação.

    O que no caso não entendi muito bem, seria, quanto ao fator irritante de desenvolver TDD no Jboss Seam?

  • Rodrigo Yoshima

    Reply Reply 12/07/2008

    Rafael, bem, vc deve saber que TDD não é só teste unitário. Quando usamos o FIT como exemplo para direcionar a implementação estamos fazendo TDD e pode ser um teste de integração. Para isso rodar, tudo pra dentro da sua Façade deve funcionar. No caso do Seam essa estratégia é dificultada pois os testes demoram muito para rodar pois o DI do Seam é pesado.

    Pra fazer testes unitários é OK pois é Pojo-Based, mas testes de integração são pesados com ele. Estou neste momento procurando uma maneira de fazer ele rodar sem o Embeddable Jboss, principalmente para o DI. Talvez eu mude de opinião.

  • Gilliard

    Reply Reply 22/07/2008

    Rodrigo, muito legal esse post. Também recomendo o Seam, é a forma mais agradável de se desenvolver para a Web que eu já experimentei também.
    Só dá uma olhada na parte onde voce cita algumas implementações de JSF, e onde voce diz que o Seam agora esta mais independente de implementação, pois o ADF Faces e o RichFaces não são implementações de JSF e sim um conjunto de componentes. E o JSF vai ser “cru” com qualquer implementação, seja a RI ou não, pois o que dá o “charme” visual nele são os componentes e não a implementação em si.
    Minha intenção não é ser chato, mas como o post é bacana, seria interessante deixar mais claro esses pontos, pois muita gente que não sabe dessas diferenças e lerão teu post podem se confudir.

  • BrunoPedroso

    Reply Reply 31/07/2008

    Rodrigo, também sofri muito pra fazer funcionar os testes de integração. Essa dependência do jboss-embeded é f*d@. Só de biblioteca vão mais de 60Mb!! A solução que achamos foi fazer testes de undade com JMock (caprichados) e testar integração apenas com JPA, criando um EntityManager apontando prum banco Hsql.

    Os testes de integração baseados no SeamTest só mesmo se vc partir de uma aplicação recém gerada com o Seam-gen. Tentamos incorporar ela num módulo puro EJB e foi uma dor de cabeça sem precedentes. Desistimos.

    Sem falar que aqueles objetos FacesRequest e ComponentTest são horrendos!

    Sinceramente, comparar o Seam com o Rails foi a coisa mais ridícula que já ouvi. Pura dor de cotovelo! (Ou então ignorância de quem realmente acha que o rails é só um monte de geradores de código.)

    Falta ao Seam o princípio mais fundamental de todos: simplicidade.

  • Rodrigo, muito bom o Post, ainda preciso avaliar o JBoss Seam pois não tive contato ainda.

    A única ressalva é sobre o Spring, se vc acha que tem muito XML é porque mexeu com versões antigas.

    Hoje há apenas um XML mínimo, apenas informando para mapear as anotações.

    A partir daí é tudo anotação.

    Para que qualquer classe passa a ser gerenciada pelo Spring e ainda ter suas dependências injetadas, veja o exemplo:
    @Component
    public class MinhaClasse {
    @Autowired
    public MinhaClasse(MinhaDependencia dependencia) {
    }

    @Autowired
    private OutraDependencia outraDependencia;

    @Autowired
    public void setMaisUmaDependencia(MaisUmaDependencia aaisUmaDependencia) {
    }
    }

    Espero ter contribuído…

  • Rodrigo Yoshima

    Reply Reply 16/07/2009

    Leonardo, de fato ainda não dei uma olhada nas últimas versões do Spring (está no meu backlog). De qualquer forma, muito obrigado pela contribuição aqui no Débito Técnico.

  • Ranieri Marinho de Souza

    Reply Reply 07/06/2010

    Ótimo post, suas informações são muito importantes, boa iniciativa

    Abraços,
    Ranieri Marinho de Souza
    SEGR – Segurança da Informação
    http://blog.segr.com.br

  • Luciano Bandeira

    Reply Reply 18/03/2012

    Olá Rodrigo,

    Estou tentando criar um projeto com Seam + Maven + Jetty, mas infelizmente o link que contemplava em conteúdo abre uma página em branco:

    http://kproject.gr/blog/?p=10

    Você possui alguma outra referência para esse conteúdo?

    Abraço.

    • Nossa Luciano, este post é de 4 anos atrás! Infelizmente parei de acompanhar o que acontece no mundo Seam. Abraços e desculpe não poder ajudar…

Leave A Response

* Denotes Required Field