node-java: OS X JDK 1.7 failing to load

I’m using OS X 10.9 with Sun’s JDK 1.7 and always get the following error:

JavaVM: Failed to load JVM: /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/bundle/Libraries/libserver.dylib
JavaVM FATAL: Failed to load the jvm library.
JavaVM: Failed to load JVM: /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/bundle/Libraries/libserver.dylib
JavaVM FATAL: Failed to load the jvm library.
Segmentation fault: 11

Indeed, the folder /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/bundle does not exist on my system.

I’m using Sun’s JDK 1.7, and do not have Apple’s installed. The output of java -version is:

java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

About this issue

  • Original URL
  • State: closed
  • Created 11 years ago
  • Comments: 54 (24 by maintainers)

Commits related to this issue

Most upvoted comments

OK. The answer is crap, but at least it makes sense now.

Debugging finally lead me to the JNI_CreateJavaVM() line in java.cpp. A quick google had this as the top result: https://bugs.eclipse.org/bugs/show_bug.cgi?id=411361

The problem, once you get towards the end of the bug report, is that Oracle’s JDK doesn’t advertise itself as supporting JNI. So even though node-java links to JAVA_HOME correctly, when the JNI_CreateJavaVM call is made the system sees that the linked JDK doesn’t “support” JNI and switches to Java 6 instead.

/headdesk

There are two solutions I’ve found from various sources:

  • manually enable JNI - edit /Library/Java/JavaVirtualMachines/<version>.jdk/Contents/Info.plist (a simple XML file) and add JNI as an option in JVMCapabilities
  • (does not work in 10.10) trick the system into thinking you have JDK6, by symlinking the new java to where JDK6 normally lives (sudo ln -s /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk /System/Library/Java/JavaVirtualMachines/1.6.0.jdk)

Both work, I’ve tested them, but neither is a good solution and both require root access to update the fix upon upgrading the JDK.

The eclipse bug report talks about a way to solve it but I don’t think their fix really applies to the c++ code here. I suspect there is very little you can do to work around Oracle’s issue here.

.

On the plus side, I know more about the whole process now and I don’t think your jvm_dll_path.json fix is necessary. binding.gyp already uses findJavaHome.js and when I run npm install --verbose the build links to my Oracle JDK even without JAVA_HOME set.

@TheSpyder @jsdevel There is another, better way to avoid this horrible issue: load libjli before loading libjvm. The ImageJ project uses this trick for its launcher successfully. And here is another example of a project using this solution. A big advantage of this approach is that users do not need to manually tweak their Java installations in order to get up and running.

Interesting. That ImageJ dev seems to like to rant about Apple. I’m amused that there were three working methods to fix the same issue; perhaps the config patch only worked by accident.

Your second link (xamarin) points to this OpenJDK bug, which was fixed in Java 9: https://bugs.openjdk.java.net/browse/JDK-7131356

So while this change is probably harmless on new releases, it seems only necessary on now-unsupported versions of Java (Java 8 fell out of Oracle support in Jan 2019).

A big advantage of this approach is that users do not need to manually tweak their Java installations in order to get up and running.

Note that manual patching wasn’t required for homebrew users, the cask did that in a post install script. Although that was been removed after someone discovered it didn’t makes sense in Java 11.

nice @ctrueden ! can you open a pr?

@TheSpyder Thanks for your solution, adding JNI also works for me! Thanks !!