Skip to content

21. Conclusão

Explorámos os conceitos básicos do framework Struts 2 e apresentámos uma aplicação que combina várias tecnologias. Os leitores iniciantes e de nível intermédio encontrarão neste documento material que os ajudará a aprender e a melhorar. Continua a ser necessário um livro de referência. Recomendo mais uma vez o livro:

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

Gostaria de concluir destacando algumas questões com que me deparei ao escrever os exemplos deste documento. Já referi alguns comportamentos inesperados do Struts 2, particularmente ao introduzir números e datas. Aqui estão algumas outras questões com que me deparei:

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

Image

A consola do Apache exibe 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 foi bem-sucedida.

Vamos desinstalar [pam-02] da mesma forma. Os registos sã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]; root of factory hierarchy
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

Linhas 12, 14, 16: são relatados erros graves. Dois deles indicam um potencial fuga de memória. De facto, a aplicação [pam-02] apresenta fugas de memória. Após algum tempo, a aplicação torna-se inutilizável. Deve então fechar o NetBeans e reimplantar a aplicação.

Todos os erros referem-se a threads. A aplicação [pam-02] não utiliza threads por si própria. Devemos, portanto, suspeitar das estruturas utilizadas: Struts 2, Spring 2.5 e Tiles. Podemos razoavelmente excluir o Tiles, que provavelmente não lida com threads. Restam, assim, o Struts e o Spring.

Realizamos então outra experiência:

Implementamos a camada [web] utilizando a estrutura JSF em vez do Struts 2. Nada mais muda. Recebemos 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 talvez eu próprio, caso não tenha utilizado o Spring corretamente. Posso ter-me esquecido de uma configuração do Spring que limparia os threads criados; posso ter-me esquecido... A solução para este problema de fuga de memória continua, portanto, por encontrar.

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

  • em [2] as propriedades do projeto [example-08] [1]
  • em [3], a seleção do servidor web

Aqui está a página recuperada no navegador:

A portabilidade esperada não foi alcançada. Existem dois erros aqui:

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

Na maioria das aplicações desenvolvidas neste documento, deparamo-nos com estes mesmos dois erros. Não tentei resolver esta nova questão.