In UNIX and its derivatives, application config files live under /etc/, whereas they live elsewhere on Windows and other systems. The philosophy behind java is "Write once, run everywhere" and an app ideally shouldn't have to care what OS it's on. But I want my application to load a config file on startup and I need to provide a path. Right now, I'm loading different file locations switching off of the OS name, but this doesn't feel like it's best practices for Java. How do I reconcile this?
- 1When it should be portable I see nothing wrong with having it in the application directory itself.user432– user4322014-06-12 18:43:29 +00:00Commented Jun 12, 2014 at 18:43
- Java already has a preferences API that handles OS differences. docs.oracle.com/javase/7/docs/api/java/util/prefs/…Dave Newton– Dave Newton2014-06-12 18:49:02 +00:00Commented Jun 12, 2014 at 18:49
3 Answers
When I am making a game/app I just put a resources folder in the same path as the app. For example in the code, the directory would be "res/config.yml". In the same folder as the jar you put the resource folder named "res". you then put the file in the res file. So the app should get the file.
Comments
I usually put configuration files in a directory .<appName> (note the leading dot) in the user home, which is read at runtime via System.getProperty("user.home"). This is the expected location for Linux users, while on Windows it feels a bit exotic (compared with profile directories like AppData/Local or AppData/Roaming) even if it's an extremely popular choice for cross-platform tools. Using the current user's home means you won't usually have troubles with filesystem access rights, and using user.home is preferred instead of a custom property because it's provided out of the box by the system (and still it can be overridden)
Another approach is using the installation directory, but then you have to use an environment variable that points to that, like $APP_HOME, because it can't generally be inferred while the application is running (actually you can get the installation directory pretty easily for typical JAR deployments by playing with URLs returned by the main ClassLoader, but I consider it a hack and think it shouldn't be used). Your application can read the variable with System.getenv("APP_HOME"), and this variable must be set by the platform-dependent scripts you provide to start your application. This strategy has the downside that the current user may not have the rights to read/write to the named directory.
Comments
In our application we use different locations for configuration on each OS.
On Linux
/etc/applicationname
On Windows
[Use Selected Install Dir]/conf
We control where the application looks via a system property
-Dconf.dir=path
I don't necessarily think there is a correct answer in this case.