Java - Setting Preferences backingstore directory

2020-03-25 14:12发布

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!

3条回答
爱情/是我丢掉的垃圾
2楼-- · 2020-03-25 14:35

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).

查看更多
叛逆
3楼-- · 2020-03-25 14:41

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.

查看更多
手持菜刀,她持情操
4楼-- · 2020-03-25 14:42

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

查看更多
登录 后发表回答