quarta-feira, 19 de fevereiro de 2014

É hora de balançar a árvore!


Como estarão suas aplicações Java daqui a 5 anos? Será que o seu lindo framework Java (TM) estará atualizado? Será que vai acomodar bem as inovações? Será que sua arquitetura é flexível o suficiente para encarar a crescente ubiquidade de informações? Como Arquiteto de Software e autor de vários livros sobre Java, acho que chegou a hora de fazer um "mea culpa" e repensar, com vocês, a arquitetura do que estamos criando agora, de modo a evitarmos "legados" no futuro.







Cuspindo na xícara que usou?

Não. Não estou "cuspindo" na xícara que usei, durante todos esses anos. Java (TM) é e sempre foi a minha linguagem de programação preferida, e eu defendo muitos dos seus conceitos. A questão é que devemos ser objetivos nas avaliações que fazemos, especialmente se forem relacionadas com o futuro das arquiteturas corporativas.

Continuo considerando a plataforma Java (TM), incluindo seus mais populares frameworks, como: Java EE, Hibernate, JSF, Spring etc, como sendo robusta, segura, estável e escalável para aplicações corporativas.

Mas eu andava meio incomodado com a alta complexidade acidental do ecossistema Java (TM), em comparação com alguns frameworks Web mais leves. E, como estou desenvolvendo o jQana Control, obviamente, estava desenhando uma arquitetura baseada em JAX-WS, para permitir a atualização do Banco e consulta. Então, pensei: "por que não usar REST? E por que não usar JSON?" e fui mudando, criando provas de conceito etc.

Também estava um pouco frustrado com os problemas de compatibilidade com navegadores, que algumas bibliotecas de componentes JSF apresentam... Especialmente se pensarmos em programação móvel. E eu estava buscando novas soluções, que desacoplassem um pouco a renderização, dando mais liberdade para usar ao máximo o HTML 5 e o CSS 3.

Diante dessa minha frustração com alguns elementos do ecossistema Java (TM), pensei em escrever um artigo sobre uma nova visão de arquiteturas corporativas, que fosse mais leve e desacoplada.

Foi então que o meu amigo Gunisalvo postou uma observação do Technology Radar, de Janeiro de 2014, editado pela ThoughtWorks (Martin Fowler), recomendando evitar o uso do JSF em aplicações. Então, tive uma epifania (Não! Não foi no banheiro!) :

Estamos criando um legado monstruoso para o futuro! Temos que "balançar" a árvore!

Eis o comentário do Technology Radar, que considerei muito válido e pertinente (traduzido por mim):
"Nós continuamos a ver as equipes enfrentarem problemas usando JSF - JavaServer Faces - e estamos recomendando evitar esta tecnologia. As equipes parecem escolher JSF, porque é um padrão J2EE, sem realmente avaliar se o modelo de programação lhes convém. Achamos que JSF é falho porque tenta abstrair HTML, CSS e HTTP, exatamente o inverso do que os frameworks web modernos fazem. JSF (assim como os webforms, do ASP.NET) tenta criar manutenção de estado em cima do protocolo HTTP, que é inerentemente "stateless", e acaba causando uma série de problemas envolvendo estado do lado do servidor compartilhado. Estamos conscientes das melhorias no JSF 2.0, mas acho que o modelo é fundamentalmente quebrado. Recomendamos às equipes usarem frameworks simples e abraçarem e compreenderem as tecnologias web, incluindo HTTP, HTML e CSS."
Uau! Foi então que pensei: "Caraca! E as milhares de aplicações Java EE/JSF que estão sendo criadas agora? E os problemas que estão acontecendo? Como isso tudo estará daqui a uns 5 anos?

Eu me lembrei de uma aplicação JSP / Struts, desenvolvida no início dos anos 2000, à qual eu tive que dar suporte. Eu disse: "Isso é legado, não se usa mais... Java EE 1.3? Francamente..." Cara, se aplicações JSP com Struts são consideradas "legado", o que dizer dos "monstros" que criamos atualmente?

E então, na minha cabeça, começaram a rodar imagens e nomes de outras coisas que estamos "chuchando" em nossas aplicações, e que também representam um futuro legado. Tudo o que estamos fazendo é criar um baita problema para nós e para nossos Clientes.

Por que?

