3

We have been using System.getProperties("user.dir") to get the location of a properties file. Now that it has been deployed on Tomcat(via servlet), the System call is giving the location as tomcat and not at the location at where the properties file exist.

How can we call the the properties file dynamically?

Given:

  • Tomcat is not the only way the app will be deployed
  • We have no control on where the app may be placed.
  • Relative paths will not work as that Vista is being used and Vista breaks relative paths.
  • This must work on all OS, including(but not limited to) Linux, XP and Vista.
  • EDIT I implied this, but in case I was not clear enough, I have no way of knowing the path String.
WolfmanDragon
  • 7,851
  • 14
  • 49
  • 61
  • 1
    I don't think that relative paths are a great solution (what its relative to would end up depending heavily on the app server). But since when did "Vista break relative paths"? That doesn't make any sense. – jsight Feb 17 '09 at 20:40
  • I agree that it doesn't but after months of having relative paths passed to me, and not a single one has worked, I must conclude that Vista is breaking the paths somewhere. I am not a system admin, and when I ask system admins I get a blank stare from them. – WolfmanDragon Feb 17 '09 at 20:47
  • That is the reason that I use System.getProperties("user.dir"), it will return the correct path on Vista, XP, and Linux. But not tomcat. – WolfmanDragon Feb 17 '09 at 20:49

9 Answers9

2

Take a look at ServletContext's getResource and getResourceAsStream methods.

John Topley
  • 113,588
  • 46
  • 195
  • 237
2

You must have a way of knowing the path of the property file which you can then wrap in a File and pass to the load() method of your properties object.

If you run inside a Tomcat service you are not running as the user you installed it as,so you cannot derive the home directory. You most likely need to hardcode SOMETHING then.


Edit: The property file is relative to the application. See http://www.exampledepot.com/egs/java.lang/ClassOrigin.html for an example of how to get to the file name for the bytecode for a given class. You should be able to continue from there.

Class cls = this.getClass();
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation();  // file:/c:/almanac14/examples/

You should be aware that some security managers disallow this.

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
  • Works on Vista, passed it on to to be tested on Tomcat. thanks +1 – WolfmanDragon Feb 18 '09 at 23:18
  • I never got an answer back from the tomcat side, as of now I am accepting your answer, as that it actually works on Vista. It only scares me what will happen with Windows 7. There might be another post. Thanks. – WolfmanDragon Mar 30 '09 at 20:38
1

I think ClassName.class.getResourceAsStream() will work for you. The comments on that method point you at ClassLoader.getResource(), which tells you how to specify a file in your classpath.

Something like this should work:

InputStream foo = ClassName.class.getResourceAsStream("file.name");

Where file.name is at the base of your classpath somewhere. If file.name is in the com.foo.bar package, you would use "/com/foo/bar/file.name"

Akrikos
  • 3,595
  • 2
  • 24
  • 22
1

If I understood the question correclty, another alternative might be to call ServletContext.getRealPath() on a jsp or a static file in your app and derive the path from the result.

It implies webapp deployed as "expanded" - i.e. not as a compressed war file - but that is what most appservers do anyway.

david a.
  • 5,283
  • 22
  • 24
  • That was one of the earliest tries at a fix. Does not work across the board. It goes to the Tomcat file, not the source file. – WolfmanDragon Mar 30 '09 at 20:34
0

We had the same requirements. The simplest thing that worked so far was to just store a basedir property in one of the property files we were already loading. Then define a method like getExternalDocPath(String path).

This allowed us to extend the docbase of Tomcat (which only Tomcat 7 supports?). Out on the web someone posted a class that actually extends Tomcat's docbase to allow multiple paths, i.e., "alpha;baker;charlie".

JosefB
  • 99
  • 1
  • 1
0

You can place your property files in your class path and read them as an input stream using something like:

ClassName.class.getResourceAsStream(filePath + fileName);

Where filePath is the relative path of the file from the class path root and fileName is the name of the file.

If you need to get the absolute path to a file you read as a resource, you can do some thing like this:

ClassName.class.getResource(filePath + fileName).getPath()

neesh
  • 5,167
  • 6
  • 29
  • 32
  • @neesh, if you do not know the filePath, how are you using it in the getResource() call? I am sure that I am simply misunderstanding what you are saying. – WolfmanDragon Feb 17 '09 at 21:04
  • So let's say you don't know the filePath and you want to know the absolute path of the directory your web-app is deployed. You can do this: ClassName.class.getResource("/").getPath(); – neesh Feb 17 '09 at 21:37
  • Does not work on Vista. Would have been a good fix otherwise. +1 – WolfmanDragon Feb 17 '09 at 22:17
  • really? What does the ..getResource("/").getPath() return in Windows Vista? – neesh Feb 18 '09 at 01:43
  • exception### I would have to go run it again to remember the exception . I will do that later and post the reply. out of time now – WolfmanDragon Feb 18 '09 at 23:17
0

Is it possible to put the config file within the classpath and reference it via something like springs ClassPathResource?

You should be able to use it like this:

ClassPathResource foo = new ClassPathResource("file.name");

Where file.name exists somewhere in the classpath at the lowest level such as:

  • /webapps/WEB-INF/classes/
  • the base of one of your jar files
Akrikos
  • 3,595
  • 2
  • 24
  • 22
0

Another approach may be to pass the variable value to the JVM with -D parameter. That way you can tie your code to the same variable name and then pass different values at the time of start-up. I haven't tried this, but i'm thinking it should work for an app deployed in Tomcat as well, if you modify startCatalina script to pass -D parameter to JVM

Rocket Surgeon
  • 575
  • 6
  • 18
0

You could store the location of your properties file in JNDI?

This should be portable across Tomcat, and for Java EE Application Servers.

toolkit
  • 49,809
  • 17
  • 109
  • 135