Reputation: 29090
I'm looking for a simple, cross-platform way, on the JVM, to get the appropriate directories for storing application settings and cache data. E.g., on Linux under the XDG specs:
~/.config/appname
~/.cache/appname
Windows stuff goes in C\Users\user\Application Data
or some such (on Win 7); I gather that Mac puts stuff under ~/Library/Application Settings
.
Is there a cross-platform call to get these path locations? I haven't been able to find one, though I find several questions asking about it. Is there some library that has implemented the correct logic for most common desktop platforms?
Worst case, I can just look up user.home
and pretend everything is an XDG-based Linux environment. But if it's easy to get the right directories for the user's OS, I'd like to do so.
Upvotes: 13
Views: 991
Reputation: 16439
After searching a lot, I have found two Java libraries via Github which uses XDG Base Directory Specification
behind the scenes to get the most common cross-platform based directories.
These are:
directories-jvm
(maintained, confirmed to work 2024): This project is actively maintained and developed by good number of contributors and there are good number of releases in Maven Repo for directories-jvm
and you can integrate this library dependency via SBT
, Gradle
and Maven
. Please read the README.md. It's very well explanatory.
Scala Example (tested):
#!/usr/bin/env -S scala-cli shebang
//> using dep "dev.dirs:directories:26"
import dev.dirs.ProjectDirectories
@main def entry(): Unit =
val myProjDirs = ProjectDirectories.from("com", "Corp", "App")
println("Config dir: " + myProjDirs.configDir)
println("Cache dir : " + myProjDirs.cacheDir)
prints the expected directories:
Config dir: /home/bob/.config/app
Cache dir : /home/bob/.cache/app
Java Example (not tested, but should probably work if one sets up a proper Maven project; Example borrowed & modified from README):
import dev.dirs.ProjectDirectories;
// Borrowed with minor changes from here:
// https://github.com/dirs-dev/directories-jvm
//
public class DirectoriesJvmDemo {
public static void main(String[] args) {
ProjectDirectories myProjDirs =
ProjectDirectories.from("com", "Foo Corp", "Bar App");
System.out.println(myProjDirs.configDir);
// Lin: /home/alice/.config/barapp
// Mac: /Users/Alice/Library/Application Support/com.Foo-Corp.Bar-App
// Win: C:\Users\Alice\AppData\Roaming\Foo Corp\BarApp\config
}
}
xdg-java
(last commit 8 years ago): The development for this project has been stopped in 2016. Since then, there is no new commit in their repository. You can try out their code base locally by cloning their project and then running the code by writing your own logic as they don't have a jar available which you can use to integrate in your application. So, use it at your own risk.
System.out.println(BaseDirectory.get(BaseDirectory.XDG_CACHE_HOME));
Upvotes: 1
Reputation: 2288
As it seems closely related and has not been mentioned before:
You may want to consider the good old (2002) Java Preferences API (for system-wide and per-user persistence of string values up to 8192 characters).
https://docs.oracle.com/en/java/javase/22/core/preferences-api1.html
Upvotes: -1
Reputation: 8764
The FileSystemView
class is the only one I know that contains access to some general directories like this, and is cross-platform. Refer to the documentation here
This class contains some method that might be helpful, such as getHomeDirectory()
and getDefaultDirectory()
. This class is used by the JFileChooser
for Swing interfaces. I know it doesn't directly point to the config and cache directories, but it might be a step in the right direction for you.
For my own apps, I take the next-best approach by trying to make all the config and settings contained within the application itself - ie. create a "config" directory under the directory where the application is installed. Even though its not a central location for config for the whole OS, at least it keeps it within the java application context.
Upvotes: 4
Reputation: 347184
We basically set up a utility class that provides this information, mostly based on the user.home
and os.name
system property.
We have a series of methods that allow us to build up a path location, something like...
SystemUtilities.getApplicationSettingsPath("Name of my awesome app");
Upvotes: 1