Sinto muito, mas epifanias são assim mesmo... Vou tentar explicar onde quero chegar, contando uma historinha "pra boi dormir". Eu era feliz e não sabia! Era um desenvolvedor Microsoft, certificado (MCSD e MCSE), que usava soluções como o MS Visual Basic 6, ASP 3.0, MS SQL Server, MS IIS e COM+, feliz da vida. Quando o .NET começou a ser badalado, eu tinha acabado de criar uma bela aplicação, que usava o COM+, o MSMQ e o Microsoft Transaction Server, de forma linda!

Eu também tinha publicado um livro sobre desenvolvimento com MS Visual Basic 6 e estava escrevendo outro, sobre a plataforma corporativa de aplicações, baseada em COM+. 

E veio o .NET, para acabar com tudo! A Microsoft havia revolucionado TUDO! O VB.NET era radicalmente diferente do VB 6.0 e, totalmente incompatível com ele. E, ainda por cima, criaram uma nova linguagem: o C#! E o .NET framework estava substituindo tudo, toda a plataforma corporativa que eu estava acostumado a trabalhar! Até o meu querido ASP do coração! (escrevi um livro famoso sobre ele).

A moral da história é: Nunca devemos "submergir" totalmente em uma única plataforma! A Microsoft, diante do crescimento da plataforma Java (TM), resolveu revolucionar a sua plataforma de aplicações corporativas, criando o .NET Framework e mudando toda a sua visão de componentes, de modo a enfrentar a concorrência do Mercado. E, quem estava "submerso" dentro do mundo VB 6 / ASP 3.0 / COM+, acabou "sem ar"!

É mais ou menos isso que eu vejo acontecendo agora mesmo, com quem está "submerso" no ecossistema Java (TM)!

Eu sei que, ao contrário do MS Visual Studio, a plataforma Java (TM) não é comandada só pela Oracle... Sei que existe toda uma "oligarquia", reunida no JCP - Java Community Process, que comanda os rumos da Plataforma, e que o risco de uma ruptura é muito remoto, mas existe outro problema, que eu chamo de "Acoplamento de Plataforma", ou seja, você pode criar soluções robustas, flexíveis e de baixo acoplamento, desde que sejam em Java (TM).

O professor Robert Antony tem uma frase que explica muito o que é "Acoplamento de Plataforma":
"If you find a good solution and become attached to it, the solution may become your next problem."
Traduzindo: Se você encontrar uma solução boa, e se tornar muito ligado a ela, então ela será o seu próximo problema.

Acoplamento de Plataforma: O seu mais novo antipattern

Uma das coisas que eu venho pregando há muito tempo sobre qualidade de software, é que devemos criar aplicações compostas por elementos de baixo acoplamento. Realmente, buscamos usar abstrações e protocolos para desacoplar os elementos e as camadas do nosso software, aumentando a manutenibilidade, testabilidade e flexibilidade dos nossos aplicativos.

Só que existe um tipo de acoplamento, que insistimos em manter, talvez por desconhecimento ou por comprometimento. Afinal, já estamos tão "submersos" no "mar" de componentes e frameworks, que sequer tentamos pensar "fora da caixa". Esse é o acoplamento de plataforma: Novas soluções só funcionam se forem na mesma plataforma.

Podemos até tentar criar componentes usando outra linguagem, como o Groovy, por exemplo, mas, ainda assim, estaremos usando a mesma plataforma.

Veja bem, apesar de tentarmos tomar todo cuidado para criar soluções flexíveis, de baixo acoplamento e de baixa dívida técnica, continuamos criando soluções usando uma única plataforma. Logo, continuamos a "submergir" cada vez mais no "mar" formado pelo ecossistema Java (TM).

E isso é um problema?

Pode ser que agora, nesse momento, não seja um problema. Mas precisamos pensar no futuro, afinal de contas, temos que aumentar o "Prazo de Validade" dos softwares que criamos, de modo a aumentar o ROI dos nossos Clientes.

Lembram do exemplo da aplicação "legada" em JSP / Struts? Pois é... Não é tão antiga assim, e as tecnologias ainda são usadas por muita gente. Só que os padrões mudaram e as pessoas também. E o Ecossistema evolui segundo o seu próprio ritmo, alheio às novidades do Mercado.

O desenvolvedor Java é conservador

