tags:

views:

115

answers:

2

Is there a way for java program to determine its location in the file system?

+2  A: 

You can use CodeSource#getLocation() for this. The CodeSource is available by ProtectionDomain#getCodeSource(). The ProtectionDomain in turn is available by Class#getProtectionDomain().

URL location = getClass().getProtectionDomain().getCodeSource().getLocation();
File file = new File(location.getPath());
// ...

This returns the exact location of the Class in question.

Update: as per the comments, it's apparently already in the classpath. You can then just use ClassLoader#getResource() wherein you pass the root-package-relative path.

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL resource = classLoader.getResource("filename.ext");
File file = new File(resource.getPath());
// ...

You can even get it as an InputStream using ClassLoader#getResourceAsStream().

InputStream input = classLoader.getResourceAsStream("filename.ext");
// ...

That's also the normal way of using packaged resources. If it's located inside a package, then use for example com/example/filename.ext instead.

BalusC
+1, but note that ProtectionDomain.getCodeSource() and CodeSource.getLocation() can both be null.
bkail
@bkail: It may indeed return null when it's loaded using a poorly designed homegrown classloader, or when it's loaded from some external stream source, etc. This however usually doesn't apply on "concrete" Java programs with a `main()`.
BalusC
This definitely does do the job - but it doesn't look very nice. What I need to do is load a configuration file which needs to be in the same folder as my jar but can be run from any location. Is this the right way to get the file location info?
markovuksanovic
So it's already in the classpath? Then just use the classloader. I updated my answer.
BalusC
getResourceAsStream suggestion is a good one. FYI, getResource will return "jar:file:path!/resource", so you'll need to deconstruct that before passing to File. Even if you assume a directory-based classpath, URL.getPath() from getResource will be URL-encoded (e.g., "Program%20Files"), so you need to decode (or just convert the URL to a URI) before converting to File. (Sorry for the pedantry; I worked in class loader support for three years and got to see/experience the pain of all these nuances :-)).
bkail
No, it's not inside a classpath. It's just in the same folder as jar - the same level, but not packaged inside.
markovuksanovic
Add that path to the classpath then. Put a `Class-Path: .` in the `MANIFEST.MF` file.
BalusC
A: 

if you want to get the "working directory" for the currently running program, then just use:

new File("");
james