Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

OS X JDK 1.7 failing to load #90

Closed
jahewson opened this Issue Nov 14, 2013 · 50 comments

Comments

Projects
None yet
9 participants

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

joewhite86 commented Nov 21, 2013

At which point in your code the error comes up?

Tested on my system (OS X 10.9 with 1.7.0_45) right now and it works.

My code was simply:

var java = require("java");
var list = java.newInstanceSync("java.util.ArrayList");

The error occurs on line 2 (determined by inserting a console.log) there is no stack trace.

Contributor

joewhite86 commented Nov 22, 2013

Seems like the java environment isn't set up correctly on your system. The only place I found this file on mine is: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries/libserver.dylib, which is the pre-installed java version that came with previous versions of OS X.

What are your Java environment variables? (JAVA_HOME, ...)

OS X 10.9 (Mavericks) does not come with Java installed. The Apple version of Java 1.6 is available as an update but not Java 1.7, which must be downloaded from Oracle.

I do not have any environmental variables set regarding Java, there is no JAVA_HOME or Java directories in the PATH as Oracle's installer did not set them.

I think the problem may be that node-java assumes that Apple's version of Java is installed, which is not necessarily true.

Contributor

joewhite86 commented Nov 22, 2013

No node-java works with both, pre-installed and others. If you upgraded from previous versions of osx you can indeed have the pre-installed jdk under /System/Library.

Try setting JAVA_HOME

I have a fresh installation of Mavericks, not an upgrade. node-java needs to work out of the box with Oracle Java 7...

I've done some investigating - as you said the JDK under /System/Library/Java is present on Mavericks, but I think it's intended for system use (or is this just where Apple keeps its JDK?):

ls /System/Library/Java/JavaVirtualMachines
1.6.0.jdk

The user-accesible (or just Oracle?) JDKs are under /Library/Java and I only have Oracle's JDK 1.7:

~$ ls /Library/Java/JavaVirtualMachines/
jdk1.7.0_45.jdk

The Oracle JDK 7's Home directory contents is:

~$ ls /Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk/Contents/Home/
COPYRIGHT               include
LICENSE                 jre
README.html             lib
THIRDPARTYLICENSEREADME-JAVAFX.txt  man
THIRDPARTYLICENSEREADME.txt     release
bin                 src.zip
db

as you can see, there is no bundle directory, which relates to the original error message.

Collaborator

jsdevel commented Dec 19, 2013

I think find-java-home would help out here.

Collaborator

jsdevel commented Dec 21, 2013

@jahewson Can you clone my fork locally and try building that? Here's the URL: https://github.com/jsdevel/node-java.git

I currently have PR for issue #94 open and I believe it will solve issues like this.

@jahewson Now that 0.3.0 is published, can you try installing again with 0.3.0?

Contributor

TheSpyder commented May 7, 2014

I'm still seeing this with 0.3.2, OS X 10.9.2.

shinji:corpus spyder$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/Home
shinji:corpus spyder$ node corpus.js 
<startup output>
No Java runtime present, requesting install.

I'm also using java.newInstanceSync.

Collaborator

jsdevel commented May 23, 2014

@joeferner should we add libserver.dylib to postInstall.js?

Owner

joeferner commented May 23, 2014

That would probably make sense. Anyone have OSX to try it on?

Contributor

TheSpyder commented May 25, 2014

I'm happy to test anything if you can give me a patch or tell me how to modify my local install :)

Collaborator

jsdevel commented May 25, 2014

@TheSpyder can you try adding git+https://github.com/jsdevel/node-java.git#a4c47f938903957f578c7f228f4aad34b6cfdb32 in your package.json for java?

Contributor

TheSpyder commented May 25, 2014

node(94131,0x7fff7d3e0310) malloc: *** error for object 0x103f7e7c0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

well that was interesting :)

Do I need to run a particular command to get more detail?

Collaborator

jsdevel commented May 25, 2014

hmmmm.... That is interesting. You're getting a different error now though which is promising!

Can you do this and paste the output of ~/contents-of-java-home.txt?

  1. cd node_modules/java
  2. cd "node findJavaHome.js"
  3. find . > ~/contents-of-java-home.txt

cc @joeferner. I'm guessing that error is related to node-java trying to free a pointer that hasn't been created yet?

Contributor

TheSpyder commented May 25, 2014

I don't want to spam anyone's inbox, so I put it on pastebin :)

http://pastebin.com/mAxiwt05

Collaborator

jsdevel commented May 25, 2014

@TheSpyder @joeferner looks like that error is happening for other Mavericks users without node-java https://www.bountysource.com/issues/1126096-tree-diffindex-pointer-being-freed-was-not-allocated.

@TheSpyder what version of java and node are you using?

Contributor

TheSpyder commented May 25, 2014

ahh, well I have upgraded node recently. I try to keep it up to date.

Node v0.10.28
Java latest (tried both 1.7.0_55 and 1.8.0_05 by changing JAVA_HOME)

I have, however, installed node via homebrew if that makes any difference.

Collaborator

jsdevel commented May 25, 2014

@TheSpyder you might try with other versions of node if you can.