Parece até um contrassenso, não? Mas o desenvolvedor Java, em especial aquele que desenvolve a plataforma Java (TM), é muito conservador, no sentido de perpetuar o uso da plataforma, não admitindo a hipótese de integrar outras plataformas para realizar o serviço.

O desenvolvedor Java é um "criador de frameworks". Esse sempre foi o pensamento e a orientação de todos os desenvolvedores dessa plataforma, desde os mais iniciantes até os mais experientes.

Um desenvolvedor Java não cria um programa para resolver um problema... Ele cria um framework para resolver todos os problemas semelhantes, e quer disseminar seu framework junto à comunidade.

Todo desenvolvedor iniciante em Java quer criar um framework de desenvolvimento em Java! Conheço mais de um deles! E, como temos muitos "Gerentes COBOL", que acabam se maravilhando com a ideia, vemos montes de frameworks idiotas, que somos forçados a usar, que acabam funcionando como âncoras para manter-nos mais e mais submersos no "mar".

Frameworks são como castelos, ou melhor: Catedrais, como no excelente livro de Eric Steven Raymond The Cathedral and The Baazar, sobre o processo de desenvolvimento Linux. E, sejam Castelos ou Catedrais, os frameworks ajudam a fechar mais ainda as "muralhas" do ecossistema, garantindo que os usuários continuem "submersos" na plataforma.

Resistance is futile

"We are the Borg. Your biological and technological distinctiveness will be added to our own. Resistance is futile."
Traduzindo: "Nós somos os Borg. Sua singularidade biológica e tecnológica serão adicionadas à nossa. Resistir é inútil."

Os Borgs são seres cibernéticos, que aparecem no universo Sci-fi de Jornada nas Estrelas. São inimigos formidáveis, que quase acabam com a Federação. Eles usam o conceito de "assimilar" para evoluir, ou seja, assimilam as formas de vida, injetando nanobots que as transformam em zangões da coletividade Borg, assim como assimilam tecnologias e as adaptam segundo sua própria versão e para seu próprio uso.

É mais ou menos assim que funciona o ecossistema Java (TM). As novas tecnologias são "assimiladas" e embutidas em frameworks (que ficam dentro de frameworks, que ficam dentro de frameworks...), e acabam se tornando parte da plataforma. Assim aconteceu com o conceito de SOAP, que era para ser algo leve e interoperável, assim aconteceu com o XML e com várias outras tecnologias.

Com o JSF - Javaserver Faces não foi diferente... De modo a simplificar a conexão de aplicações corporativas ao ambiente Web, mantendo o isolamento e a "submersão" dos desenvolvedores, o framework encapsula e abstrai quase totalmente as tecnologias que estão "por baixo dos panos", como: HTML, CSS, HTTP e Javascript. É claro que isto tem algumas vantagens, pois, ao isolar o desenvolvedor corporativo, permite reaproveitar mão de obra e tornar "web-enabled" as aplicações tradicionais Java, com um mínimo de investimento.

Porém, como o Technology Radar bem frisou: "JSF é falho porque tenta abstrair HTML, CSS e HTTP, exatamente o inverso do que os frameworks web modernos fazem". E isso tem um preço: Compatibilidade!

As tecnologias "assimiladas" pelo JSF não ficaram paradas! Elas evoluíram, assim como surgiram novas tecnologias e versões, e, como todo framework, a base de componentes JSF não acompanha o ritmo frenético das novidades (Web 3.0, Web 4.0 etc). Várias inovações do HTML 5, do CSS 3, do Javascript e de protocolos, como o SPDY e o HTTP 2.0, estão aí para desafiar o "Castelo" dos componentes JSF, tornando a vida dos desenvolvedores Web mais difícil.

Lendo algumas das lições de Eric Steven Raymond The Cathedral and The Baazar, vemos uma que se associa muito bem com o que o Tecnology Radar apontou:
"Often, the most striking and innovative solutions come from realizing that your concept of the problem was wrong"
Traduzindo: "Muitas vezes, as soluções mais impressionantes e inovadoras surgem ao se perceber que o seu conceito do problema estava errado". E é isso mesmo! Ao invés de "abstrair", seria mais interessante pensar em interoperar com o HTML, o CSS e o Javascript, ou com outras plataformas Web, desacoplando os aspectos da aplicação corporativa e mantendo os desenvolvedores mais antenados nas mudanças tecnológicas.

