Search code examples
tomcatjsf-2reloading

Tomcat 7 is reloading application when saving properties file


I'm having a strange behavior in my application when it try to save a .properties file. The application is a JSF 2.0 using maven and Spring 3.0.5.

The code that tries save the file is this:

public class ControladorPopupConfiguracaoImportadorNFe extends ControladorPopup{

private static final long serialVersionUID = 1L;
private ModeloPopupConfiguracaoImportadorNFe modeloPopup;
private ControladorPopupAlerta popupAlerta; 

@Override
public void submit() {          
    Properties propriedades=new Properties();       
    definirPropriedades(propriedades);      
    if(salvar(propriedades)){
        this.fechar();      
        popupAlerta.abrir("As novas configurações foram salvas e já estão em uso!");
    }else
        popupAlerta.abrir("Não foi possível salvar as novas configurações.");
}

private void definirPropriedades(Properties propriedades) {     
    propriedades.setProperty("recuperadorNFe.usaSsl",modeloPopup.getUsaSsl().toString());
    propriedades.setProperty("recuperadorNFe.porta",modeloPopup.getPorta());
    propriedades.setProperty("recuperadorNFe.urlImap",modeloPopup.getUrl());
    propriedades.setProperty("recuperadorNFe.usuario",modeloPopup.getUsuario());
    propriedades.setProperty("recuperadorNFe.senha",modeloPopup.getSenha());
    propriedades.setProperty("recuperadorNFe.nomeDaCaixa",modeloPopup.getCaixaEntrada());
    propriedades.setProperty("recuperadorNFe.diretorioDeArmazenamento",modeloPopup.getDiretorioDeArmazenamento());
    propriedades.setProperty("recuperadorNFe.caixaDestino",modeloPopup.getCaixaDestino());
    propriedades.setProperty("recuperadorNFe.horarioRecuperacao",modeloPopup.getHorarioRecuperacao());      
}

private synchronized boolean salvar(Properties propriedades) {  
    try {           
        FileOutputStream outputStream=new FileOutputStream(modeloPopup.getArquivo());           
        propriedades.store(outputStream, "SEM COMETÁRIOS");         
        System.out.println("!!!!!!!!!!!!! - - - "+outputStream.getFD().toString()+" - - - !!!!!!!!!!!!!!");         
        outputStream.close();           
        return true;
    } catch (Exception e) {             
        e.printStackTrace();
    }       
    return false;
}

@Override
public void setModelo(ModeloComponenteBasico modelo) {
    modeloPopup=(ModeloPopupConfiguracaoImportadorNFe) modelo;
    super.setModelo(modelo);
}

public ControladorPopupAlerta getPopupAlerta() {
    return popupAlerta;
}

public void setPopupAlerta(ControladorPopupAlerta popupAlerta) {
    this.popupAlerta = popupAlerta;
}}

The Spring file that create the object of the class ControladorPopupConfiguracaoImportadorNFe is this:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    scope="singleton">
    <property name="locations" value="classpath:../propriedades/recuperadorNFe.properties" />
</bean>


<bean id="controladorPopupConfiguracaoImportadorNFe" class="com.hrgi.ui.controladores.popups.ControladorPopupConfiguracaoImportadorNFe"
    scope="request">
    <property name="modelo" ref="modeloPopupConfiguracaoImportadorNFe"/>
    <property name="popupAlerta" ref="controladorPopupAlerta"/>
</bean>

<bean id="modeloPopupConfiguracaoImportadorNFe" class="com.hrgi.ui.modelo.ModeloPopupConfiguracaoImportadorNFe"
    scope="session">
    <property name="visivel" value="false"/>
    <property name="caixaDestino" value="${recuperadorNFe.caixaDestino}"/>
    <property name="caixaEntrada" value="${recuperadorNFe.nomeDaCaixa}"/>
    <property name="diretorioDeArmazenamento" value="${recuperadorNFe.diretorioDeArmazenamento}"/>
    <property name="horarioRecuperacao" value="${recuperadorNFe.horarioRecuperacao}"/>
    <property name="porta" value="${recuperadorNFe.porta}"/>
    <property name="senha" value="${recuperadorNFe.senha}"/>
    <property name="url" value="${recuperadorNFe.urlImap}"/>
    <property name="usaSsl" value="${recuperadorNFe.usaSsl}"/>
    <property name="usuario" value="${recuperadorNFe.usuario}"/>
    <property name="arquivo" value="#{propriedadesImportador.file}"/>       
