Reading and Writing from/to Java Preferences fails on fresh Windows 8, - java

I have a Java application that reads from the Preferences by using:
Preferences prefs = Preferences.userNodeForPackage(MyClass.class);
prefs.get((String)key, "");
On a fresh Windows 8 machine this fails with:
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs
at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
Error code 5 is access denied.
I can't find anything I'm doing wrong. Google and SO searches give old results relating only to Windows Vista/7 where one was wrongly using systemRoot (How can I write System preferences with Java? Can I invoke UAC?).
The error can be "cured" by creating HKLM/Software/JavaSoft/Prefs and setting permissions to HKLM/Software/JavaSoft as mentioned here Java: java.util.Preferences Failing. But this is not something I can require my users to do when they install the program.
So I'm looking for a better solution. My last ditch effort is to simply write to file but I'd like to avoid that. This also seems related I'm trying to use Java Prefences from XML WITHOUT using Windows registry, but I see a Registry-related message but it was down voted without an answer.
At current I suspect a Win8 JVM bug...
Questions
Does any one know of a solution that doesn't involve writing files?
Why does the same code work perfectly fine in Windows 7 but fails miserably in Windows 8?

I recently started noticing a same warning and thought it means that registry cannot be written. But upon closer inspection I noticed that all preferences where successfully updated in HKEY_CURRENT_USER anyways. So I got curious why I'm seeing this warning.
It turned out that the culprit is this static member variable: WindowsPreferences.systemRoot
Looks like Java tries to initialize WindowsPreferences.systemRoot just in case it is used later on by the program, and that initialization obviously fails if the program is not ran as administrator.
Since you're using Preferences.userNodeForPackage(), you will never need the systemRoot, therefore you can safely ignore that warning.
Of course, this is a horrible practice that Java tries to initialize systemRoot when it's not requested.
Update: I tested this problem in various Java versions and concluded that this bug was introduced in Java 1.7.0_21. It worked fine in Java 1.7.0_17 simply because the installer of that version would create the "Pref" folder in registry! Of course even in that version if you were to delete "Pref" from registry then it would stop working, so it was a silly solution on the part of Oracle to begin with. I will fill a bug report.
Update 2: The warning message is not a bug. It seem to be the intended behavior: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6809488

Related

finding out gracefully the version of makeindex

