问题
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!
回答1:
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.
回答2:
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
回答3:
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).
来源:https://stackoverflow.com/questions/15004954/java-setting-preferences-backingstore-directory