A ubiquidade da informação está forçando as aplicações a coexistirem com plataformas e linguagens completamente diferentes, portanto, fora do ecossistema Java (TM). Não dá para pensar em uma aplicação moderna sem pensar em: Web Services RESTful, Ajax, HTML 5 e plataforma Mobile.

Ao tentar assimilar e abstrair todas as tecnologias, o ecossistema Java (TM) acaba se tornando de alta complexidade acidental, forçando seus desenvolvedores a ficarem tão envolvidos com a compreensão dos frameworks, que eles passam a ser um fim, e não um meio para alcançar o objetivo.

O mundo está mudando

Os "sinais de fumaça" já estão aparecendo no horizonte, na forma de conselhos, como o do Technology Radar, artigos e estatísticas.

Vamos ver, para as principais tecnologias do ecossistema, o que está acontecendo e quais são as tendências.

JSF / Java EE

Realmente, o JSF não está conseguindo ser tão popular quanto o JSP foi no passado. Além do artigo da empresa de Martin Fowler, temos alguns indicadores que sua popularidade e atualização estão caindo.

Veja por exemplo essa estatística do site Hot Frameworks, que pesquisa a popularidade dos frameworks de aplicação de acordo com o GitHub e o StackOverflow:



Vemos que a lista de popularidade é:

  1. ASP.NET;
  2. Ruby on Rails;
  3. ASP.NET MVC;
  4. Django;
  5. AngularJS;
E o JSF vem em décimo quinto lugar. 

E existem várias referências, como este excelente artigo de Brian O' Neill, na DZone: "J2EE is Dead: Long-live Javascript Backed by JSON Services ". Em resumo, ele acredita que a camada de apresentação vai se separar totalmente do mundo Java EE, trocando páginas JSF, hospedadas em Containers Java EE, por páginas HTML 5 simples, que usam componentes Javascript para consumir RESTful Web Services baseados em JSON. E tem mais, ele acredita que até mesmo os componentes corporativos, representados por Web Services Jax-WS ou componentes EJB, moverá para fora do mundo Java EE, através de soluções Fuse, Mule ou Camel. Implementações de ESB modernas, que podem agregar componentes e tecnologias fora do ecossistema Java EE. 

Isso sem falar em novas soluções para aplicações distribuídas, como o Node.js, um framework baseado em Javascript para processar aplicações Servidoras, que está revolucionando o desenvolvimento de aplicações corporativas (veja o artigo Node.js is taking over the Enterprise – whether you like it or not), e não foi "assimilado" pelo ecossistema. 

O Blog Shine fez um "benchmark" entre o Java EE e o Node.js, ambos lendo um documento JSON a partir de um Banco no-sql (CoachDB), e adivinhem quem ganhou em performance? O Node.js! Veja o artigo AQUI

E temos que falar também nos outros frameworks, muito usados em aplicações Java EE, como o Spring, por exemplo. Apesar de útil, agrega grande complexidade acidental e reforça o conceito de "Acoplamento de Plataforma". 

XML e SOAP

Ontem mesmo, um amigo veio falar sobre um Web Service que vai criar, obviamente Jax-WS usando SOAP e XML. E eu fiquei me perguntando "por que? "

Eu NUNCA gostei muito do XML, e a implementação SOAP no ecossistema Java é de altíssima complexidade acidental, tornando algo simples em uma verdadeira "Catedral". 

Igualmente, ODEIO SOAP! Não o SOAP original, mas no que ele se tornou. Em suas origens, "SOAP" significava: Simple Object Access Protocol, e foi criado para o mundo do saudoso MS Visual Basic, como uma forma simples e desacoplada de invocar métodos em objetos remotos, trocando informações de modo padronizado, usando XML.

XML é verboso, difícil de ler, difícil de analisar e custoso para processar. É claro que o ecossistema Java (TM) se incumbiu de "assimilar" o XML e embuti-lo no framework JAXB - Java Architecture for XML Binding, que permite ler arquivos XML e gerar instâncias de classes Java, ou fazer o contrário. Só que, como todo framework do ecossistema, é complexo e mantém o vínculo com a plataforma.

Ambos, o XML e o SOAP, são difíceis de usar sem o auxílio de frameworks. Já tentou criar uma invocação de Web Service SOAP usando Javascript? 

E não sou só eu que reclamo... Veja só a estatística de uso do ProgrammableWeb, um site respeitavel sobre Web Services e Mashups, que eu costumo usar muito: 

