0

In my Java EE web application, I need a place to put my properties file where I can find it using getResource() and then update that file.

Placing it in the lib directory doesn't seem to have worked for tomcat. Suggestions?

The application is that GXT needs to have a properties file to hold internationalized strings. I have a requirement to load these strings from a database table. So I have to create the properties file on startup. I am creating an empty one that goes into my jar file in the lib directory. Then I find that file and write to it with the new answers. It all works in jetty, but not in tomcat.

Thanks.

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Thom
  • 14,013
  • 25
  • 105
  • 185

2 Answers2

3

You can't necessarily reliably write to a classpath location as it might not represent a local disk file system path. You can only write to a (absolute) disk file system location.

Best would be to have a known fixed disk file system location which is in turn also added to the classpath, so that you could use both ClassLoader#getResource() to load it from the classpath and FileOutputStream to write it to the local disk file system.

In case of Tomcat, you can add a fixed disk file system location to the classpath by the shared.loader property of /conf/catalina.properties. E.g.

shared.loader = /var/webapp/conf

It might be useful as well to add a property representing the fixed disk file system location to the properties file itself.

my.location = /var/webapp/conf

This way you can read it as

Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("foo.properties");

And save as

properties.store(new FileOutputStream(new File(properties.getProperty("my.location"), "foo.properties")));

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Yeah, but I'm making sure that I can write to it. – Thom Nov 09 '12 at 17:16
  • I'm not sure if I understand your last comment. Do you understand that you need a `FileOutputStream` in order to write it? Do you understand that the `FileOutputStream` in turn needs a fixed disk file system location? My answer shows how to do that. – BalusC Nov 09 '12 at 17:17
  • Yes. That's the issue I'm running into. Surprising WEB-INF/lib doesn't appear to be on the classpath. – Thom Nov 09 '12 at 17:18
  • It's definitely in the classpath. I'm now only getting more confused about the concrete problem which made you to post those strange comments. Please elaborate more about that concrete problem. This doesn't seem to be covered in your question at all. What exactly made you think that WEB-INF/lib is not in the classpath? – BalusC Nov 09 '12 at 17:19
  • This is covered in 1st sentence of my answer: *"You can't necessarily reliably write to a classpath location as it might not represent a local disk file system path"*. Tomcat might for instance have extracted the WAR into memory instead of into some folder on local disk file system. You can't create a `FileOutputStream` to a file in memory, let alone a file which is by itself inside a JAR (you'd have to extract the JAR first, repack it and then have the classloader reload it). – BalusC Nov 09 '12 at 17:29
0
    //read properties    
    Properties prop = new Properties();
    ClassLoader loader = Thread.currentThread().getContextClassLoader();            
    InputStream stream = loader.getResourceAsStream("sample.properties");
    prop.load(stream);      
    //now save back, take as URL 
    java.net.URL f = loader.getResource("sample.properties");   
    File file = new File(f.getPath());
    OutputStream outstream = new FileOutputStream(file);
    prop.store(outstream, "");
    outstream.close();

But I will suggest using of http://commons.apache.org/configuration/howto_properties.html , because of diferen features including keeping the file "user readable" after store()

DejanR
  • 441
  • 4
  • 11