How to reload properties file without rebooting Tomcat
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.
Albataur
Updated on July 18, 2022Comments
-
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 over 13 yearsAnd in the off topic theme, you shouldn't code in french, but that's another debate.
-
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 over 13 yearsYes, 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 over 13 yearsThank 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 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.