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
2010-05-26 15:29:45
+1, but note that ProtectionDomain.getCodeSource() and CodeSource.getLocation() can both be null.
bkail
2010-05-26 18:22:28
@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
2010-05-26 18:26:44
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
2010-05-26 21:34:02
So it's already in the classpath? Then just use the classloader. I updated my answer.
BalusC
2010-05-26 22:00:41
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
2010-05-27 04:31:34
No, it's not inside a classpath. It's just in the same folder as jar - the same level, but not packaged inside.
markovuksanovic
2010-05-27 05:53:09
Add that path to the classpath then. Put a `Class-Path: .` in the `MANIFEST.MF` file.
BalusC
2010-05-27 11:18:26
A:
if you want to get the "working directory" for the currently running program, then just use:
new File("");
james
2010-05-26 16:01:43