Launcher can't find JAVA_HOME running with Linux alternatives
Most of the issues reported under https://github.com/jruby/jruby/issues/6049 appear to be due to the fact that we can't detect that the JDK being used supports modules.
Normally if you have JAVA_HOME set to the location of your JDK, we will look for JAVA_HOME/jmods to determine that the JDK supports modules. In some scenarios, only java will be in path. The logic at present assumes that java is under JAVA_HOME/bin, and infers JAVA_HOME From that path. Unfortunately on most Linux distributions, java is installed as a link in /usr/bin, so we can't determine from that path where JAVA_HOME is actually located.
I believe we need a more robust mechanism to determine that the target JDK supports modules.
The workaround for now is to set JAVA_HOME. On most Linux distributions, there will be commands you can run to get the location of the default JDK installation. The JDKs are also usually installed under /usr/lib/jvm; paths there are suitable for JAVA_HOME (just make sure they match the default version of Java run by /usr/bin/java).
Thank you @headius, I'll play around to figure out the proper value of JAVA_HOME to get this to work.
It seems to me from what you wrote that it would be enough to resolve the real location of java if it's a symlink before all the current logic to figure out the JAVA_HOME?
@deivid-rodriguez I am doing a spike of writing this launcher in rust. What is described with alternatives is a single function (fs::canonicalize(path)) and if we do continue with the existing launcher it will likely need to be readlink in a loop since /usr/bin/java -> /etc/alternatives/java -> /the/actual/location.
@enebo Ruby's File.realpath seems to handle that just fine:
$ ls -l /usr/bin/java
lrwxrwxrwx 1 root root 22 ago 21 2019 /usr/bin/java -> /etc/alternatives/java
$ jruby -e 'puts File.realpath("/usr/bin/java")'
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method sun.nio.ch.NativeThread.signal(long)
WARNING: Please consider reporting this to the maintainers of com.headius.backport9.modules.Modules
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
/usr/lib/jvm/java-11-openjdk-amd64/bin/java
And the workaround works, by the way! :tada:
$ JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 jruby -e "puts 1"
1
Another way to get JAVA_HOME:
$ jruby -e 'puts ENV_JAVA["java.home"]'
/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
We are probably not going to go further with this in the existing launcher codebase since the new Rust-based launcher has been coming along well. I would recommend anyone using JRuby have a JAVA_HOME set until we have the newer, smarter launcher to handle that for you.
I'm using the jruby:9.2-jre11 Docker image.
> echo $JAVA_HOME
/usr/local/openjdk-11
> which java
/usr/local/openjdk-11/bin/java
> JAVA_HOME=/usr/local/openjdk-11/ jruby -e "puts 1"
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.headius.backport9.modules.Modules to method sun.nio.ch.NativeThread.signal(long)
WARNING: Please consider reporting this to the maintainers of com.headius.backport9.modules.Modules
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
1
However, when I execute find / -name jmod, it yields no result.
@nfrankel What version of JRuby is in that docker image? We were supposed to take over maintenance but have not had time to do so. It may be out of date.
ruby --version
jruby 9.2.11.1 (2.5.7) 2020-03-25 b1f55b1a40 OpenJDK 64-Bit Server VM 11.0.7+10 on 11.0.7+10 +jit [linux-x86_64]
jruby 9.2.11.1
😬 Yikes, ok, we need to get those images taken over and updated to latest JRuby.
Workaround for now would be to manually force a newer JRuby by downloading or installing it in the container.
No worries, I can live with a warning until the new image is provided. Thanks for the feedback!
The docker images seem up to date though: https://hub.docker.com/_/jruby/. I think you need to docker pull to update your base image.
Thanks for the hint @deivid-rodriguez. The image was from 5 months ago, there's indeed a new one... and a new warning message.
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.jruby.ext.openssl.SecurityHelper (file:/opt/jruby/lib/ruby/stdlib/jopenssl.jar) to field java.security.MessageDigest.provider
WARNING: Please consider reporting this to the maintainers of org.jruby.ext.openssl.SecurityHelper
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
On a meta level, this raises the question as to why the tag may reference different image hashes over time. Since it's the second time I encounter this behavior, I'm less surprised, but I do think this is not a good idea.
You have different options for specifying your base docker image, which go from yours, jruby:9.2-jre11, meaning "give me the latest patch level version of the 9.2 series", to more constraining such as jruby:9.2.13.0-jre11, meaning give me exactly the base image tagged as 9.2.13.0, but potentially including changes still being tagged as 9.2.13.0 (for example, a bug fix in the Dockerfile) to the fully deterministic jruby:9.2.13.0@sha256:8b217bb79ecaec62b2ea86f7389348cca44a9a6446c50b1da13fd2f40df91687.
Regarding the warning, you can also try upgrading the jruby-openssl gem to 0.10.5.
@deivid-rodriguez Makes sense, thanks for the explanation