Working with Windows registry using java.util.prefs.Preferences - java

I have some questions about the registry.
We have
Preferences p = Preferences.userRoot();
If we execute
p.nodeExists("/HKEY_CURRENT_USER/Software/Policies/Microsoft")
it will return true.
After it:
p = p.node("/HKEY_CURRENT_USER/Software/Policies");
for(String s : p.childrenNames()){
System.out.println(">" + s);
}
We see that it has one child: "Windows". But
p.nodeExists("/HKEY_CURRENT_USER/Software/Policies/Microsoft/Windows")
returns false. Why?
Thanks.
UPDATE
Ok. I have some mistakes. Let me try again: Why does
p.nodeExists("/HKEY_CURRENT_USER/Software/Policies/Microsoft/Windows")
return false?

If you execute the code lines shown, in the order shown, when you get to the line
p.nodeExists("/HKEY_CURRENT_USER/Software/Policies/Microsoft/Windows")
p does not anymore point to the user root, but to "/HKEY_CURRENT_USER/Software/Policies".
Btw you have a probable omission in your third code sample:
p = p.node("/HKEY_CURRENT_USER/Software/Policies");
should be
p = p.node("/HKEY_CURRENT_USER/Software/Policies/Microsoft");

I stumbled on this one today. The answer you've accepted is completely wrong.
You seem to be under the impression that Java Preferences is a general tool to manipulate the Windows Registry. It is not. It just so happens that the default implementation of Preferences on the Windows platform happens to store its data in the Windows Registry.
The implementation on Windows stores stuff under the following Registry paths:
For systemRoot: HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs
For userRoot : HKEY_CURRENT_USER\Software\JavaSoft\Prefs
(note: The registry paths changes a bit if you are using a 32bit JRE on a 64-bit OS but that has nothing to do with Java and everything to do with Windows. Sun's code always use the above paths.)
The point to make is that you can maybe use Java Preferences interface to read or change values in the Windows Registry but only below the above registry paths. The reason why I say 'maybe' is that this is just how it happens to be at the moment. Sun/Oracle could at any point in time decide to not to use the Windows Registry or use the Windows Registry but without using sub-nodes, i.e. store everything in one big XML string or something. The point is that Java Preferences is designed to shield you from this.
A lot of Java software that use the Java Preferences provide their own implementation (which is pretty simple to do) to avoid Sun's default implementation that uses the Windows Registry. Not everyone can write to the Windows Registry these days so that was a pretty bad design decision on Sun's part. Fortunately very easy to change.

Related

How do I track what java is actually looking for as it traverses CLASSPATH?

How is the java utility that begins the process of launching a class told to "spill its guts" on what it's doing as it tries to load classes?
In particular, what file paths is it TRYING to access, only to perhaps discover whatever it's looking for is not there, at least as it interprets the specification given? There was a way to get that information, but I can't find it now.
Note that this is Java version "1.8.0_333" on Windows 10.
I've tried every flag known to me, via the -h and -X flags, and I strongly suspect what I'm looking for is (was) an X flag that's been removed, just as the -X help output warns. And so, there must be an OS way to figure this out, I sure hope!
You might ask why? Whatever for? What are you trying to do? Well, that's the bulk of this question's text. To wit:
As one of the very early users of Java (I started with 1.1) way back in the '90s, I had an issue moving an application suite I'd written for my company on Linux to MS Windows and I got it working by using Cygwin. Along the way, this same sort of issue came up and I quite vividly recall having found a mechanism for getting the Java launcher to articulate just what file specifications - paths - it was actually using in searching for the appropriate class. And through using this, I found that the CLASSPATH was being specified incorrectly, and with some experimentation, I got it working reliably. Now I need to do that again!
This flag I'd used was immensely helpful in figuring out just what the file specification format CLASSPATH needed to be (we're not talking semicolons here) this combination of OS, Java, and Cygwin. After some hours of what I hope was reasonable hunting, I'm wondering if this capability has been removed at some point? Either that or "I'm looking for the wrong thing." Heck, since the source is available (I think!), maybe some brave soul has hacked the java utility to do such a thing?
It may help to understand that for this application I wrote for my company, it was a major goal to have the source work pretty much the same on all Windows and Linux / Unix systems (and at the time, macOS), and just use a configuration file to tell the code what's different. And that wasn't easy to figure out, but with this flag, it wasn't that hard, either.
But, unfortunately, I haven't needed this knowledge since I figured it all out all those years ago, and apparently, this little kernel of knowledge is very hard to find today. Or, it's no longer pertinent to the modern version(s).
I don't think this has anything much to do with the actual problem, but it may help in people's thinking if they understood the scenario: The current situation is that I have a fully functional installation of this software on Windows 7 to use as a comparison for how to configure things on Windows 10 (and hopefully younger). The Windows 7 is running a pretty modern Cygwin installation and very nearly the most modern Java - just a sub-version away from the new installation from last week on a Windows 10 box. (Everything's bright and shiny new on the new box.)
The required format for CLASSPATH on the nearly identical but fully functional Windows 7 system is:
CLASSPATH="C:/opt/OurInstallationDir/lib"
And that's it.
This value is picked up in several places as the code later needs to launch Java itself to do some unusual things. However, the java command that gets it all going is launched from a C program - not that that matters for this problem - but the C program (compiled under Cygwin, but perfectly runnable from any Windows environment) helps ensure that the Java environment is secured (policy file contents and so forth) before getting into Java, else it refuses. And this program on Windows 11 launches Java just fine, it's just giving it a CLASSPATH that isn't useful, apparently, even though the files are there where they should be, etc.
Configuring things as before just doesn't work, even from the command line. No version of specifying CLASSPATH seems to work if it's more than a dot; the only thing that works, is being in the /lib directory when starting and using "-cp ." ... But that's just not going to fly for so many reasons! To be a little more clear, I've tried reversing the slashes, using /cygdrive/c/, and whatever else I could think of. But, at least we know that if you're in the directory and use -cp, it will find and launch the program. So, there's nothing wrong with the Java, just pointing the java utility at it.
Again: How is the java utility that begins the process of launching a class told to "spill its guts" on what it's doing as it's trying to load classes?
You use this construct on the JVM:
java -XX:+TraceClassPaths -cp "C:\opt\SomeDirectory\lib" myClass
I was able to get confirmation of what Java was using, not only for my CLASSPATH, but "internally" by using the above.
The fact that it echoed back both what I was doing and what it was doing somehow gave me the insight to check everything about it. Java itself doesn't work (at all) if it's installed in a location that it thinks has a link in it, and it's own fetches go right back to the system disk specification.
From that I found that Java on Windows won't take a CLASSPATH that has a link in it!
Simply ensuring that the whole tree was specified "from the top" of the drive it's on works. If it's not, it won't.
It's now working happily using the syntax noted above.
This is quite different from every other application I've seen on Windows. But, well, it's Java!
This really came from a pointer from Mark Rotteveel who commented above about this article: How to track when class is loaded and destroyed in jvm? And therein I learned how to get the list of all the options the presently in-use JVM supports. All Java developers should be aware of this in my opinion, so thanks to Mark for that.

Apparently java doesn't have the same nashorn.jar for Linux and Windows

I'm trying to configure my workspace from windows in linux.
This code which is OK in windows:
jdk.nashorn.internal.parser.JSONParser p = new jdk.nashorn.internal.parser.JSONParser(s, null);
gets the following error under linux:
constructor JSONParser in class JSONParser cannot be applied to different types
And when I look at the source code under Linux and at the source code under Windows, I see very clear that the same class is different.
Does anyone know why this? If so, WORA principle isn't applied here, which seems pretty confusing to me.
With the hints given by different users, especially #FedericoklezCulloca, I managed to fix my problem. I would state the following points bellow:
Use only "exposed" interface from Java API and avoid using restricted one.
I had to get exactly the same version of JDK (the same vendor, of course) in linux. Than it worked.

How can I change the input method in a Java program on Linux?

I am writing a Java application, in which I need to be able to change input languages (say, from English to Japanese) on user request. Normally, a user would just go into the Windows/Linux system settings and change it there. However, for this particular application, the user will not have access to these menus.
I've done quite a bit of research on SO and elsewhere. The solutions I've found indicate using the InputContext.selectInputMethod([locale]) method. This works on Windows (using the IMEs in the Windows registry), but I can't seem to get it to work on Linux (it always returns false, even when selecting a locale for which I have the appropriate language packs installed).
Ideally, I'd like to have a completely platform independent implementation, but I at least need it to work on Linux. So what am I missing? Do I need to install input methods as an extension? Are there built in IMEs I can use? It seems like this wouldn't be too difficult to implement, but I've found surprisingly little concrete information.
Thanks in advance for the feedback!

Operating System Detection by Java or JavaScript

I need to detect OS name & version in Java. That I can do by
String os_name = System.getProperty("os.name", "");
String os_version = System.getProperty("os.version", "");
but the problem is that this is not reliable. Sometimes it returns incorrect information, and I can't detect all operating systems, except the most popular Windows, MacOS, Linux etc, and this even provides wrong information in the case of 64 bit operating systems. I need to detect any OS with any kind of specification. I am unable to find the right solution for this.
Maybe I can do this with JavaScript? If it's impossible in Java then please tell me how to do it with JavaScript.
Any input or suggestions highly appreciated.
Thanks in advance.
Best regards,
**Nilanjan Chakraborty
In Java there are some common bugs while guessing the operating system:
http://bugs.sun.com/view_bug.do?bug_id=6819886
Maybe in newer versions of Java, they are solved.
In Javascript you can use navigator.appVersion:
// This script sets OSName variable as follows:
// "Windows" for all versions of Windows
// "MacOS" for all versions of Macintosh OS
// "Linux" for all versions of Linux
// "UNIX" for all other UNIX flavors
// "Unknown OS" indicates failure to detect the OS
var OSName="Unknown OS";
if (navigator.appVersion.indexOf("Win")!=-1) OSName="Windows";
if (navigator.appVersion.indexOf("Mac")!=-1) OSName="MacOS";
if (navigator.appVersion.indexOf("X11")!=-1) OSName="UNIX";
if (navigator.appVersion.indexOf("Linux")!=-1) OSName="Linux";
document.write('Your OS: '+OSName);
All the browser's I'm familiar with report the OS from the navigator object (javascript)-
alert(navigator.platform)//returns string- eg'Win64'
There are not too much ways to detect this. Most probably it will work correctly 99% of the time.
However if you are looking for another method, you can consider checking some magic file paths. i.e:
if /etc or /proc folders exists, it is Linux
if C:\Windows\ exists, it is Windows.
etc.
However they won't be again reliable since /etc /proc may also exist in Mac.
If you want to find exact name of the OS, you can look at /etc/issue file in Unix-Linux-Mac and you can use "os.name" (which you claim that it is inaccurate) or WMI (windows management instrument) to retrieve OS name+version.

How to tell if a directory is remotely mounted using Java

Is there a way to determine programatically if a particular directory is actually remotely mounted? Can this be done with Java, and if not can it be done with native C code over JNI?
Since this is Java it could be running under Linux or Windows or Mac, so a proper solution needs to address all these platforms. (Again if its multiple separate solutions with C over JNI thats ok). And there may be different cases like with NFS or samba or anything else.
Thanks.
for Linux, and possibly Macintosh, you can use system library through JNI.
The relevant system call is getmntent, described here.
There is a field in mntent you can use to check to see if mount point is from device or a server, mnt_fsname, in a similar field you can get filesystem type, `mnt_type"
For Linux, you can parse /etc/mtab to find the filesystem type (nfs, smb, etc.) and match it against known network filesystem types in your program.
EDIT: column 2 is what you want in /etc/mtab
I need that as well and might end up implementing it using this command:
df -k
That works under Linux, Mac OS and Solaris.
Maybe this is something else that will be added to JDK 7 since they're also going to support symlinks.

Categories