</bean>

<bean id="propriedadesImportador" class="org.springframework.core.io.ClassPathResource"
    scope="request">
    <constructor-arg name="path" value="../propriedades/recuperadorNFe.properties"/>
</bean> 

and this is what happens in tomcat:

...
 15/08/2011 15:57:47 com.hrgi.persistencia.cadastro.conversores.ConversorPessoa carregarBeansDeContato
AVISO: Lista de contatos está nula!!
15/08/2011 15:57:58 org.apache.tomcat.util.http.Parameters processParameters
INFO: Parameters: Invalid chunk '=' ignored.
!!!!!!!!!!!!! - - - java.io.FileDescriptor@671ca33b - - - !!!!!!!!!!!!!!
15/08/2011 15:58:02 org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name [/cadastro] has started
15/08/2011 15:58:02 org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
15/08/2011 15:58:02 org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing Root WebApplicationContext: startup date [Mon Aug 15 15:57:10 BRT 2011]; root of context hierarchy
15/08/2011 15:58:02 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3445378f: defining beans [controladorPopupNovoCadastroPessoa,modeloPopupNovoCadastroPessoa,carregadorTipoPessoa,tipoPessoa,controladorPopupCadastroPessoa,modeloPopupCadastroPessoa,carregadorTipoCadastro,tipoCadastro,carregadorTipoBuscaPessoa,tipoBuscaPessoa,controladorPopupBuscaPessoa,modeloPopupBuscaPessoa,controladorSugestaoPessoa,carregadorPessoaEdicao,carregadorCidadesEnderecoEntrega,carregadorCidadesEnderecoFaturamento,carregadorItensSelectEmpresa,controladorRemocaoContato,controladorSelecaoTabelaContatos,linhaSelecionadaTabelaContato,contatoSelecionado,controladorRemocaoEmail,controladorSelecaoTabelaEmail,linhaSelecionadaTabelaEmail,controladorRemocaoTelefone,controladorSelecaoTabelaTelefone,linhaSelecionadaTabelaTelefone,controladorPopupNovoContato,modeloPopupNovoContato,controladorPopupNovoTelefone,modeloPopupNovoTelefone,controladorPopupNovoEmail,modeloPopupNovoEmail,entityManagerFactory,tipoLogradouroDao,ufDao,cidadeDao,empresaDao,cadastroDao,ramoAtividadeDao,contatoDao,emailDao,telefoneDao,funcionarioDao,funcaoDao,nomeApelidoFuncionarioDao,cepDao,bancoDao,febrabanDao,agenciaDao,tipoBancoDao,contaDao,visaoBuscaPessoaDao,visaoListagemEmpresaDao,visaoListagemAgenciaDao,validadorCPF,validadorCNPJ,validadorIE,validadorEmail,validadorSenhaNovo,validadorSenhaMudanca,validadorSenhaAtual,itensSelectUf,itensSelectTipoLogradouro,controladorPopupAlerta,modeloPopupAlerta,controladorPopupConfirmacao,modeloPopupConfirmacao,funcionarioLogado,empresaFuncionarioLogado,enderecoEmpresaFuncionarioLogado,coletorUsuarioLogado,funcionario,pessoaFisica,pessoaJuridica,enderecoEntrega,enderecoFaturamento,carregadorEnderecoFaturamento,carregadorEnderecoEntrega,controladorArmazenamentoFuncionario,controladorArmazenamentoPessoa,controladorArmazenamentoEmpresa,conversorFuncionario,conversorEmpresa,conversorPessoaFisica,conversorPessoaJuridica,conversorEnderecoEntrega,conversorEnderecoFaturamento,conversorContato,novaEmpresa,controladorPopupNovaEmpresa,modeloPopupNovaEmpresa,controladorPopupCadastroEmpresa,modeloPopupCadastroEmpresa,controladorPopupBuscaEmpresa,modeloPopupBuscaEmpresa,controladorSugestaoEmpresa,carregadorEmpresaEdicao,carregadorTipoBuscaEmpresa,tipoBuscaEmpresa,org.springframework.security.web.PortMapperImpl#0,org.springframework.security.web.context.HttpSessionSecurityContextRepository#0,org.springframework.security.core.session.SessionRegistryImpl#0,org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy#0,org.springframework.security.authentication.ProviderManager#0,org.springframework.security.access.vote.AffirmativeBased#0,org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0,org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator#0,org.springframework.security.authentication.AnonymousAuthenticationProvider#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint#0,org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#0,org.springframework.security.config.http.UserDetailsServiceInjectionBeanPostProcessor#0,org.springframework.security.filterChainProxy,org.springframework.security.authentication.DefaultAuthenticationEventPublisher#0,org.springframework.security.authenticationManager,daoAuthenticationProvider,detalhadorDeUsuarios,passwordEncoder,controladorPopupCadastroFuncionario,modeloPopupCadastroFuncionario,controladorPopupNovoCadastroFuncionario,modeloPopupNovoCadastroFuncionario,carregadorFuncoesFuncionario,controladorPopupMudancaSenha,modeloPopupMudancaSenha,controladorPopupBuscaFuncionario,carregadorFuncionarioEdicao,modeloPopupBuscaFuncionario,controladorSugestaoFuncionario,carregadorTipoBuscaFuncionario,tipoBuscaFuncionario,controladorPopupCadastroAgencia,modeloPopupCadastroAgencia,agencia,conversorAgencia,controladorArmazenamentAgencia,carregadorBancos,controladorPopupNovoCadastroBanco,modeloPopupNovoCadastroBanco,controladorPopupCadastroBanco,modeloPopupCadastroBanco,bancoOficial,itensSelectBancoFebraban,controladorArmazenamentoBanco,conversorBanco,controladorPopupCadastroConta,modeloPopupCadastroConta,conta,armazenadorConta,carregadorEmpresasComCNPJ,carregadorAgencias,controladorPopupConfiguracaoImportadorNFe,modeloPopupConfiguracaoImportadorNFe,propriedadesImportador,importadorNFe,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,organizador,recuperador,imap,conectorImap,movedorEmail,marshaller,conversorEndereco,conversorIdentificacao,conversorEmitente,conversorDestinatario,conversorProduto,formatadorDecimal,formatadorData,conversorICMS,conversorICMS00,conversorICMS10,conversorICMS20,conversorICMS30,conversorICMS40,conversorICMS51,conversorICMS60,conversorICMS70,conversorICMS90,conversorICMSPartilhado,conversorICMSST,conversorIPI,conversorPIS,conversorCOFINS,conversorImposto,conversorTotalizador,conversorItem,conversorTransportadora,conversor    INFOrmacoesAdicionais,conversorTransporte,conversorFatura,conversorDuplicata,conversorCobranca,conversorNotaFiscal,formatadorString,geradorDigitoVerificador]; root of factory hierarchy
...

Solution

  • That will happen when <Context reloadable="true"> is been set for the webapp. Most IDE's like Eclipse do that by default so that Tomcat will reload (basically: restart) whenever a webapp context resource has been changed. This is useful for development.


    Apart from the concrete problem, saving files into webapp context while the webapp is running is really a bad idea due to the following reasons:

    1. All changes get lost whenever you redeploy the WAR file and/or restart the server.
    2. Not all containers will expand the deployed WAR into a writable folder structure.

    You should rather put those files in a fixed file system path outside the webapp and add that path to the webapp's runtime classpath. For example, /var/webapp/conf. You could configure that path externally as a system property and you could add that path to the classpath by specifying it in shared.loader property of Tomcat's /conf/catalina.properties. All other servletcontainers support similar constructs. Just document it properly along the install manual of your webapp.