42
Experimentando o Apache Tapestry
Recentemente começamos um projeto de evolução de uma aplicação web escrita em Apache Tapestry. Já fazia um tempo que não ouvia falar a seu respeito (uns seis anos pelo menos), então esta foi a oportunidade perfeita (e necessária) para que finalmente eu estudasse um pouco a seu respeito, e o que estou aprendendo tenho achado muito interessante.
Nota importante: este é um post escrito por um iniciante no assunto (eu). Sendo assim toda correção é bem vinda!
O que é o Apache Tapestry e minhas primeiras impressões
Uma definição bem vagabunda: "é framework para desenvolvimento de aplicações web, baseado em componentes, voltado para a plataforma Java". Isto não incita ninguém a correr atrás da ferramenta, especialmente se levarmos em consideração que não vemos muitos artigos escritos a seu respeito nos últimos anos. Sendo assim neste post vou escrever uma aplicação de exemplo que ilustra seu funcionamento.
Meu primeiro contato com Tapestry foi através de artigos na Internet e revistas em 2004/2005: anos mais tarde, lá por 2011, trabalhei em uma empresa que tinha alguns projetos baseados neste framework, mas eu mesmo jamais tive qualquer contato com estes projetos. Como nunca fui fã de frameworks que fossem baseados em componentes, torci o nariz para o projeto, até este mês (agosto/2017), quando precisei estudá-lo.
O que gostei no Tapestry
O que não gostei
Notas sobre a popularidade do framework e se você deve adotá-lo ou não com base nisto.
Tapestry, assim como Grails, Wicket, Play e outros não é o que podemos chamar de uma opção "mainstream", tal como o Spring (aliás, de todos os frameworks fora do Java EE, talvez o único mainstream seja o Spring) ou Java EE (puro,o que inclui o JSF). Sendo assim, quaisquer comparações em relação a estas opções é descabida de fundamentação.
No caso do Java EE, ainda mais, especialmente se levar em consideração o fato de que todos os demais frameworks dependem deste para funcionar (o que consequentemente o tornará sempre o mais popular).
O que levo em consideração na adoção destes frameworks (que são verdadeiras armas secretas) é a atividade da comunidade que possuem e a quantidade de releases anuais. Normalmente quando não ocorrem releases por mais de um ano levanto o sinal amarelo.
A propósito, já escrevi sobre este tópico neste link alguns anos atrás, mantenho minha opinião e já está na hora de escrever outro post a respeito.
(e ei, se você curte uma tecnologia e não escreve sobre ela por não ser tão popular, só tenho uma coisa a te dizer: SHAME ON YOU!)
"Olá Mundo" com Tapestry
O código fonte pode ser baixado neste repositório do GitHub.
O que você vai precisar
É uma aplicação bem simples, só pra mostrar os conceitos de páginas, componentes e o modus operandi do framework, sendo assim não esperem muita coisa daqui.
Criando o projeto com Maven
No link "Getting Started" do projeto você lerá que deve executar o comando a seguir:
mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org
Não funcionará com o Maven 3: você topará com a seguinte mensagem de erro:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:3.0.1:generate (default-cli) on project standalone-pom: archetypeCatalog 'http://tapestry.apache.org' is not supported anymore. Please read the plugin documentation for details. -> [Help 1]
Isto é fácil de resolver: basta usar uma versão anterior do plug-in archetype do Maven, tal como a 2.4 no exemplo a seguir:
mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate -DarchetypeCatalog=https://repository.apache.org/content/repositories/staging -Dfilter=org.apache.tapestry:quickstart
Após metade da Internet ser baixada para seu computador, serão aprsentadas 10 opções de arquétipos a serem escolhidos. Para o nosso exemplo adotei a opção "20" que equivale à última versão disponível do Tapestry (5.4.3).
Na sequência você precisará responder algumas perguntas:
Respondidas as perguntas, será criado um diretório cujo nome equivale ao artifactId do projeto. Para testar o projeto, mude seu diretório corrente para o criado pelo projeto e execute o comando abaixo:
mvn jetty:run

Será iniciado o servidor Jetty, embarcado no projeto. Sim, seu ambiente de desenvolvimento está pronto. Acessando a URL http://localhost:8080, exposta na saída do prompt, você se deparará com a seguinte página:

clique sobre o link: ele aponta para uma URL similar ao artifactId que você forneceu ao criar o projeto. Agora você verá a página de boas vindas do Tapestry.

Dica: dá pra criar o projeto de uma forma muito mais simples usando o Eclipse, tal como descrito neste link.
A estrutura do projeto

Importe o projeto Maven para a IDE de sua preferência, pois iremos alterar levemente este código fonte para expor o funcionamento do Tapestry. O arquétipo do Maven cria alguns sub-pacotes que são importantes: neste post falarei apenas de dois:
E na pasta "src/main/resources" também são criados alguns diretórios interessantes:
Os mesmos nomes dos pacotes se repetem nas pastas criadas em "src/main". Como disse no início deste post, uma aplicação Tapestry é composta essencialmente por páginas. Uma página, por sua vez, tem duas faces:
Com base no exemplo acima, alterei o código fonte do arquivo "Index.java" para que fique tal como o exposto a seguir:
package br.com.itexto.pages;package br.com.itexto.pages;
public class Index{
public String getRandomico() {
return java.util.UUID.randomUUID().toString();
}
}
Note que é uma classe Java simples, sem a necessidade de realizar qualquer implementação de interfaces ou uso de anotações. Alterei também levemente o arquivo de template relacionado (src/main/resources/br/com/itexto/pages/Index.tml) para que fique tal como no exemplo a seguir:
<html t:type="layout" title="inicio-tapestry Index"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
>
<p>Randomico como ${randomico}</p>
</html>
(Quando acessamos a URL do projeto, é a página Index que será renderizada para o visitante. Se você quiser experimentar, crie páginas com o nome "Teste" (contendo o código Java e o de template) e acesse as URLs diretamente para brincar.)
O template é a outra face da página: é o conteúdo HTML que será renderizado. No caso do Tapestry, é XHTML que usamos na realidade (HTML formatado como XML). Em seu interior, incluímos uma expressão: ${randomico}, que irá renderizar o valor retornado pela função getRandomico(), definido na classe Index.java. Tapestry usa a especificação JavaBeans do Java para definir as expressões que serão usadas na renderização das páginas.
Coloque a aplicação para executar em sua IDE usando o comando "mvn jetty:run" para ver o resultado, que será similar ao exposto na imagem a seguir:

Recarregamento dinâmico de classes
Agora, com a aplicação ainda em execução, faça o seguinte experimento: modifique a função getRandomico() da classe Index para que retorne diferentes valores, sem parar a aplicação. Carregue novamente a página: a mudança é instantânea.
Vá além: crie outros "getters" para novas propriedades e vá incrementando o arquivo de template. Note como mesmo novos métodos são detectados instantaneamente na aplicação sem precisar realizar qualquer tipo de reinicialização. Isto dá muita produtividade no desenvolvimento. A propósito, observou a velocidade com que a aplicação é iniciada?
E os componentes?
Bom, vendo a última imagem você deve ter notado que é renderizada uma barra de navegação, mas não a digitamos no código fonte do template. Notou? Então vou repetir o código aqui:
<html t:type="layout" title="inicio-tapestry Index"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"
>
<p>Randomico como ${randomico}</p>
</html>
O template define que ele é de um dado tipo: "layout". Você notou que existe uma pasta chamada "components" em "src/main/resources" e também um pacote chamado "components"? Se você abrir o código fonte do arquivo "src/main/resources/br/com/itexto/components/Layout.tml" verá que a barra de navegação, assim como o rodapé e toda a identidade visual está aí. E também vai achar um trecho similar ao exposto a seguir:
<div class="container">
<t:body />
<hr />
<footer>
<p>&copy; Your Company 2015</p>
</footer>
</div> <!-- /container -->
Sabe esta tag <t:body/>? Ela inclui o conteúdo da página Index no interior do Template. É um mecanismo muito similar ao Sitemesh do Grails! Na realidade é um pouco mais que isto, mas para este post inicial, creio que esta definição será o suficiente.
Código fonte do exemplo
O código fonte deste projeto pode ser encontrado neste link. Talvez eu o evolua no futuro conforme novos posts surjam no blog.
O que o Tapestry não tem e não é
É importante salientar que este não é um framework full stack tal como o Grails ou Spring Boot (dependendo da configuração). Quando criamos um novo projeto ele não vem com a camada de persistência pré-configurada. É necessário realizar esta configuração manualmente, tal como exposto na própria documentação.
O projeto já vêm com algumas configurações prontas, tal como o mecanismo de logging e algum CSS, baseado no bootstrap, mas não muito mais do que isto.
Também é importante observar o seu foco: são aplicações web que contenham páginas interativas, não APIs REST. É possível configurar no mesmo projeto um segundo framework para prover estas funcionalidades, tal como o JAX-RS ou mesmo o Spring, mas não recomendo isto.
Sei que não mencionei neste post nada relativo à gestão de sessões, mas este é outro aspecto interessantíssimo do Tapestry: não é um destes frameworks no qual você tem a sessão explícita. Lidamos com ela de uma forma indireta através de anotações que incluímos em nossas classes (@Persistent). Sendo assim, para projetos que precisem lidar diretamente com sessões (cada vez menos o caso), Tapestry também não se aplica.
Conclusões finais sobre este contato inicial
Neste post mostrei apenas o básico do básico do básico do Tapestry (quase nada pra ser sincero). Muita coisa ficou de fora, tal como a forma como é realizada a navegação entre as páginas, gestão de sessão, formulários, inversão de controle, etc.
Meu objetivo foi apenas gerar algum interesse pelo framework e, talvez, criar o post inicial que me permita ir detalhando aos poucos como o Tapestry funciona conforme vou avançando nossos estudos a seu respeito.
Estou achando uma solução muito interessante: mais interessante que o JSF na minha opinião, pois é mais fácil de aprender e oferece uma produtividade muito superior. Isto sem mencionar no desempenho, que foi um dos fatores que mais me surpreendeu.
(tal como mencionado no início deste POST, para implementar APIs REST não é uma solução interessante. Aliás, nem sei se faria sentido, dado ser focado em componentes, e não em ações, tal como ocorre no Grails e Spring MVC)
Dado o estado atual da comunidade (ao menos minha percepção inicial), não sei se o recomendaria para iniciar novos projetos, mas em relação a este aspecto apenas o tempo me dará uma resposta satisfatória. Entretanto, se o tempo mostrar que ainda há gás nesta comunidade, sem sombra de dúvidas que o incluirei em nosso radar.
Visto que tão pouco se escreve a respeito do Tapestry ultimamente, creio que no mínimo estes meus posts servirão para atrair interessados a seu respeito. Mesmo que você jamais o use, as ideias que ele trás já valem à pena conhecer.
Mais fontes sobre Tapestry
Talvez você tenha se interessado pelo framework. A documentação oficial apesar de boa não é suficiente. Sendo assim, seguem alguns links que estão me ajudando no aprendizado:
42