Collaborator

jsdevel commented May 25, 2014

@TheSpyder you may attempt the proposed debugging instructions in that bountysource link I posted. It may be related to a function within node-java. What line do you get that error on BTW?

Contributor

TheSpyder commented May 25, 2014

I'm not familiar with gdb, so I'd need help to get a backtrace. The error is definitely coming from newInstanceSync, even this is enough to do it:

var java = require('java');
java.newInstanceSync("java.lang.String");

And just to be sure, I tried passing an empty and incorrect strings to newInstanceSync - still failed. It doesn't even manage to check if the class exists.

Collaborator

jsdevel commented May 25, 2014

@TheSpyder I'm no c++ expert. You may attempt adding print statements in src/Java.cpp#newInstanceSync and re-build. That could let you know where the failure is at.

Contributor

TheSpyder commented May 25, 2014

I was trying older versions of node, no dice.

Adding printf to help debug the method calls revealed this nugget in Java::createJVM:

  // setup classpath
  std::ostringstream classPath;
  printf("10\n");
  classPath << "-Djava.class.path=";
  printf("11\n");

10 prints, then crash without 11. I'm no C guru either, but doesn't that read as classPath has been declared but not defined before use? :)

Contributor

TheSpyder commented May 25, 2014

hmm. git history shows that's been there since 2012, so clearly I'm off base somehow.

I just installed 0.3.3 plain and I'm getting the same error, so it wasn't anything you did :)

Contributor

TheSpyder commented May 25, 2014

ooh, and I'm getting it with 0.3.2 as well.

When I remove JDK 1.7 and 1.8 and type java at the command line, it no longer offers to install it - instead I get a message saying I need to install a JDK and linking to the oracle site.

It looks like Java 1.6 is officially dead on OS X.

They must've snuck that in with 10.9.3 (I only just realised I was still on 10.9.2 when I first posted here).

Collaborator

jsdevel commented May 26, 2014

@TheSpyder
10 prints, then crash without 11. I'm no C guru either, but doesn't that read as classPath has been declared but not defined before use? :)
In c++ there's something called RAII which basically means merely declaring the type acquired a new instance of the object, so in that case classPath would be a new instance of std::ostringstream.

@TheSpyder @jahewson are you using macports? Can you verify that you're compiling with g++?

@joeferner this (http://stackoverflow.com/questions/21413852/simple-protocol-buffers-program-works-when-compiled-with-g-but-not-clang) seems to be very relevant.

Collaborator

jsdevel commented May 26, 2014

And here we have this: https://trac.macports.org/wiki/UsingTheRightCompiler.

With Xcode 4.0 and 4.1 on OS X 10.6 or 10.7, llvm-gcc-4.2 is the default. With Xcode 4.2 or later, clang is the default and gcc is no longer included. The Xcode 4.6 release notes state that it is the last version of Xcode that will include llvm-gcc-4.2, which will leave only clang.

@TheSpyder @jahewson I'm guessing node-java is getting compiled with clang and not gcc.

Collaborator

jsdevel commented May 26, 2014

@TheSpyder looks like I may have been wrong about RAII in this context.

@joeferner From http://clang.llvm.org/compatibility.html, "Clang does not zero initialize local block variables, and programs which rely on such behavior will most likely break when built with Clang."

Contributor

TheSpyder commented Jun 3, 2014

Sorry for not responding, I was on holiday.

I'm using Homebrew, not macports, but I have Xcode 5 (the latest) so yes clang is the cause. An update around mid may removed GCC completely, which broke a lot of open source projects.

Homebrew has a replacement GCC package that was already installed, so doing this fixed it:

export CXX=gcc
npm rebuild

I'm not sure what you can do about that, other than searching for GCC before CLANG and hoping it's installed.

But now that we've cleared that up, back on topic - your commit above (git+https://github.com/jsdevel/node-java.git#a4c47f938903957f578c7f228f4aad34b6cfdb32) doesn't work and still requests Java 6. Same with the new 0.3.4 release (Which I can see contains that commit).

My node_modules/java/build/jvm_dll_path.json file contains ":/Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/Home/jre/lib/server" and that path is correct, libjvm.dylib is in that folder. But it doesn't appear to be using it.

Want me to insert print statements in the C code again? :)

Hi all, just upgraded to node 0.10.28, OS X 10.9.3, and JDK 1.7.0_60. Experiencing this same issue now. Any debug info I can provide to help troubleshoot?

node(70832,0x7fff748a2310) malloc: *** error for object 0x103b117c0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
make[1]: *** [test-debug] Abort trap: 6

Contributor

TheSpyder commented Jun 5, 2014

That's the clang issue. Assuming you have gcc installed, this will fix it:

export CXX=gcc
npm rebuild

If you don't have gcc, I recommend homebrew :)

Thanks for the reply. Yes, GCC installed, exported CXX ENVAR, npm rebuild.. but, new error this time:

$ make run
/Applications/Xcode.app/Contents/Developer/usr/bin/make DEBUG= 'run-debug'
dyld: lazy symbol binding failed: Symbol not found: _ZNSt8__detail15_List_node_base7_M_hookEPS0
Referenced from: /Users/xxxx/xxxx/xxxx/node_modules/node-fix/node_modules/java/build/Release/nodejavabridge_bindings.node
Expected in: dynamic lookup

