JRuby's launchers currently attempt to determine JAVA_HOME by resolving symlinks - it uses this mechanism to determine if the JVM has modules support, which necessitates calling java with various `--add-opens` flags for fully-featured operation. This obviously doesn't work on FreeBSD, as it just resolves to /usr/local/bin: https://github.com/jruby/jruby/issues/6905 Manually setting JAVA_HOME works around this, but is obviously not an ideal solution. The best fix would seem to be for javavmwrapper to offer a mechanism to determine the configured JAVA_HOME, and there seems to be precedent for such a feature on other platforms which offer similar functionality in the form of a `java_home` command: https://medium.com/notes-for-geeks/java-home-and-java-home-on-macos-f246cab643bd > java_home - return a value for $JAVA_HOME > > -v or --version version > Filters the returned JVMs by the major platform version in "JVMVersion" form. > Example versions: "1.5+", or "1.6*". > -V or --verbose > Prints the matching list of JVMs and architectures to stderr. > --exec command ... > Executes the command at $JAVA_HOME/bin/<command> and passes the remaining arguments. > Any arguments to select which $JAVA_HOME to use must precede the --exec option. For JRuby's purposes only the most basic functionality would be required, with the rest perhaps a nice-to-have. This might also be nice for heavy Java users - manually setting JAVA_HOME cuts out most of javavmwrapper's overheads (in my case, 95ms becomes 15ms), and this would allow it to be set without manually hardcoding it. Does this seem reasonable?
What is the user impact with this resolution mechanism missing? Some subset of java software cannot be built/installed (they fail?) Are there precedents/examples for a standard mechanism in the packages for other OS's we can reference & use?
It basically means a user unaware of how to work around the problem will struggle to install recent versions of JRuby - a `rbenv install jruby-9.3.1.0` will fail with an obscure "Bad file descriptor" error when attempting to build jruby-launcher, which ruby-build considers fatal. A manual attempt might run into issues like: > javavm: warning: The use of 'javavm' as a synonym for 'java' is deprecated > 2021-10-27T00:27:59.661Z [main] WARN FilenoUtil : Native subprocess control requires open access to the JDK IO subsystem > Pass '--add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED' to enable. symlink chasing results in calling a deprecated name for javavmwrapper, and incorrect JAVA_HOME guessing results in a failure to detect a modularized JVM giving strange warnings and limited functionality. This is also the reason I haven't updated the port - I'm not sure how to actually make it work reliably in the general case. As far as I can tell the java_home command is specific to macOS, and other platforms tend to just go for a single version blessed by symlinks.
Created attachment 229074 [details] Initial implementation attempt Here's a quick implementation of such a command, supporting only short options. ❯ java_home /usr/local/openjdk16 ❯ java_home -v 13 java_home: error: no suitable JavaVMs found ❯ java_home -v 13+ /usr/local/openjdk14 ❯ java_home -v 13+ -o linux java_home: error: no suitable JavaVMs found ❯ java_home -v 13+ -e java -version openjdk version "14.0.2" 2020-07-14
Created attachment 229075 [details] Minor tweak to initial implementation Remove a vestigial -: from getopts which was from an aborted attempt to support long options.
Created attachment 229096 [details] Updated patch Tidy up argument handling, fix some default variable handling, and add a -V option for setting JAVA_VENDOR. This does diverge from the macOS implementation with a different meaning for -V, but it seems unlikely anyone's going to use that in a script.
FWIW, I have removed all Java discovery logic from Maven 4 because it was brittle and never complete. Jruby and others suffer from the same problem: applying to much discovery magic.
Hi Thomas, Thanks for taking the time to submit this bug report and patch. I'd like to compare what you've got to the MacOS version but java_home doesn't appear to exist on my MacOS box (running Mojave). Do you know when it was introduced? I can potentially run a newer version in a VM and check it out that way. -- Greg
It's /usr/libexec/java_home on macOS, and dates all the way back to 10.5 (Leopard).
Thanks! /usr/libexec was not in my path, but I do see it there. I'll give the man page a read and try it out a bit and compare.
(In reply to Greg Lewis from comment #9) Did you get a chance to look at this?