I wrote something like a make-tool for latex documentation (in fact a maven plugin https://github.com/Reissner/maven-latex-plugin).
As this invokes just a bunch of command line tools
and i frequently have problems when new versions of those tools come up, i decided to provide a way to check the versions (in fact a goal).
E.g. i let my tool invoke pdflatex -v to get version of pdflatex.
This works fine for all tools but makeindex,
because makeindex offers no regular way, to get the version and nothing but that.
To find out by hand i just type makeindex and then ctrl-d on my bash shell.
The result is then
This is makeindex, version 2.15 [TeX Live 2020] (kpathsea + Thai support).
Scanning input file stdin...done (0 entries accepted, 0 rejected).
Nothing written in stdout.
Transcript written in stderr.
The keystroke ctrl-d seems to be tied to unicode 0004.
So from the bash shell, this works just fine.
Is there a way to do that with a java execution?
I tried to invoke (java string)
"makeindex \u0004" and related.
No success,... makeindex just quits with an error.
To be honest, I dont know why because from the terminal all is fine.
The last problem to solve: the procedure shall be platform independent.
Now tried some hack providing a dummy file.
But of course this is the contrary of elegant.
Assuming you use texlive, you could use
tlmgr info --only-installed --data="localrev" makeindex
which returns something like
52851
This is the revision information from the makeindex package you have installed. This is not the version number, but should be enough to detect if the installed version changes.

Getting "Unable to check for available memory." on Oracle DB 18c

I am trying to create a database in order to complete my self learning, but unfortunately I got unexpected error "Unable to check for available memory.", I am doing it using Database Configuration Assistant (DBCA).
My Oracle Database Version
Add the following parameter to bypass the error:
dbca -J-Doracle.assistants.dbca.validate.ConfigurationParams=false &
This error as it says, indicate that the "DBCA" can not check for available memory. This happens when "DBCA" does not have permission to check.
To bypass this error, run your Command Prompt as Administrator before lunching "DBCA".
Bypass via advanced setup
Run DBCA as admin and work your way through the advanced setup. I think this issue is avoided because it lets you manually enter, or use recommended defaults, for the memory section.
If anyone reading is running into the above issue and find that
dbca -J-Doracle.assistants.dbca.validate.ConfigurationParams=false &
didn't fix it for them, consider launching the advanced configuration setup for a database. (There's a radio button listed on the "Creation Mode" step). Its pretty straight forward and avoids the validation steps. That's how I got around the issue
On Windows 10, Oracle 19 setup. I installed Oracle without creating a database, because of this memory error.
Then
I ran cmd as administrator
I added "dbca -J-Doracle.assistants.dbca.validate.ConfigurationParams=false &" to the dbca.bat first if statement at the bottom of the file
I switched off all options.
I had the same problem, but when on the second stage of creating a database I select option "pluggable" and enter the name, it works correctly.
Steps:
Rename your PC Name
Restart and again start installation
I also had this problem. I had previously installed Java 18.0.1.1 X64 bits
By removing it and restarting the system, the problem was solved.
Apparently, Java should not be installed on the machine before creating the database.
For Me i was facing this issue while doing normal setup for Oracle Database 19c , and renaming your PC name did work for me . the issue can be understand as below -
In my case this was a permissions issue on the Oracle Home directory. If your Windows PC name is >= 16 characters in length, the name of the administrators group is affected, because only the first 15 characters are included. The mismatch between that first part of the name and the full name is what was causing the issue. DESKTOP-ASUS-ROG vs. DESKTOP-ASUS-RO in my case (notice the missing G). I renamed the PC to DESKTOPASUS, restarted the machine, and it worked without issue. The name discrepancy was apparent when looking at the security configuration of the folder when my system name was over max.
You can get your PC name by running hostname from the command line. If it's >= 16 characters, rename the PC to be <= 15 characters, and restart.
The underlying issue is indirectly discussed here in a different context: https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/naming-conventions-for-computer-domain-site-ou
Maximum name length: 15 characters.

Java: java.util.Preferences Failing

