3

I need to create a persistent storage in my Java app so all users can access it. So I was studying about java.util.prefs.Preferences and using systemRoot() works fine to me on Windows, saving data at Register. But I'm really facing some problems on Linux (Ubuntu). I want to use a directory that other of our apps already uses: /usr/share/. So, I'm trying to redirect systemRoot default directory to /usr/share at runtime. Here's my code:

System.setProperty("java -Djava.util.prefs.systemRoot", "/usr/share/myfolder");
Preferences pref = Preferences.systemRoot().node("/usr/share/myfolder");

According to this site, I have to create .systemPrefs folder before execute this command line and its implicit that systemRoot() will use it.

When I execute my program, I get the following WARNING: java.util.prefs.FileSystemPreferences syncWorld WARNING Couldn't flush system prefs: java.util.prefs.BackingStoreException: /etc/.java/.systemPrefs/usr create failed.

So I'm assuming that System.setProperty isn't working. Any suggestion? Thanks in advance!

Leonardo
  • 1,263
  • 7
  • 20
  • 51
  • Instead of `System.setProperty("java -Djava.util.prefs.systemRoot", "/usr/share/myfolder");` try `System.setProperty("-Djava.util.prefs.systemRoot", "/usr/share/myfolder");` first thing when your `main()` starts – Bimalesh Jha Feb 21 '13 at 15:51
  • I tryed it, but no success. – Leonardo Feb 21 '13 at 17:55

3 Answers3

9

This is a really pesky issue Java running on *nix based servers.

I was able to solve it by using the following vm args:

-Djava.util.prefs.userRoot=/opt/apache-tomcat-7.0.50/uprefs -Djava.util.prefs.systemRoot=/opt/apache-tomcat-7.0.50/sprefs

One important note though on the systemRoot path is to create a sub-folder within it named .systemPrefs or it will not work.

Also, don't forget to chown -R these directories to the user running the java application (in my case it was tomcat).

okrunner
  • 3,083
  • 29
  • 22
  • mkdir .systemPrefs very important – niken May 30 '14 at 18:17
  • 1
    And according to http://stackoverflow.com/questions/9520987/tomcat-7-where-do-i-set-system-properties you can set these properties in `tomcat7/conf/catalina.properties` – Sam Barnum Oct 12 '16 at 05:01
7

Bimalesh suggested that instead of

System.setProperty("java -Djava.util.prefs.systemRoot", "/usr/share/myfolder"), that you say

System.setProperty("-Djava.util.prefs.systemRoot", "/usr/share/myfolder").

But the name of the property that you are trying to set is java.util.prefs.systemRoot, and not -Djava.util.prefs.systemRoot, so you should do

System.setProperty("java.util.prefs.systemRoot", "/usr/share/myfolder");

If that doesn't work, try adding the "-D" switch to the command line that starts your program. That is where java -D... should go. The command would start with

java -Djava.util.prefs.systemRoot=/usr/share/myfolder

Grzegorz Piwowarek
  • 13,172
  • 8
  • 62
  • 93
StevieP
  • 71
  • 1
  • 1
5

In a Linux system, the System root preference node will be under /etc. This is due to history, and is a standard that is regulated by the Linux Standard Base. Any non-system preferences can go in other locations, but it is a violation of the design of the operating system to have system preference go elsewhere.

Odds are your define is ineffective in a Linux system because it fails to start at /etc. Apparently something in the Java code defers to the specification of the operating system over your decision to re-base the preference root.

Typically such files are protected against modification by not being world (or even most user) writeable. This means that for users to have access to Preferences, they should go under

 Preferences.userRoot()

Which will place them in hidden directories just off their home directory (where they will have modification privileges).

If your want any user to read any other user's preferences (the description sounds like you might) then you will need to have an installer that runs as a sufficiently authorized user (typically root) to make the required directory under /etc and change it's permissions to be world writeable.

Typically files under /etc are not world writable as users changing other's user's setting is then possible, and considered a type of security breach of the user's expected environment. For example, a careless employee (or a disgruntled one) could wipe out all other user's preferences in one stroke.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • I read that I can choose a custom directory if I use `Properties` instead of `Preferences`. Is that true? Is there any depracation on using `Properties`? – Leonardo Feb 21 '13 at 20:01
  • Yes, because properties are not constrained by the operating system. In other words, properties will just be files, not in the registry or the Linux equivalent of the registry (the /etc directory) – Edwin Buck Feb 21 '13 at 20:13
  • OK... but is there any disadvantage using `Properties`? It's still persistent, right? I read about best practicing using `Preferences` instead of `Properties`. – Leonardo Feb 21 '13 at 20:23
  • properties are more like ini files, they only have a key (not really a true path) and a possible value. Since they are files, they are not in the registry. This might mean something to you depending on how good you want the application to integrate with the operating system. I would use Preferences without a reasson not to, but asking to not put system wide configuration parameters for you application in /etc is like me asking to politely park my car in you living room. It isn't even considered a system wide config outside of /etc. – Edwin Buck Feb 21 '13 at 21:41
  • Thanks for your time and patience Edwin! I will use Preferences in its default directory, just providing due permissions. – Leonardo Feb 22 '13 at 14:09
  • @Leonardo You're welcome. Glad to hear you found the solution you seek. Also remember that the parameter to Preferences is a relative path to the root of the preference tree, not a file system path. "/application/system/setting" would work just as well. – Edwin Buck Feb 23 '13 at 13:40