Baseado na apresentação realizada no TDC 2010 em Florianópolis preparei um vídeo tutorial com narração desmonstrando o uso do Spring Roo gerando uma aplicação Web baseada no GWT (Google Web Toolkit) e deploy no GAE (Google App Engine).
Neste último final de semana aconteceu em Florianópolis a terceira edição do "The Developers Conference" promovido pela Globalcode e V.Office. O evento contou com mais de 500 inscrições, 6 trilhas de assuntos e 42 palestras. Eu tive a oportunidade ímpar de contribuir com 3 palestras de assuntos que gosto muito. Foi sensacional!
Agora resolvi publicar aqui os slides que utilizei durante as palestras. A primeira palestra foi sobre computação física com Arduino, Program-ME e a plataforma Java. Apresentei nesta palestra o conceito de computação física, hardware open source, além de mostrar o Arduino e o Program-ME (exemplos de hardware open source) como excelentes meios de realizar/experimentar/aprender computação física.
Na segunda palestra falei sobre a plataforma Spring através do tema "Spring 3: Uma plataforma além do framework". O objetivo era apresentar os vários frameworks, linguagens, ferramentas e portes do Spring que começam a estabelecer uma nova plataforma de desenvolvimento de aplicações Java. Na segunda parte desta palestra tratei das funcionalidades e características presentes na versão 3.0 do Spring Framework.
A terceira e última palestra foi para mostrar a ferramenta de geração de códigos chamada de Spring Roo. O objetivo desta palestra, além de definir e apresentar o Spring Roo, era de mostrar como gerar uma aplicação Web baseada em GWT (Google Web Toolkit) e o deploy no GAE (Google App Engine). A aplicação gerada e demonstrada durante a palestra está disponível no GAE: Scrum ROO Toys. Disponibilizei também o script para criação da aplicação demo através do ROO shell: ScroomToys.
Como sempre, não pude deixar de visitar um pub local para beber uma cervejinha artezanal da região. Daí, o happy hour para network etílico aconteceu no Chopp do Gus (sábado) e na Academia da Cerveja (domingo).
Definitivamente o modelo de componentização definido no Java EE 5 e 6 evoluiu e melhorou muito. Mas, sem dúvida muita dessa evolução se deve às pressões do Hibernate e Spring Framework. Estes dois últimos frameworks nasceram baseados no conceito de POJO, que nada mais é do que a concepção de um modelo de componentização baseado em classes Java sem as regras impostas pelo EJB (curioso, sem o EJB não existiria o Hibernate ou o Spring).
O Hibernate nasceu da idéia de promover um modelo de persistência mais simples que o proposto pelos EJBs do tipo Entity Beans definido na especificação EJB 2.x. Este foi o primeiro tipo de EJB a sofrer com a evasão de desenvolvedores com o surgimento deste framework e a conscientização sobre os problemas nos Entity Beans. A partir de um modelo baseado em JavaBeans e o uso do JDBC, o Hibernate usa a Reflection API para gerar os SQLs necessários para persistir o estado de beans em diversos banco de dados relacionais, além de definir o conceito de dialeto para resolver as diferenças de sintaxe do SQL usado entre as diferentes implementações de banco de dados. Ao resolver efetivamente a persistência dos objetos em banco de dados relacional, a morte dos entity beans estava decretada. Não foi atoa que no Java EE 5, numa tentativa de resgatar um padrão efetivo entre os desenvolvedores, surgiu o JPA usando os mesmos conceitos do Hibernate e promovendo uma API padrão com base em vários dos seus conceitos. A morte oficial dos entity beans no EJB!
Já o Spring Framework nasceu para combater os problemas resultantes das idéias usadas nas definições de outro tipo fundamental de componente do modelo proposto pelos EJBs: os Session Beans. Usando a mesma proposta do Hibernate, o Spring Framework adotou o JavaBean como modelo de componentização aliado aos serviços enterprise com o auxílio da programação orientada a aspectos (AOP). Assim, o Spring Framework decretou a morte dos EJBs do tipo Session Beans.
O Java EE 5, apesar de manter compatibilidade com as versões anteriores, aplica os mesmos conceitos usados pelo Hibernate e Spring Framework (JavaBeans e injeção de dependências, por exemplo), numa tentativa de evitar o êxodo de desenvolvedores da padronização. Dando o braço a torcer, o EJB 3 aplica um modelo baseado em POJOs (que ironia!) até eliminar a obrigatoriedade das interfaces home, remota e local (favorecendo uma modelagem OO efetiva, uso de herança, polimorfismo, design patterns e interfaces de negócios). Contudo, o Java EE 5 trouxe uma novidade que impôs uma evolução nos frameworks que foram os seus carrascos: O uso de anotações para eliminar configurações em XML. Poderíamos dizer que o EJB 3 não é uma mera cópia dos conceitos usados no Hibernate e Spring, mas também traz uma inovação ao fazer copy/paste/modify. Curioso foi ver que o Hibernate e o Spring foram obrigados a evoluir.
Contudo, podemos notar que o EJB 3.0 deixou de fora muitas das melhorias já presentes no Hibernate/Spring. No JPA 1.0 podemos notar a falta do mecanismo de "Criteria" e no EJB a falta de uma modularização mais flexível além dos tradicionais JAR, WAR e EAR. Tanto que agora no EJB 3.1 e JPA 2.0, várias melhorias tentam eliminar as deficiências reclamadas pela comunidade que já não existiam em versões antigas do Hibernate e Spring Framework.
Muitos se questionam hoje se deveriam usar o Hibernate e o Spring considerando as evoluções do EJB 3 e JPA estabelecidas pelo Java EE 5 e 6. Acredito que pela simplicidade e padronização proporcionados no Java EE deveríamos usar o EJB e JPA. Mas, considerando as limitações deveríamos levar em consideração o uso do Hibernate e do Spring Framework. Apesar de não serem frameworks padrões, e por isso mesmo, não estão limitados às imposições políticas de vários interesses, estes frameworks têm a liberdade de evoluir e experimentar idéias inviáveis até o momento no Java EE, além de propiciar a integração com outros frameworks que também não são padrões e são legados ainda em uso pela comunidade (por exemplo: Struts, iText, Quartz, etc). Muitos conhecem as vantagens de usar o Hibernate diretamente em detrimento das limitações do JPA. No Spring temos a modularização através de OSGi e o uso pleno do AOP como parte da modelagem dos componentes de negócios das aplicações enterprise.
Apesar das melhorias amplamente comentadas no Java EE 6 através do EJB 3.1 e JPA 2.0, ainda é evidente muitas das vantagens do uso direto do Hibernate e do Spring Framework.
No TDC2009 realizado pela Globalcode em São Paulo eu apresentei um Lightning Talk sobre um problema específico de performance em aplicações Web com JPA e uma possível solução usando o Spring Web Flow.
Num período de 15 minutos, os slides a seguir foram apresentados e seguidos de alguns vídeos de demonstração de uma aplicação Web em execução.
Nesta apresentação foi dito que temos encontrado problemas de performance em aplicações Web que utilizam as tecnologias JSF + JPA + Ajax quando precisamos gerenciar um contexto de persistência (EntityManager). Este problemas se manifestam quando aplicamos uma resposta errada para a pergunta: Como gerenciar o contexto de persistência numa aplicação Web?
Se as aplicações não usam Ajax e limitam-se ao modelo orientado a requisições, a solução mais comum é o uso do design pattern chamado "Open Session In View Filter". Através deste design pattern, um contexto de persistência novo é aberto no início de uma requisição Web através de um filtro e fechado ao final desta requisição pelo mesmo filtro. Durante o processamento da requisição, as entidades persistente carregadas não geram erros (LazyInitializationException, por exemplo) porque o contexto de persistência ainda esta aberto. Mas se estas entidades são armazenadas no escopo de sessão, muitos erros podem acontecer quando estes objetos são usados numa outra requisição. Para resolver estes erros, muitos desenvolvedores utilizam o artifício de navegar nas associações, ou reinserir (merge) as entidades no novo contexto de persistência ou recarregar/salvar várias vezes estas entidades. Estas implementações degradam consideravelmente a performance da aplicação, além de inviabilizar o uso efetivo de cache de objetos, normalmente encontrado nas implementações de JPA.
O problema de performance é agravado quando a aplicação usa intensamente o modelo orientado a eventos. Este modelo é a tendência natural dos sistemas Web 2.0, principalmente pela mudança de paradigma de desenvolvimento Web proporcionado pelo JSF e Ajax. Ao longo de uma sessão de uso da aplicação e acesso às telas, muitas requisições assíncronas são enviadas para a aplicação no lado do servidor. A cada requisição, um novo contexto de persistência é aberto e fechado se o design pattern sugerido anteriormente é aplicado. Portanto, a resposta para a primeira pergunta não é o uso deste design pattern e muito menos os "workarounds" para os efeitos colaterais resultantes do uso deste padrão no novo modelo orientado a eventos.
Uma solução proposta e aplicada na prática está baseada no uso do conceito de escopo de conversação. Um escopo numa aplicação web define uma visibilidade e um tempo de vida dos objetos armazenados no servidor. Atualmente, um contâiner Web implementa os escopos de página, requisição, sessão e aplicação. O JSF 1.2 usa estes mesmos escopos e o JSF 2.0 adiciona os escopos View e Custom (que permite a criação de novos escopos). Já o Spring Framework disponibiliza os escopos singleton, prototype, request e session. Contudo, nenhum destes escopos tem a visibilidade por usuário e, ao mesmo tempo, o tempo de vida entre uma requisição e uma sessão como requerido pelo escopo de conversação. Mas, os frameworks Spring Web Flow, Seam Framework e Apache MyFaces Orchestra implementam este escopo e permitem o gerenciamento automático de um contexto de persistência neste escopo.
Então, uma solução efetiva para os problemas de performance e erros numa aplicação que usa JPA e o modelo orientado a eventos é o uso do escopo de conversação implementado por um dos frameworks sugeridos. Na aplicação web a ser demonstrada foi escolhido o Spring Web Flow por ser um dos produtos do Spring Portifolio, utilizar as mesmas boas práticas do Spring Framework, ter um baixo risco de se tornar um produto descontinuado e ser fácil de integrar numa arquitetura já baseada no Spring Framework + JSF + JPA.
O uso do Spring Web Flow (SWF) permitiu o fim dos erros de LazyInitializationException, o uso efetivo de cache das entidades persistentes, redução da quantidade de objetos na sessão, suporte a paginação, filtro e ordenação já na camada de apresentação com uma forte integração com o mecanismo de persistência JPA. Contudo, o SWF na versão atual (v.2) ainda requer o uso de XML para determinar quando uma conversação é iniciada e quando será destruída. Além de ser necessário realizar um "merge" das entidades ao final da conversação para atualizar na base de dados as possíveis alterações em memória.
Os vídeos de demonstração a seguir ilustram o funcionamento da uma aplicação web realizada através de uma implementação de referência que usa Spring Framework 2.5, JSF 1.2, JPA 1.0, Richfaces 3.3, Facelets 1.1.15, Spring Web Flow 2.0, Hibernate (JPA Provider) e MySQL 5.0.
TDC2009 Video Demo 1
TDC2009 Video Demo 2
TDC2009 Video Demo 3
Este último vídeo demonstra o poder do Lazy Loading a medida que os painéis são abertos e fechados. Como o contexto de persistência permanece disponível durante o período do escopo de conversação aberto, tornou-se possível carregar da base de dados somente alguns objetos e depois os outros objetos a medida que os painéis são expandidos. Os logs apresentados através do NetBeans neste vídeo ilustram a carga sob demanda dos objetos. Também ilustra o uso do cache nos objetos já carregados quando painéis que já foram expandidos são abertos novamente. Neste caso, nenhum log de consulta ao banco de dados aparece no NetBeans.
Finalmente consegui ter uma cópia da edição 65 da revista Java Magazine. Já fazem 10 dias que tive notícias de colegas que assinam a revista dizendo que já receberam. Mas, até hoje ainda não está nas bancas!
Estava ancioso para por as mãos nesta edição para ver como ficou o artigo que escrevi sobre o Spring Framework.
O artigo descreve uma aplicação simples e completa usando Spring Framework, JSF e JPA. Através de configurações em XML e anotações, os serviços de transação e persistência são ilustrados no desenvolvimento de DAOs e componentes de negócios gerenciados pelo Spring e acessados através de telas na web com JSF. As principais funcionalidades do Spring Framework e as partes que compõem o Spring Portfólio também são descritas neste artigo.
Uma aplicação completa para web é presentada, desde a modelagem simples de casos de uso até códigos em classes Java, interfaces e diagramas UML de classes e sequência, mostrando como usar o Spring Framwork para simplificar o desenvolvimento de aplicações.
Nem tudo é perfeito ... Por mais que revisemos o artigo e que exista um editor extremamente criterioso durante a revisão, sempre sobram alguns erros. Para a tranquilidade de todos, não são erros técnicos, mas sim, pequenos erros ortográficos e posicionamento de figuras e listagens em páginas diferente de onde são referênciados.
Aqui estão algumas erratas que encontei após uma nova leitura do texto através da revista:
Pág. 54, 1a. coluna, 3o. parágrafo: A figura 1 citada aparece na página 53 exigindo do leitor a mudança de página;
Pág. 60, 1a coluna, 3o parágrafo: Aparece a palavra "componentes" onde deveria ser "componente" resultando em: "Em alguns casos não é possível configurar um componente gerenciado pelo Spring através de anotações";
Pág 60, 1a coluna, 3o e 4o parágrafos: O início do 4o parágrafo repete a mesma informação apresentada no final do 3o. parágrafo;
Pág. 61, 1a coluna, 1o parágrafo: Uma das anotações do Spring está grafada com um s a mais: @Respository, e o certo seria: @Repository;
Pág. 61, 1a coluna, 4o parágrafo: A listagem 5 é referenciada nesta página e o conteúdo desta listagem está na página 62, exigindo do leitor a mudança de página.
Pág 63, 1a coluna: As listagens 7 e 8 são citadas nesta página, mas o conteúdo destas listagens estão na página 64, exigindo do leitor a mudança de página.
Como podem verificar não são problemas sérios. Alguns são inevitáveis por conta da necessidade de diagramação e outros foram descuido do escritor que vos escreve :)
De qualquer maneira, o artigo ficou muito bom e muito bem apresentado na Java Magazine. Está bem diagramado e com o conteúdo na medida certa. Contudo, para não estender o tamanho do texto, foi necessário colocar somente os códigos fontes e diagramas necessários para o entendimento do assunto apresentado. Em alguns códigos, trechos considerados irrelevantes foram omitidos sem prejuízo para a compreenção. Mas, a DevMedia disponibilizou para download o projeto Eclipse completo que fiz para a aplicação demonstrada no artigo. Quem se interessar pode fazer o download clicando aqui. O zip baixado tem um arquivo "leiame.txt" com os pré-requisitos e passos para instalação.
Show de bola foi a dobradinha com o artigo nesta mesma edição da Java Magazine que traz a tradução da entrevista com o Rod Johnson (criador do Spring e fundador da SpringSource) realizada no JavaOne2008. Eu ajudei a escrever algumas perguntas que foram realizadas pela Yara Senger (Globalcode) e Melissa Villela (Globalcode) durante o evento. Não perdi a oportunidade de questionar os seguintes pontos:
A plataforma Spring pretende ser uma alternativa viável à própria plataforma Java EE, e não apenas uma alternativa a EJB?
Depois do EJB 3 no Java EE 5, porque deveríamos continuar usando Spring nas aplicações enterprise?
Não foi surpresa ouvir uma resposta positiva para a primeira pergunta e um bom argumento para continuarmos com o Spring. Tem um bom tempo que percebo a intenção do Spring de ser um forte concorrente da plataforma Java EE e isto motivou a minha pergunta. Ele também cita que mesmo com as melhorias no Java EE 5, o EJB 3 ainda continua contendo grande parte do legado "por baixo dos panos" e que diversas funcionalidades continuam limitadas e falham em atingir os objetivos propostos por algumas tecnologias, como por exemplo AOP! Com estas respostas ficou claro para mim que não adianta mais ficar comparando Spring com EJB. O Spring Framework é apenas uma parte da plataforma. Já temos um servidor de aplicações Spring com suporte fantástico a OSGi que implementará no futuro alguns dos profiles especificados para o Java EE 6. Também não podemos esquecer das diversas bibliotecas e frameworks que compõem o chamado Spring Portfólio. Agora temos que comparar as plataformas para decidirmos qual arquitetura implantar no nosso sistema corporativo: Spring Platform versus Java EE Platform!
Por fim, comento no artigo os passos necessários para se tornar um profissional certificado em Spring Framework (S2CP - SpringSource Certified Professional). No início deste ano fiz a prova de certificação. Depois conto os detalhes em outro post.
Quem quiser comentar estes artigos da edição 65 da Java magazine é só mandar para blog@spock.com.br ou escrever comentários para este post.
Com o recente lançamento do site InfoQ no Brasil com artigos traduzidos para o português, alguns dasavisados acabaram acreditando.
Os 20 melhores artigos de 2008 da InfoQ em inglês foram traduzidos para o português e um deles incluiu a pegadinha de primeiro de abril realizada pelo Rod Johnson (criador do Spring Framework e CEO da SpringSource).
Vejam video abaixo.
Muitos caíram no erro pelo site não ter divulgado inicialmente que era uma piada de primeiro de abril. Mas, alguns leitores espertos perceberam o deslize e avisaram o site para correção. Links para os artigos na InfoQ:
Ele participou de uma palestra onde um integrante da equipe de desenvolvimento do site contou as experiências de uso do Spring. Interessante foram alguns números apresentados pelo Matt: 2 data centers (~600 máquinas), ~100 serviços (componentes), ~30-40 interfaces, ~1000 arquivos de configuração do Spring e atualmente 30 milhões de usuários com a taxa de crescimento de 1 milhão a cada 2-3 semanas! Uau! Tudo rodando num cluster de ~600 máquinas com o Tomcat! Isso mesmo, TOMCAT! Agora eles querem evoluir a solução para usar modularização através de OSGi e Spring Dynamic Modules for OSGi (que facilita tremendamente o uso de OSGi). Tudo isso para prover hotdeploy e múltiplas versões dos componentes, além da distribuição automatizada no ambiente em cluster.
Legal também foi a frase que vi no blog do pessoal do LinkedIn: LinkedIn is 99% Java but 100% Mac. Nos outros 1% estão usando C++, Ruby on Rails e Groovy/Grails.
Contudo, fiquei muito espantando quando soube que tem alguns poucos loucos querendo remover o Spring Framework de uma aplicação funcionando muito bem em produção simplesmente por ter birra do Spring e birra de frameworks. Se pelo menos estivessem substituíndo por EJB 3 ou JBoss Seam com um servidor de aplicações decente como o JBoss Application Server, aí eu aceitaria. Mas a insanidade leva a quererem usar servlets puro ou talvez Struts puro. Vai entender!
Quanto mais pesquiso sobre o Spring Framework vejo que tornou-se um padrão de fato. Não precisa ir muito longe em cliques ou páginas de resultado da busca no Google para ver muitos outros casos de sucesso de arquiteturas funcionando muito bem com o Spring Framework.
No JustJava2008 apresentei uma palestra com o resultado da integração destes dois frameworks. Nesta apresentação ilustrei os passos necessários para configurar uma aplicação Web para ter os dois frameworks funcionando em conjunto. Apresentei as características do Seam que o qualificam para o gerenciamento da camada de apresentação (View e Controller) numa arquitetura MVC na Web com Ajax e as características do Spring que o qualificam para o gerenciamento da camada model com integração com os serviços EE (transação, segurança, logging, remoting, pooling, etc). Claro que estes frameworks são mais abrangentes do que o discutido na palestra.
Na apresentação pude discutir os problemas encontrados nesta integração considerando as diferenças destes frameworks que resultam em alguns curto-circuitos. Contudo, a integração até que funciona bem! Mas, tem que ficar atento com estes curtos.
A seguir estão os slides para a comunidade. Then, enjoy it!
Na palestra que realizei no último TDC junto com o Ricardo Jun, colocamos dois slides na apresentação que chamamos de Ecossistema Spring. Estes slides foram muito apreciados por várias pessoas que viram a apresentação. Como tivemos muitos feedbacks positivos sobre estes slides, gostaria de compartilhar com vocês as imagens utilizadas para representar o ecossistema.
A primeira imagem ilustra as integrações com diversos fremeworks e serviços Java EE que o Spring Framework proporciona. Estas integrações estão todas disponíveis num único JAR (spring.jar).
Os elementos folha neste diagrama representam as tecnologias ou frameworks que o Spring Framework permite integração sem reinventar a roda. Em alguns casos o Spring Framework traz uma implementação própria como, por exemplo, o Spring MVC e Spring JDBC (templates e datasources). A seguir alguns destas caixinhas são detalhadas:
Core: Implementa o contêiner IoC;
Web: Recursos para implementação de aplicações Web: integração com frameworks MVC, implementação própria de MVC e integração com tecnologias de visualização;
DAO: Classes utilitárias para desenvolvimento de DAO's com JDBC e gerenciamento de transações;
AOP: Disponibiliza o conceito de aspectos via AOP Alliance e AspectJ para integrar os POJO's com os serviços enterprise;
ORM: Implementa o suporte para integração com frameworks de mapeamento objeto/relacional;
Java EE: Classes utilitárias para integração com serviços Java EE;
Remoting: Expõe os métodos dos POJO's para invocação remota.
A próxima imagem ilustra o que é chamado de Spring Portfolio. Este portfolio é composto por diversos projetos que complementam o Spring Framework e utilizam as mesmas boas práticas sugeridas pelo Spring. Neste portfolio, pelo menos os seguintes recursos são disponibilizados: Segurança, integração com outros frameworks, processos batch, OSGi e ferramentas de desenvolvimento.
Neste diagrama, os elementos vinculados ao Spring Framework são pacotes distribuídos separadamente e disponíveis em um ou mais arquivos JAR. Cada produto tem uma página própria de documentação e download que são acessíveis na página Spring Projects. A seguir alguns destas caixinhas são detalhadas:
Spring Security: Segurança declarativa via XML ou anotações com suporte a AOP e integração com tecnologias de segurança: JAAS, LDAP, DAO, OpenID, CAS, X509, Windows NTLM;
Spring Web Service: Suporte a Web Services a partir da definição do XML Schema e WSDL (Data Contract e Service Contract);
Spring Web Flow: Suporte ao controle de fluxo de navegação Web, integração com JSF, conversação e Ajax;
Dynamic Modules for OSGi: Simplifica o uso da API OSGi através do Spring com POJO's;
Spring Modules: Projeto guarda-chuva que implementa a integração com diversos outros frameworks e ferramentas;
Spring Rich Client: Recursos para desenvolvimento desktop com Swing e Spring;
Spring JavaConfig: Suporte a configuração dos beans programaticamente sem usar XML ou anotações;
Spring LDAP: Classes utilitárias para interação com um serviço de Lightweight Directory Access Protocol (LDAP);
Spring Integration: Implementa o suporte para integração de sistemas via mensagens (EAI e Enterprise Integration Patterns);
Spring Batch: Suporte a execução de processos em batch de longa duração;
Spring IDE: Plugin para incrementar produtividade durante o desenvolvimento com o Eclipse;
Spring BeanDoc: Ferramenta para gerar documentação semelhante ao Javadoc;
Spring .NET: Porte de parte do Spring Framework para desenvolvimento de aplicações .NET!
Alguns destes produtos estão consolidados e maduros, outros estão em desenvolvimento. Portanto, na hora de usar num projeto importante ou em produção, será necessário verificar o status atual do projeto correspondente.
Veja a seguir os slide usados na palestra.
Todas os slides das palestras do evento TDC2008 estão disponíveis para download no site da Globalcode.
Para fechar este post, algumas frases que definem o Spring Framework:
Um framework de código aberto e uso livre, sob licença Apache, criado por Rod Johnson;
Implementa um contêiner de injeção de dependências (DI) e inversão de controle (IoC);
Um framework para programação orientada a aspectos (AOP);
Um framework para integração de aplicações com serviços Java EE;
Um framework para integração com outros frameworks que implementam serviços enterprise;