My program saves encrypted product key data to the computer with the java.util.Preferences class (system preferences, not user). The problem is, on both Windows and Linux (haven't tested on OSX, but it's probably the same), if I don't run the program with sudo or with Administrator privileges, it emits an exception or warning whenever it tries to read or save the data.
Obviously requiring the user to run the program with Admin privileges would be impractical. Optimally, I'd like the operating system to ask the user for permission.
This is quite silly, and removes half the purpose of Preferences. How can this be fixed?
Here's a summary what I need: I need my program to ask for permission from the operating system to save system settings.
Here is the error information
Here's the error when the when I try to read a node (because the node doesn't exist):
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences <init>
WARNING: Could not create windows registry node Software\JavaSoft\Prefs\myapp at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node Software\JavaSoft\Prefs\myapp at root 0x80000002.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node Software\JavaSoft\Prefs\myapp at root 0x80000002. Windows RegOpenKey(...) returned error code 2.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002.
Mar 18, 2011 9:41:15 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002. Windows RegOpenKey(...) returned error code 2.
And this is what happens when I try to write to a node:
Mar 18, 2011 9:43:11 AM java.util.prefs.WindowsPreferences WindowsRegOpenKey1
WARNING: Trying to recreate Windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002.
Mar 18, 2011 9:43:11 AM java.util.prefs.WindowsPreferences openKey
WARNING: Could not open windows registry node Software\JavaSoft\Prefs\myapp\subpackage at root 0x80000002. Windows RegOpenKey(...) returned error code 2.
Unfortunately most of the answers you got here are wrong ... at least slightly. In the sense that the symptom is being treated, not the cause.
Let's recap. Java Preferences has two "trees": the user tree and the system tree. You can write your own backend to Java Preferences (called a backing store) but few developers do, so you end up with the JDK's default backing store. On a Windows platform this means the Win Registry, more specifically:
The user tree is written into HKEY_CURRENT_USER\Software\JavaSoft\Prefs (the OS user always has write access here)
The system tree is written into HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs (only an OS user with admin privs has write access here)
In summary: As long as your code doesn't attempt to use the system tree, you should be fine and shouldn't need to mess with assigning privileges at the OS level. The system tree is meant for "all users on the host" and the user tree is meant for the specific logged-in user. In your case I'm confident you can suffice with the user tree, so that is really your solution. Don't go messing with privileges, running as Administrator, and what not.
.... but there's more. Suppose your code deliberately doesn't touch the Java Preferences system tree, as instructed. You'll then still see this warning on Windows:
WARNING [java.util.prefs]: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
So what is going on? Did I give you the wrong advice ? Not really. Stay with me.
Diving into the JDK source code you'll see that 0x80000002 means HKLM, i.e. the place in the Win Registry that shouldn't be touched. Your code never references the system tree and yet you still see this warning !?? (At this point you must be ripping all your hair out ... as I did)
Well, this is one of the rare occasions where there really is a JDK bug. You can read more about it in this answer by me which I encourage you to read if you are interested in why subtle bugs can go undetected in the JDK for years. The bug has existed ever since JDK 1.4 but has only recently been fixed and not yet backported to JDK 8 (update: the fix has now been backported to version 8u192 onwards of the JDK)
Best advice
Make sure your code only references the user tree, not the system tree. It is only fair that the OS requires all kinds of privs for you to write to a system-wide location. If you really need to write into such a location then there really is no other solution than assigning privs, executing as Administrator or what not.
Ignore the warning. It'll go away once you are on Java 8 update 192 or later. The warning can be safely ignored.
Alternatively you can try to programmatically silence the warning. It comes from the JDK's Platform Logger, so something like this should work, albeit I haven't tried it myself:
sun.util.logging.PlatformLogger platformLogger = PlatformLogger.getLogger("java.util.prefs");
platformLogger.setLevel(PlatformLogger.Level.OFF);
This link is work for me:
Resolving the problem
The work around is to login as the administrator and create the key HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs
It is possible to change the access rights of the registry entries. If you allow full access rights to
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs to everybody, everybody will see the same set of preferences and everybody will be able to change them globally. I am aware that this is not a solution for software that is installed by customers, but it might be of use for somebody.
Modifying the answer based on feedback.
This solution is probably overkill but ...
I suggest you change your store to write to a file instead of the registry (example)
A lot of java-based products ship with their own JVM. They do it so that they can run with a custom policy file (which would be needed in your case to write to a common location) and save on support issues (like outdated/untested JVM's being used)
Especially with Windows 7, the JVM has not by default the permission to write into the Windows registry where the backing store for java.util.prefs.preferences is located under MS-Windows.
When executing either the ReverseXSL transformer, or even the Regex tester program, one can get errors like: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx
This does prevent registering a license. It does not prevent the software to perform transformations in the free software mode.
Fixing the issue is simply a matter of granting the necessary permissions to the registry root key at stake.
Run regedit.exe as administrator (regedit.exe is located in the c:\Windows operating system root directory).
Go to key HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs. Right click to set permissions. Check a mark in the Full Control check box for the user(s) that need executing the reverseXSL software.
Just Run the application as administrator, or if using eclipse, run eclipse as administrator.
This has finally been patched, in January 2019, in Java SE Development Kit 8u202.
This is the Patch Set Update (PSU), as opposed to the Critical Patch Update (CPU), 8u201. The difference is explained here. (The page uses Java 7 as an example, but it gets the point across.)
The download can be found lower down on the "Java SE Development Kit 8" page. (https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)
The Answer by peterh already elaborated on the background, but I was searching for a fix and found it!
Since you can't touch the PlatformLogger itself, you have to void its message:
// get rid of the bugged Preferences warning
PrintStream err = System.err;
System.setErr(new PrintStream(new OutputStream() {
public void write(int b) {}
}));
Preferences PREFS = Preferences.userNodeForPackage(Settings.class);
System.setErr(err);
This way the annoying Warning is gone without leaving any traces. Note that you only need to do this at the point where you are referencing the Preferences API for the first time in your program.
The fix is to run JMeter as Administrator, it will create the registry key for you, then you can restart JMeter as a normal user and you won't have the warning anymore.JMeter official site - changes
The solution for me was not obvious - it was to update my cryptography security jars from Oracle as it seems to be a key length restriction (I didn't believe it was related, until I tried it).
Download from Oracle website
The download contains instructions and explains:
Due to import control restrictions of some countries, the version of
the JCE policy files that are bundled in the Java Runtime Environment,
or JRE(TM), 8 environment allow "strong" but limited cryptography to be
used. This download bundle (the one including this README file)
provides "unlimited strength" policy files which contain no
restrictions on cryptographic strengths.
This apparently applies to Registry keys too
Go to your registry and create JavaSoft\Prefs\myapp under HKEY_LOCAL_MACHINE-->SOFTWARE
Create key name as Prefs and in that create a sub key as myapp, this will resolve the issue.

Set write permissions on ProgramData subfolder using JNA

I have a program, written in Java, which originally used its directory in Program Files to write files accessible to all users of this program. This required our users to run as administrator all the time. In an effort to alleviate that, we decided to move files which needed to be written during regular usage to the ProgramData folder using the %ALLUSERSPROFILE% environment variable. Using a subfolder in this directory for our application works great if it is designated as writable during the installation process, which works fine using NSIS.
The problem comes with upgrading existing users. The Java File API provides setWritable but this does not appear to work after testing on development machines. It looks as though the new file API with Java 7 would solve this problem, but with no release date on the horizon I would rather not wait.
It seems the simplest solution would be to use JNA to call the appropriate Windows API call to set this directory writable. Since upgrading the software necessitates admin rights, similar to installing, it should let this change go through fine. However, I'm unsure where to start, having never used JNA before or the Windows API. Suggestions as to which Windows library to load and what functions to call would be appreciated, especially if someone has encountered a similar problem before.
Well, I'm glad you gave some background...You could use JNA, but the easier way would be to execute a call to the command-line utility cacls. It's included by default in Windows XP installations, I believe, so it should do the trick for you. Try Runtime.getRuntime().exec("C:\\Windows\\System32\\cacls.exe"+options)
Check out the documentation here -> http://technet.microsoft.com/en-us/library/bb490872.aspx
I use the follow line:
Runtime.getRuntime().exec( "C:\\Windows\\System32\\icacls.exe \"%ProgramData%\my application" /grant *S-1-5-32-545:(OI)(CI)(W,M)" );
S-1-5-32-545 is the SID for BUILTIN\Users because the name work only on English systems. https://support.microsoft.com/de-de/kb/163846
This give the BUILTIN\Users write access to all files in the given directory independent which user has create it.

Using java.util.prefs.Preferences in Jython

I seem to be having trouble storing Java preferences using a Jython script. If in Jython 2.5 beta I use:
clazz = Class.forName('mypackage.myclass')
prefs = Preferences.userNodeForPackage(clazz);
# or Preferences.userRoot()
prefs.put('propertyname', 'yes')
The preferences are not stored. If I then add:
prefs.flush()
I get
java.util.prefs.BackingStoreException: Couldn't get file lock.
I am currently running this on Linux and Unix using Java 1.6. I'm hoping that I'm missing something obvious, since my Java applications can successfully use java.util.prefs.Preferences on the same system.
Any help would be greatly appreciated.
In the comments on your question and the answer you state that it tries to write /etc/.java/.systemPrefs. I don't think that's actually right.
clazz = Class.forName('mypackage.myclass')
prefs = Preferences.userNodeForPackage(clazz);
# or Preferences.userRoot()
prefs.put('propertyname', 'yes')
You are using Preferences.userNodeForPackage, so you will get the .userPrefs.
These are located at /home/[user]/.java and should be writable.
With the systemPrefs you can get permission problems on linux. The preferences are stored in /etc/.java/.systemPrefs by default. If this directory isn't available(if you just copied the jre onto your system for example), the FileSystemPreferences class used to write
the preferences falls back to [java.home]/.systemPrefs.
To call prefs.flush() shouldn't be necessary, since the preferences are saved in a predefined interval and when your program terminates.
This seemed relevant.
Could it simply be that a file is not created or the owner on the file has insufficient permissions? Or something like that?

Categories

Resources