Skip to content

Estrutura Projetos Play

Markenson edited this page Aug 21, 2014 · 2 revisions

Estrutura dos projetos para execução pelo Play Framework 1.2.4

Introdução

Esta página explica como estão estruturados os projetos siga-play-module e os que dele dependem para ser executados com sucesso pelo Play Framework e empacotados num .war para deploy no JBoss.

O projeto siga-play-module

Para concentrar os componentes que serão utilizados por todos os projetos feitos em Play, foi criado o siga-play-module, que depende dos projetos siga-base, siga-cp, siga-cp-sinc-lib e siga-cd. Entre os componentes do siga-play-module reutilizáveis estão os binders, as tags e a classe ObjetoBase.

A classe ObjetoBase

A classe br.gov.jfrj.siga.model.ObjetoBase faz parte do projeto siga-base (do qual, como dito, depende o siga-play-module). Essa classe é filha de java.lang.Object. E dela herdam as classes do Corporativo.

Porém, uma classe de mesmo nome e caminho que o ObjetoBase do siga-base precisou ser criada no siga-play-module, de modo a sobrescrever aquela. A diferença é que, no siga-play-module, ela estende GenericModel, para atribuir funcionalidades do Play (como o findById) a classes dela sejam filhas. Isso possibilita que, na visão do siga-play-module, as classes do Corporativo constem como herdando de GenericModel.

Essa manobra foi necessária por não ser possível, no Java, que a classe SrConfiguracao, por exemplo, seja herdeira de CpConfiguracao e, ao mesmo tempo, de GenericModel. Então, pelo esquema utilizado, o projeto siga-play-module bem como os que dele dependem passam a enxergar, de modo simplificado, da seguinte maneira:

java.lang.Object -> GenericModel -> ObjetoBase -> Objeto -> Classe do corporativo -> Classe filha do Corporativo

Enquanto, fora do siga-play-module, a visão continua a tradicional:

java.lang.Object -> ObjetoBase -> Objeto -> Classe do corporativo -> Classe filha do Corporativo

Assim foi superada a proibição da herança múltipla.

Declaração de módulos do Play

Para um projeto Play ser baseado no siga-play-module, não basta ter siga-play-module como dependência configurada no Eclipse ou outro ambiente de desenvolvimento. O Play Framework não conhece essa configuração. É necessário que o arquivo application.conf do projeto declare a dependência entre si mesmo e o módulo. Isso é feito por meio da seguinte linha:

module.siga-play=../siga-play-module

Essa linha indica ao Play que, no diretório de mesmo nível que o do projeto (../) e de nome siga-play-module, está um projeto que vai funcionar como módulo do principal e será chamado de siga-play.

Enhancement

Antes da execução de qualquer aplicação, o Play Framework realiza um procedimento chamado enhancement das classes cujo fonte estão no diretório app. Essa operação consiste em incrementar o código dessas classes, possibilitando, entre outras coisas, a chamada ao método findById.

Quando se declara um módulo da aplicação, conforme explicado acima, o Play passa a fazer também o enhancement das classes com fonte no diretório app do módulo. É necessário que isso aconteça pois ocorrem conflitos estranhos quando uma classe enhanced herda de outra não manipuladas pelo Play. A aplicação executa, mas acontecem erros em várias chamadas de métodos e salvamentos em cascata.

Isso leva a uma questão: já que classes do projeto Play (SrConfiguracao, por exemplo) herdam do Corporativo, como fazer com que o Play faça o necessário enhancement do Corporativo, já que o siga-play-module não contém os fontes do Corporativo? A solução foi declarar o projeto siga-cp também como um módulo do projeto:

module.siga-cp=../siga-cp

E o diretório src do siga-cp foi renomeado para app. Essa foi a única alteração que precisou extrapolar o domínio do siga-play-module e dos projetos Play.

Ainda havia um problema: a classe Objeto, parte da hierarquia e contida no siga-base. Como torná-la enhanced, visto que não faz parte do siga-cp? Foi necessário realizar também com essa classe o procedimento descrito acima para a classe ObjetoBase, de modo que o siga-play-module também declara a classe br.gov.jfrj.siga.model.Objeto, em substituição à correspondente do siga-base.

Linked Folders

Um projeto Play possui as suas bibliotecas compatíveis com a versão 1.2.4 do Play Framework, incluindo o Hibernate 3.6.1. Essa versão do Hibernate pode ser diferente da importada pelo siga-base. Como, ao se executar um projeto Play pelo Eclipse (não foi realizado teste com outro ambiente), o arquivo .launch (gerado pelo framework ao criar a estrutura do projeto) carrega as bibliotecas do classpath do projeto, o Hibernate importado pelo siga-base entra em conflito com o importado diretamente pelo projeto Play.

A solução para esse conflito foi substituir a dependência entre o projeto siga-play-module e os projetos siga-base, siga-cp, siga-sinc-lib e siga-cd por linked folders. Esse método possibilita uma importação seletiva desses projetos-base. Importam-se apenas os diretórios src. Os arquivos .java contidos nesses diretórios, no entanto, não sofrem uma cópia para o siga-play-module, mas apenas os seus correspondentes .class. Em resumo, esse procedimento evita que as bibliotecas usadas pelo siga-base (como o Hibernate) sejam importadas pelo siga-play-module (e, por conseguinte, pelo projeto Play dependente do siga-play-module), impedindo-se então o conflito entre versões do Hibernate.

Como a importação mencionada é seletiva, pôde-se optar por não importar certos arquivos do próprio diretório src do siga-base, do siga-cp, do siga-cp-sinc-lib e siga-cd que também poderiam gerar conflito (assim como as bibliotecas) ou que não teriam utilidade para o siga-play-module. Entre eles estão os arquivos .java referentes às classes Objeto e ObjetoBase, visto que são sobrescritas, conforme explanado acima, e pacotes relativos a relatório e assinatura digital.

Comandos Python

Como mencionado acima, ao executar a aplicação pelo ambiente de desenvolvimento (Eclipse, Netbeans, etc), o framework é orientado a carregar as classes do classpath configurado para o projeto naquele ambiente.

Como a geração do war não é feita por dentro do ambiente, não havendo, portanto, nenhuma orientação para o framework carregar as bibliotecas conforme configurado na IDE, foi incluído no projeto siga-play-module um trecho de código Python que será executado pelo framework ao gerar o war. Esse trecho empacota num jar os arquivos .class gerados no diretório bin pela IDE (diretório esse que não é usado pelo Play) e grava esse jar no diretório lib do siga-play-module. Isso possibilita a carga dessas classes na geração do war.

Pendente de teste: se o comando run, não war, for executado por fora da IDE, essas classes serão corretamente carregadas?

Dúvidas pertinentes

  • Por que não foi usada a última versão do Play Framework? A versão 2 do framework trabalha de modo consideravelmente diferente da versão 1. A migração não será trivial, e não há previsão de ser feita. A versão 1.2.4 é a última acompanhada de uma versão do Hibernate compatível com o ambiente dos servidores de aplicação da JFRJ.
Clone this wiki locally