views:

53

answers:

3

Hi,

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 !

+1  A: 

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

Colin Hebert
+1 - this is the simplest solution.
Stephen C
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
A: 

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.

Stephen C
And in the off topic theme, you shouldn't code in french, but that's another debate.
Colin Hebert
@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 :-)
Stephen C
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 ..
Albataur
@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.
Stephen C
+1  A: 

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

Pascal Thivent
Thank you.It sounds pretty good.
Albataur