dyld: Symbol not found: _ZNSt8__detail15_List_node_base7_M_hookEPS0
Referenced from: /Users/xxxx/xxxx/xxxx/node_modules/node-fix/node_modules/java/build/Release/nodejavabridge_bindings.node
Expected in: dynamic lookup

make[1]: *** [run-debug] Trace/BPT trap: 5
make: *** [run] Error 2

Thoughts?

Collaborator

jsdevel commented Jun 8, 2014

@stefankutko you might try cleaning up the build directory first. It's possible the code that was compiled with clang is still present.

@TheSpyder I think the solution here would be to compile the code against clang and see how hard it would be to make it compatible.

FYI, I was able to fix this issue this morning with a brew update gcc... latest version is 4.8.3_1

Contributor

TheSpyder commented Jun 10, 2014

Very weird. All of a sudden I am getting those dyld errors as well - but updating gcc doesn't fix it.

It looks like the cause is that the code now compiles against JAVA_HOME but is still running against the system JDK6 (hence the prompt to install it still appears). This causes dynamic link errors.

When I recompile without JAVA_HOME set, using gcc, and allow JDK6 to be installed, it still works.

Contributor

TheSpyder commented Jun 10, 2014

I think it was a weird combination of using my actual project (which still links to v0.3.2) instead of my test project, and needing a brew update.

0.3.4 now compiles without needing CXX=gcc and doesn't have dylib errors even when JAVA_HOME is set. I hate moving targets :)

Contributor

TheSpyder commented Jun 10, 2014

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.

Collaborator

jsdevel commented Jun 10, 2014

Awesome job researching this @TheSpyder !

Collaborator

jsdevel commented Jun 12, 2014

So I was able to compile successfully with CXX=clang++ :/ OSX 10.8.5 Xcode 5.0.2

Contributor

TheSpyder commented Jun 12, 2014

Yeah, I suspect homebrew was interfering for a while there. One of their recent updates removed /usr/local/bin/gcc in favour of a more specific /usr/local/bin/gcc-4.8. This means running gcc now uses /usr/bin/gcc (which is just clang).

I don't need to set CXX at all anymore (osx 10.9.3, Xcode 5.1.1).

Collaborator

jsdevel commented Jun 12, 2014

@TheSpyder I'm curious now what the actual issue was originally. I'm a bit confused ATM. Thoughts?

Contributor

TheSpyder commented Jun 12, 2014

I'm not sure exactly what was causing the malloc and dyld errors, but I strongly suspect the mid-may Xcode update. Homebrew likely took some time to catch up to whatever Apple did.

Right now, we're back to just the Java 6 issue.

Collaborator

jsdevel commented Jun 12, 2014

@TheSpyder is it safe to close the issue then?

Contributor

TheSpyder commented Jun 12, 2014

Yes. I don't believe you can fix this. It's worth adding a note (and possibly my suggested workarounds) to the readme, though.

Collaborator

jsdevel commented Jun 12, 2014

Thanks @TheSpyder! I think for now we can close it. Can you submit a PR with the README addition?

@jsdevel jsdevel closed this Jun 12, 2014

Thanks, @TheSpyder! That was super helpful.
It looks like the homebrew cask installation for Java 7 now applies your first suggested workaround: https://github.com/caskroom/homebrew-versions/blob/master/Casks/java7.rb#L17

Installation steps for the next person to stumble upon this issue:

$ brew install caskroom/cask/brew-cask
$ brew tap caskroom/homebrew-versions
$ brew cask install java7

jamestyrrell added a commit to jamestyrrell/homebrew-cask that referenced this issue Jan 5, 2017

Add JNI as a capability of the JVM
This is copying the behaviour found in the [java](https://github.com/caskroom/homebrew-cask/blob/master/Casks/java.rb#L21) cask and resolves an issue with node-java (as described [here](joeferner/node-java#90 (comment))).

@jamestyrrell jamestyrrell referenced this issue in caskroom/homebrew-cask Jan 5, 2017

Merged

zulu/1.8.0_112,8.19.0.1: add JNI as a capability of the JVM #28607

3 of 3 tasks complete

miccal added a commit to caskroom/homebrew-cask that referenced this issue Jan 5, 2017

Add JNI as a capability of the JVM (#28607)
This is copying the behaviour found in the [java](https://github.com/caskroom/homebrew-cask/blob/master/Casks/java.rb#L21) cask and resolves an issue with node-java (as described [here](joeferner/node-java#90 (comment))).

@megastef megastef referenced this issue in sematext/logagent-js Jan 19, 2017

Open

Implement JMX input #48

junqdu commented Mar 13, 2017

@TheSpyder any idea why JDK doesn't advertise itself as supporting JNI?

Contributor

TheSpyder commented Mar 16, 2017

@junqdu no idea. I don't think Oracle cares about Java on OS X much anymore.

Adding JNI to the list of JVMCapabilities worked perfectly for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment