Skip to content

21. Conclusão

Foram estudados os fundamentos do framework Struts 2 e foi apresentada uma aplicação que reúne várias tecnologias. O leitor de nível iniciante ou intermédio encontrará neste documento material para se formar e progredir. Resta a necessidade de um livro de referência. Recomendo novamente a obra:

«Struts 2 in Action», escrito por Donald Brown, Chad Michael Davis e Scott Stanlick, publicado pela editora Manning.

Gostaria de terminar apresentando alguns problemas com que me deparei ao escrever os exemplos deste documento. Já referi comportamentos inesperados do Struts 2, nomeadamente durante a introdução de números e datas. Eis alguns outros problemas encontrados:

Vamos descarregar a aplicação [pam-01] do servidor Tomcat:

  

A consola do Apache apresenta então os seguintes registos:

1
2
3
4
5
6
7
8
janv. 05, 2012 11:18:58 AM org.springframework.context.support.AbstractApplicationContext doClose
Infos: Closing org.springframework.web.context.support.XmlWebApplicationContext@57488b9c: display name [Root WebApplicationContext]; startup date [Thu Jan 05 11:18:45 CET 2012]; root of context hierarchy
janv. 05, 2012 11:18:58 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
Infos: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@78ae9d8d: defining beans [config,metier]; root of factory hierarchy
janv. 05, 2012 11:18:58 AM org.apache.tiles.access.TilesAccess setContainer
Infos: Removing TilesContext for context: org.apache.catalina.core.ApplicationContextFacade
janv. 05, 2012 11:19:00 AM org.apache.catalina.startup.HostConfig checkResources
Infos: Repli (undeploy) de l'application web ayant pour chemin de contexte /pam-01

A descarga decorreu sem problemas.

Vamos descarregar da mesma forma o [pam-02]. Os registos são então os seguintes:

janv. 05, 2012 11:21:07 AM org.springframework.context.support.AbstractApplicationContext doClose
Infos: Closing org.springframework.web.context.support.XmlWebApplicationContext@5d9131fa: display name [Root WebApplicationContext]; startup date [Thu Jan 05 11:11:10 CET 2012]; root of context hierarchy
janv. 05, 2012 11:21:07 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
Infos: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@7b66d238: defining beans [config,metier,employeDao,indemniteDao,cotisationDao,entityManagerFactory,dataSource,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,txManager,org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0]; raiz da hierarquia da fábrica
janv. 05, 2012 11:21:07 AM org.springframework.orm.jpa.AbstractEntityManagerFactoryBean destroy
Infos: Closing JPA EntityManagerFactory for persistence unit 'pam-PU'
janv. 05, 2012 11:21:07 AM org.hibernate.impl.SessionFactoryImpl close
Infos: closing
janv. 05, 2012 11:21:07 AM org.apache.tiles.access.TilesAccess setContainer
Infos: Removing TilesContext for context: org.apache.catalina.core.ApplicationContextFacade
janv. 05, 2012 11:21:07 AM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
Grave: The web application [/pam-02] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
janv. 05, 2012 11:21:07 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
Grave: The web application [/pam-02] appears to have started a thread named [Timer-0] but has failed to stop it. This is very likely to create a memory leak.
janv. 05, 2012 11:21:07 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
Grave: The web application [/pam-02] appears to have started a thread named [MySQL Statement Cancellation Timer] but has failed to stop it. This is very likely to create a memory leak.
janv. 05, 2012 11:21:08 AM org.apache.catalina.startup.HostConfig checkResources
Infos: Repli (undeploy) de l'application web ayant pour chemin de contexte /pam-02

Nas linhas 12, 14 e 16, são assinalados erros graves. Dois deles indicam uma possível fuga de memória. De facto, a aplicação [pam-02] apresenta fugas de memória. Passado algum tempo, a aplicação deixa de estar utilizável. É então necessário encerrar o NetBeans e reimplantar a aplicação.

Todos os erros estão relacionados com threads. A aplicação [pam-02] não utiliza threads por si própria. Por isso, deve-se suspeitar dos frameworks utilizados: Struts 2, Spring 2.5 e Tiles. É razoável excluir o Tiles, que provavelmente não gere threads. Restam o Struts e o Spring.

Fazemos então outra experiência:

Implementamos a camada [web] com o framework JSF em vez do Struts 2. Nada mais muda. Obtemos então as mesmas mensagens de erro que com o Struts 2.

Portanto, o culpado parece ser o Spring, o pool de ligações dbcp aqui utilizado pelo Spring, ou então eu próprio, caso não tenha utilizado o Spring da forma correta. Posso ter-me esquecido de uma configuração do Spring que permitiria limpar os threads criados, posso ter... A solução para este problema de fuga de memória continua, portanto, por encontrar.

Outra experiência. O IDE NetBeans é instalado com os servidores Tomcat e GlassFish. Vamos tentar executar no GlassFish uma aplicação criada neste documento:

  • em [2] as propriedades do projeto [exemple-08] [1]
  • em [3], a escolha do servidor web

Eis a página recuperada no navegador:

A portabilidade esperada não se concretizou. Existem aqui dois erros:

  • em [1], a internacionalização não funcionou
  • em [2], ocorre uma exceção

Na maioria das aplicações desenvolvidas neste documento, ocorrem estes mesmos dois erros. Não procurei resolver este novo problema.