O REST (70%) aparece como o primeiro colocado entre as APIs de Web Services, ficando o SOAP com 21%. 

No ProgrammableWeb tem ainda o excelente artigo de Adam DuVander: "1 in 5 APIs Say “Bye XML”", que, apesar de ser de 2011, apresenta bem a tendência da substituição do XML pelo JSON


Hibernate e mapeamento O/R em Java

É claro que o Hibernate e o JPA - Java Persistence API são tecnologias populares, dentro da comunidade e do ecossistema Java (TM), mas não representam as únicas soluções para persistência de dados. 

A tendência agora são os Bancos de dados NoSQL, que não utilizam modelo relacional para armazenar os dados. Eles podem trabalhar com outros tipos de objetos, como os representados por estruturas JSON. São mais leves e apresentam melhor performance em muitos casos do que os seus "primos" mais velhos. 

Veja só o que Martin Fowler tem a dizer sobre os bancos NoSQL

"The rise of NoSQL databases marks the end of the era of relational database dominance.
But NoSQL databases will not become the new dominators. Relational will still be popular, and used in the majority of situations. They, however, will no longer be the automatic choice.
The era of Polyglot Persistence has begun"


Traduzindo: "A ascensão de bancos de dados NoSQL marca o fim da era do domínio de banco de dados relacionais.

Mas os bancos de dados NoSQL não se tornarão os novos dominadores. O modelo Relacional ainda será popular, e utilizado na maioria das situações. Eles, no entanto, não serão mais a escolha automática. 
A era da persistência poliglota começou".

Temos um excelente artigo de Herman Mehling, no DevX sobre o assunto: "The Rise of NoSQL Databases", apesar de ser um pouco antigo (2010), mostra as razões do crescimento de bancos NoSQL fora do ambiente Java (TM). 

Os bancos NoSQL foram criados para armazenarem grandes volumes de dados, de forma distribuída, suportando inúmeras requisições simultâneas, sendo a plataforma ideal para aplicações de Big Data, conforme o próprio Martin Fowler disse. 

E o ecossistema Java (TM) ainda não absorveu corretamente o impacto dos bancos NoSQL, embora existam alguns "providers" JPA que suportam alguns tipos de bancos NoSQL, como o EclipseLink

Mas, o que você quer dizer com isso tudo?

O que eu quero dizer é simples. Ao limitarmos nossas aplicações ao ecossistema Java (TM), estamos criando um legado monstruoso, que poderá impactar significativamente o retorno do investimento feito nelas, afetando o ROI dos clientes e criando uma enorme dívida técnica. 

Estou exagerando?

Talvez...

Então me responda: Que outro tipo de solução usa o protocolo RMI-IIOP, além dos Enterprise JavaBeans? Talvez componentes CORBA (conhece alguma)?  Como você acha que vai ser o suporte e interoperabilidade de aplicações Java EE com EJB daqui a uns 10 anos? E o JSF? Você acha mesmo que os fornecedores de componentes conseguirão acompanhar a evolução da ubiquidade e a convergência digital? 

Precisamos repensar urgentemente nossa arquitetura de aplicações corporativas, de modo a quebrar o "Acoplamento de Plataforma". Isso não significa romper de vez com o Java (TM), ou com os frameworks que compõem o seu ecossistema. Mas significa "quebrar" a dependência entre as camadas, utilizando protocolos (REST) e modelos (JSON) mais simples e interoperáveis, permitindo a coexistência de componentes diferentes com os componentes Java tradicionais.

Não tenho dúvidas que até mesmo no backend muita coisa vai mudar, seja com a adoção de ESBs como o Mule, por exemplo, ou aplicações Node.js. 

De qualquer forma, é necessário "levantar a cabeça" do "mar" formado pelo ecossistema de frameworks e pensar um pouco "fora da caixa", pois, daqui a uns 5 ou 10 anos, suas aplicações ainda estarão aí e, talvez, você tenha que dar manutenção nelas. 

Sei que os desenvolvedores Java são muito territorialistas e sensíveis e que vou ferir alguns sentimentos, afinal eu mesmo me sinto um pouco ferido por causa deste artigo, mas o objetivo é fazer pensar, e não denegrir o Java (TM), o Java EE (TM) ou os inúmeros frameworks que compõem o seu ecossistema. Se você se sentiu atingido, por favor me desculpe.