Using Oracle Java VM in-process on Mac - java

This is a followup to this question.
MacOS X has the java command under /usr/bin. If one installs the JRE from Oracle, it doesn't work - claims there's no Java runtime, and offers to download and install Apple's runtime. But if you first run
export JAVA_HOME=/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home
then java works as expected. That's where Oracle JRE installs itself.
Now I'd like to use the Oracle Java VM in-process, and I can't - the "You need Java runtime" error message keeps popping up, even with JAVA_HOME being set.
Linking against the JavaVM framework causes the message on app startup, even before main().
Trying to dynamically load /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/server/libjvm.dylib and invoke JNI_CreateJavaVM causes the same message during the method call.
EDIT: the java command does it somehow, after all. I've poked around with a debugger, it does invoke JNI_CreateJavaVM at some point. I've even mimicked the arguments (there's one extra one, -Dsun.java.launcher=SUN_STANDARD), it didn't make any difference.

Found the answer here.
Instead of loading libjvm.dylib, one needs to load /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/jli/libjli.dylib. It exports JNI_CreateJavaVM, too. Call that one, and it'll work as expected.
Works even with JAVA_HOME not being set.
Future warning: Oracle says that since Java 1.9, the browser plugin technology will no longer be supported. With that in mind, Oracle JRE's home in version 1.9 might not be under Internet Plug-Ins anymore.

Related

JDK and JRE version confusion

I've been working with Java for a bit now and the JDK/JRE version has given me quite a bit of trouble lately. I am developing using the Intellij IDEA IDE and it of course uses the latest version of the JDK, 14. However when I attempt to execute software compiled with JDK 14 outside the IDE, I get an error that the JRE isn't new enough to run this software. So I updated Java on my computer and another machine and attempt to run again without any success. After some digging, I tweaked my machine to use the JRE included in the JDK 14 which is compatible.
However it is kind of odd that I had to do that, one would think that the latest version of java should of been enough to run applications made with the latest version of the JDK (14). Right now Java is version 8 build 251 and says there is no newer update available. If JDK 14 is out for a while now, why would they not update the version of Java they ship?
The problem is partially solved, as only the machine I am using for development is capable of executing the created applications. Other people I've sent them to have been unable to run them, despite having the latest version of java. Also it is a pain to get the latest JDK, especially when having limited experience on how to get rid of old versions, change path point to the latest version, get the right package (open/oracle JDK) and do that for windows and several distrubutions of linux. What is going on? Did I get Java from the wrong place and everyone else as well? Why are oracle doing this and why are there no java updates since clearly there exists a newer version?
Starting with Java-11, separate JRE does not exist anymore. In other words, if you are using Java-11 or above, you should care about JDK only.
You should uninstall JRE-8 from your machine and make sure your JDK-14 bin folder in the PATH variable. Some application even requires JAVA_HOME to work and therefore you should make sure that your system has an environment variable called JAVA_HOME and its value set to the root folder of JDK-14 (i.e. one level above your JDK bin).
Q: What should my clients do to run my application compiled on JDK-14?
Ans: Your clients must install JDK-14. Also, check this thread for some alternatives.
You're confusing how IntelliJ or JDK are used on the OS. IntelliJ, now, often comes with its JDK binaries (but even this can be configured, IntelliJ can be configured to use any JDK/JRE build you'll provide to it); however, if you run your Java application out of IntelliJ, most likely you're using Java installed locally on your OS, which might be referenced via your JAVA_HOME environment variable.
I'd suggest to:
Check java -version in your shell (and hence you'll see what JVM instance your OS spins up when you run a Java application);
Check where java (on Windows, or which - on Linux) in your shell, to see all the Java binaries available on your OS.
Try to uninstall Java SE Development Kit and Java JRE(if you have both in your machine) and reinstall both again, JDK and JRE both, I am sharing my google drive link where you can find the latest version of both JDK and JRE and when you are done installing, add there bin folder path in the Environment Variables of your machine.

Compiling JNI application on Mac OSX - No Java Runtime Present

I have a C++ application that uses JNI to create a Java virtual machine. I have the latest version of Java installed - JDK 8-144. If I run "java -version" it comes up and tells me that Java Hotspot 8 is the JVM. I have JAVA_HOME defined in the .profile file, and it works -- JAVA_HOME points to the JDK8-144 folder.
My application is including jni.h from the latest JDK. Our code creates a JVM with the JNI_VERSION_1_8 version flag. On Windows, this compiles and works perfectly.
The problem is that when we compile this code on the Mac, and use the JVM Framework for linking, we end up with an executable that, when run, says that there's "No Java Runtime present" and a dialog comes up that says we need to install the Version 6 JVM. This happens if we run the application from either the Bash terminal or from XCode.
I've researched this and there are other people who have had this identical issue. Everyone seems to suggest that JAVA_HOME needs to be pointing to the correct place, and mine is. Again, java -version works correctly. The whole thing is quite puzzling.
Does anyone know the right way to solve this? I've tried two different Macs with identical results. They are both running the latest version of macOS Sierra.
Thanks!
Dan

Native library bluecove not available on Mac

I downloaded bluecove-2.1.0.jar and added it as an external JAR on my Eclipse project. I am following this tutorial for using Bluetooth with Android: http://luugiathuy.com/2011/02/android-java-bluetooth/
When I run the program intended for my laptop to act as a server, I get an error stating 'Native library bluecove not available'. I made sure bluetooth was enabled by typing 'bluetooth' in Spotlight (which took me to Bluetooth File Exchange and allowed me to select a file to send).
I saw another Stackoverflow post stating that BlueCove requires 32-bit JVM to run so I added the -d32 argument under VM arguments in the run configuration. When I ran it, I got another error stating
"Error: This Java instance does not support a 32-bit JVM.
Please install the desired version."
Does anyone have any ideas on how to fix this?
Try using OpenJDK rather than the Oracle JDK. This supports the -d32 arguments so it ought to work for you.
OpenJDK may work as Mike suggested but its installation process was rather involved. I found a workaround by installing an earlier version of Eclipse that supported 32-bit OS X versions and setting -d32 in the VM arguments there worked without issues. Be sure to keep the earlier version of Eclipse in a separate folder so it doesn't overwrite your recent version.
I installed the 32-bit version of Eclipse Kepler from here: https://eclipse.org/downloads/packages/release/Kepler/SR2
Of course, Bluecove had some other issues with IOBluetooth device not found (since Apple removed that since OS X 10.8 I believe), for which you can check here for a possible solution.

Java 7 update 25 silent installation fails if another version of java already exists

I am trying to install java from install shield script
1) I have no other version of Java in my PC and When I install Java 7 silently it installs correctly
2) If I have any other java version already installed in my PC and I try to install Java 7 silently it fails
Do we have an option to install java silently even though it detects another version of java is already installed?
Why is the install failing?
The first thing you should probably do is find out for sure why the JRE install is failing.
The Windows version of it takes some command-line parameters that may be of some use to you. For logging /L <path_to_log> will create a log file.
I usually extract the MSI from the EXE's that Oracle makes available. Using the MSI directly allows you to specify install properties without having to please InstallShield's goofy command-line syntax. If you launch the EXE downloaded from Oracle (but don't proceed—just let it extract itself), look in the user's AppData\LocalLow\Sun\Java directory for a dir corresponding to the version of Java whose installer you just launched (e.g. jre1.7.0_25). Get the MSI and other files from there.
With the MSI, you can specify logging options on the command-line, like msiexec /i <jre_msi_file> /lxv* C:\temp\jre_install.log.
I'm pretty sure I've seen instances where JRE installers will effectively block the installation of an older ("less secure") version. It might be that this is what's happening in your case. You should see an indication of such in the install log file. If that's the case, I think there's a registry key that you can remove to "unblock" the install.
Static vs. Patch-in-Place
Another potential source of trouble is the type of install you want (or previously used). Oracle has two install methods that you may need to expressly specify when you install it.
A patch-in-place install always leaves a single version of the JRE installed, removing the old one (or upgrading it—I'm not certain about the details of how it's done) and leaving the new one in its place. This is the default behavior, and is probably what you will want to use. Browsers can only use one version of Java at a time, so there's not much reason to have older versions around if you're only interested in having Java in the browser.
A static install creates a new install of Java for every unique version number. This would be useful if you needed to be able to choose among some precise versions of Java for specific applications. Programs relying on quirky/undocumented behavior of specific Java VM implementations might need to use such an installation. In general, though, this kind of thing should be avoided, if for no other reason, than to avoid leaving JRE versions with known (and actively exploited) security vulnerabilities.
You can specify which install type on the command-line with STATIC=0 (a patch-in-place install) or STATIC=1. This should work with either the EXE or the MSI.

Understanding Oracle's Java on Mac

I've been using Java on OS X for many, many years and recently when Apple stopped including Java by default I let the OS go and install it for me (Apple's variety, of course).
So now I'm using OS X 10.8 and I need to install Java 7 so I just got Oracle's Update 15 in DMG form and ran the installer. It updated my /usr/bin/java (and related files) to point here:
/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
Tracing this back to '/System/Library/Frameworks/JavaVM.framework/Versions' everything either points to 'Current' or 'CurrentJDK', the former being a link to 'A' (which is Oracle's Java 7, from what I can tell, not sure why it is 'A') and the latter being a link to Apple's Java 6 in '/System/Library/Java/JavaVirtualMachines/1.6.0.jdk'.
Now this is all really confusing but this isn't even my question yet. It appears there is a Java 7 installed here:
/System/Library/Frameworks/JavaVM.framework/Versions/A
But there is also a Java 7 installed here:
/Library/Java/JavaVirtualMachines/jdk1.7.0_15.jdk
Finding 'java' in both and printing out the version yields the same version and build (java version "1.7.0_15"), however, when hashing the files they are different.
So does this mean Oracle installed Java 7 in two different places? If so, why? Which am I supposed to use? And why do some things still point to Java 6 (CurrentJDK).
I've looked on Oracle's website but nothing there clears anything up.
Oracle's JVM is only installed in one location. You've been misled!
As you've noted, the Java commands in /usr/bin are symlinks to binaries in /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands. The binaries within that directory are stub applications that determine which Java VM to use*, and then exec the corresponding real binary within that VM version. This is why all of the binaries within /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands are almost identical in size, despite the fact that you'd expect them to be implementing quite different functionality.
You can see this in action by using dtrace:
mrowe#angara:~$ sudo dtrace -n 'syscall::posix_spawn:entry { trace(copyinstr(arg1)); }' -c "/usr/bin/java -version"
dtrace: description 'syscall::posix_spawn:entry ' matched 1 probe
dtrace: pid 44727 has exited
CPU ID FUNCTION:NAME
8 619 posix_spawn:entry /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java
The given dtrace invocation prints out the path argument to posix_spawn when it is called by java -version. In my case the stub application has found Apple's Java 1.6 runtime in /System/Library/Java/JavaVirtualMachines/1.6.0.jdk and is invoking that version of the java command.
The stub binaries also have another benefit: when they detect that no Java VM is installed they will prompt the user to install one.
As for the CurrentJDK symlink, as best as I can tell this for sake of backwards-compatibility with the past when Apple was the only source of the JVM on OS X.
* A combination of factors are considered when determining which Java VM should be used. JAVA_HOME is used if set (try JAVA_HOME=/tmp java). If JAVA_HOME is not set then the list of all virtual machines on the system is discovered. The JAVA_VERSION and JAVA_ARCH environment variables are used, if set, to filter the list of virtual machines to a particular version and supported architecture. The resulting list is then sorted by architecture (preferring 64-bit over 32-bit) and version (newer is better), and the best match is returned.
The Oracle Java 7 JRE (i.e. the one that is used by the web browser plugin to run applets and Java Web Start) installs itself in /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home, and it is this one that any automatic updates will affect. The JDK (the one you download from http://www.oracle.com/technetwork/java/javase/downloads/index.html) installs by creating a directory under /Library/Java/JavaVirtualMachines, and it's up to you to update this yourself. You can have multiple JDK versions installed side by side but only one "public" JRE under JavaAppletPlugin.plugin (which will correspond to the latest installed JDK or a later version if it has been auto-updated since).
As explained by bdash, the commands under /usr/bin are stubs that delegate to whichever JDK/JRE is pointed to by the JAVA_HOME environment variable, or if that is not set then they will pick the most appropriate Java to run. You can use /usr/libexec/java_home to see which one the stubs would pick. If no Java is installed the stubs will offer to install the latest Apple Java 6 (as far as I know they will not offer to install Java 7).
I find this post:
https://developer.apple.com/library/mac/qa/qa1170/_index.html
The /usr/libexec/java_home tool dynamically finds the top Java version specified in Java Preferences for the current user.

Categories

Resources