How to reload properties file without rebooting Tomcat

16,552

Solution 1

Actually, your webapp does have access to the ServletContext at various points. For example you can get it using ServletRequest.getServletContext(), or from a ServletContextEvent obtained via a ServletContextListener callback.


This is a bit off topic, but you should realise that this code:

String cheminFichier = new StringBuilder(100).append(classeBP.getPackage().getName().replace(".", "/")).append(File.separator).append(
    REPERTOIRE_MAPPING).append(nomFichier).append(".properties").toString();

could / should be written as:

String cheminFichier = classeBP.getPackage().getName().replace(".", "/")) +
    File.separator + REPERTOIRE_MAPPING + nomFichier + ".properties";

There is no performance advantage here in explicitly using a StringBuilder here, because the Java compiler will compile the concatenation to the same code.

You only need to use a StringBuilder if the concatenation involves a loop.

Solution 2

You could use something like Commons Configuration that supports automatic reloading.

Solution 3

You can still use the Tomcat Manager to reload your application.

Share:
16,552
Albataur
Author by

Albataur

Updated on July 18, 2022

Comments

  • Albataur
    Albataur almost 2 years

    I load a property file from classpath with the method :

        String cheminFichier = new StringBuilder(100).append(classeBP.getPackage().getName().replace(".", "/")).append(File.separator).append(
            REPERTOIRE_MAPPING).append(nomFichier).append(".properties").toString();
        InputStream isMapping = Thread.currentThread().getContextClassLoader().getResourceAsStream(cheminFichier.toString());
        if (isMapping == null)
        {
            throw new ServiceMappingException("Erreur lors du chargement du mapping du service. Le fichier "
                + cheminFichier + " n'existe pas.");
        }
        else
        {
            Properties mapping = new Properties();
            try
            {
                mapping.load(isMapping);
            }
            catch (IOException e)
            ...
        }
    

    Ok, it's work. But if I modify the content of the property file when Tomcat is running, changes are ignored. It's not hot-reloaded as with classes.

    My context is configured with reloadable="true" option and the classloader returned by Thread.currentThread().getContextClassLoader() is the WEBAPP classloader (not the system classloader or other).

    I read it's possible to use ServletContext.getResourceAsStream, but I haven't access to the servlet context.

    It's Tomcat 5.5.

    Any idea ? If not, do you have a solution for forcing to reload a specific resource (my property file) ?

    Thanks !

  • Colin Hebert
    Colin Hebert over 13 years
    And in the off topic theme, you shouldn't code in french, but that's another debate.
  • Stephen C
    Stephen C over 13 years
    @Colin - I wouldn't go that far, but it is a bit awkward to read Java with a French to English dictionary. Indonesian would be fine though :-)
  • Albataur
    Albataur over 13 years
    Yes, but it's precisely what I want to avoid. My application spend about 1 min to start, so I won't reload entire application once I change the property file.
  • Albataur
    Albataur over 13 years
    Thank you for your answer. I will try that. About the StringBuilder, I disagree with you (maybe I am wrong ...). I initalize the StringBuilder with 100 chars, so Java will not reallocate when the string will grow, no ? About the french coding, I agree with you :) but I didn't write the rules ..
  • Stephen C
    Stephen C over 13 years
    @Abalataur - about StringBuilder, it depends on how close your estimated size is to the real size. If your estimate is close, then you may win a bit. If it is not, you won't. In particular, if it is significantly large, then you will lose big. But either way, this is an optimization that is probably not worth it ... unless profiling tells you otherwise.