-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
--jvm tries to find Java executable system-wide. #11500
base: develop
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The --jvm option now tries to find java executable from JAVA_HOME and from PATH. If that is not found, the distribution manager's runtimes are used as a fallback.
I'd say that this is the wrong order. The target audience of Enso users is unlikely to have proper JVM installed in the system. Searching for a system JVM is good for us, developers, but not for our target audience.
trying to find the java executable from the distribution manager's runtime (on my system located in ~/.local/share/enso/runtime) and it used the first runtime found. But the first runtime on my system is JDK 17.
It is good we have such a failing example! What is the layout of your Enso JVM runtimes? That is an important information for your #11274 bug report.
Anyway, the enso
launcher should:
- search managed runtimes (in
~/.local/share/enso/runtime
) first - ignore the outdated ones - e.g. having JVM spec version lower than
21
(right now) - select the exact match, if found
- select acceptable match (e.g. newer JDK), if found - probably with some warning printed
- if no match found among managed runtimes, fallback to system JVM - with some warning printed, if the JDK isn't exactly the one we expect
Would the above steps work for your system setup, Pavel?
That is a good point.
Certainly. Sounds like a good plan. I will see what I can do. |
It would be great, if we selected the same JDK as used for the build (however that's
DistributionManager shall do most of the selection logic. CCing @radeusgd to give us an expert guidance. |
…m runtime-version-manager
/** | ||
* Tries to find {@code java} executable on the system. If a system-wide JDK is not found, tries | ||
* to find it in the {@link DistributionManager distribution} runtimes. | ||
* | ||
* @return null if cannot be found. Otherwise, returns the absolute path to the executable, or | ||
* simply {@code java} if it is on the {@code PATH}. | ||
*/ | ||
static String findJavaExecutable() { | ||
var javaHome = System.getenv("JAVA_HOME"); | ||
if (javaHome != null) { | ||
var java = new File(javaHome, "bin/java").getAbsoluteFile(); | ||
if (java.exists()) { | ||
return java.getAbsolutePath(); | ||
} | ||
} | ||
if (isJavaOnPath()) { | ||
return "java"; | ||
} | ||
var javaInRuntime = findJavaExecutableInDistributionRuntimes(); | ||
if (javaInRuntime != null) { | ||
return javaInRuntime.toAbsolutePath().toString(); | ||
} | ||
return null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the precedence should actually look into distribution first and only afterwards use system JVM.
The whole purpose of ensoup
was to manage JVMs related to the engine versions, so that the engine is run with the right compatible JVM and not a random version that may be incompatible with it (I guess it used to be more important before Truffle 'got unchained').
I think ideally we should first to run the JVM version required by the engine if it's found in the distribution. Then we can fallback to using the logic of searching JAVA_HOME
and Path
.
Ideally I'd also check the JVM version and log a warning if the version required by engine does not match the version that has been found.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JVMs related to the engine versions
This version is stored in the engine's manifest - see for example built-distribution/enso-engine-0.0.0-dev-windows-amd64/enso-0.0.0-dev/manifest.yaml
.
It contains fields: graal-vm-version
and graal-java-version
.
You can see lib/scala/runtime-version-manager/src/main/scala/org/enso/runtimeversionmanager/components/Manifest.scala
for the logic of loading the manifest and extracting the GraalVMVersion
from it.
We have a GraalCEReleaseProvider
which translates this GraalVMVersion
into a strategy for downloading it from GitHub - but you probably don't need this.
The function graalDirectoryForVersion
in RuntimeVersionManager
takes GraalVMVersion
and gives you back the directory name under which this JVM version will be sitting in the $ENSO_DATA_DIRECTORY/runtime
(installed by ensoup
).
I guess you could factor out the Manifest
and graalDirectoryForVersion
utilities to a common package and you could use it to figure out the JVM version tied to the engine.
Btw. the manifest also contains a jvm-options
field. I'd be very happy if we could keep the (sometimes changing) options in a single place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess if you want to check if the JVM version is correct you need to call java --version
and somehow parse its output and compare with graal-java-version
.
e.g. I get
openjdk 21.0.2 2024-01-16
OpenJDK Runtime Environment GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30)
OpenJDK 64-Bit Server VM GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30, mixed mode, sharing)
I guess I want to extract the second word from the first line. At least for now that seems to work. But we can update the logic whenever the version format of expected JVM changes - unexpected format just means it's not the JVM we expect :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly better way than parsing output of java -version
is to run a small program on the JVM:
public static void main(String... args) {
System.out.prinltn(System.getProperty("java.vm.version"));
// etc.
}
and just read the output line by line without the need to parse words.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool - that indeed sounds better, I didn't think of that
As of 586fc73:
Only when there is no newer runtime found in the managed distribution runtimes, |
...ion-manager/src/main/java/org/enso/runtimeversionmanager/components/GraalVersionManager.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall it looks very nice and clean. Some doubts:
- does it work on Windows?
- possibly too many exports from the new
module-info
} | ||
} | ||
if (isJavaOnPath()) { | ||
return "java"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that work on Windows?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't expect it to work on windows. This is a fallback that is currently only usable for devs and not anyone else. For all the other use-cases, the java exe should be found in the installed distribution runtimes.
...ion-manager/src/main/java/org/enso/runtimeversionmanager/components/GraalVersionManager.java
Outdated
Show resolved
Hide resolved
Windows CI does not have
|
What about |
Fixes #11274
Pull Request Description
Fixes
--jvm
option, given to the native image. This was failing on my machine, because when given--jvm
option, the runner was trying to find thejava
executable from the distribution manager's runtime (on my system located in~/.local/share/enso/runtime
) and it used the first runtime found. But the first runtime on my system is JDK 17.The
--jvm
option now tries to:java
from$JAVA_HOME
and from$PATH
. But this is just a fallback.Important Notes
--jvm
argument to a native image of engine-runnerruntime-version-manager
sbt project migrated to a JPMS moduleengine-runner
now depends onruntime-version-manager
.runtime-version-manager
dealing with outdatedgu
Graal Updater utility.Checklist
Please ensure that the following checklist has been satisfied before submitting the PR:
Scala,
Java,
TypeScript,
and
Rust
style guides. In case you are using a language not listed above, follow the Rust style guide.
or the Snowflake database integration, a run of the Extra Tests has been scheduled.