-
Notifications
You must be signed in to change notification settings - Fork 332
Consistency of --jvm
CLI options: allowing optional JVM path
#13225
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
Consistency of --jvm
CLI options: allowing optional JVM path
#13225
Conversation
--jvm
CLI options: allowing optional JVM path
✨ GUI Checks ResultsSummary
See individual check results for more details. |
...ct-manager/src/main/scala/org/enso/projectmanager/boot/configuration/MainProcessConfig.scala
Show resolved
Hide resolved
val requiresJVMRunner = | ||
ensoLauncher.exists(_.equals("shell")) || runSettings.jvmMode | ||
if (requiresJVMRunner) { | ||
if (runSettings.jvm.isDefined) { |
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.
Is there a recommended way to (unit) test this logic?
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 think we are testing this at all. Make sure you try manually launching project-manager
.
if (requiresJVMRunner) { | ||
if (runSettings.jvm.isDefined) { | ||
val javaHome = runSettings.jvm.get | ||
val javaExec = if (javaHome.isDefined) { |
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 wrote this code in a way I can read it later.
- I assume there is some fancy way of using
Option.map.orElse
instead - reviewers feel free to make such a local stylistic changes directly
- you have write access to the code in this PR
|
||
object Runner { | ||
|
||
private val LAUNCHER_ENV_NAME = "ENSO_LAUNCHER" |
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 think there is any need to support ENSO_LAUNCHER=shell
when there is --jvm
option in project-manager
. Removing the ENSO_LAUNCHER check.
...ion-manager/src/main/scala/org/enso/runtimeversionmanager/runner/LanguageServerOptions.scala
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.
Unification of --jvm
argument is good.
- Make sure you manually test it, I am afraid there are no unit tests for this.
- Please choose any other type than
Option[Option[Path]]
.
...n/scala/org/enso/projectmanager/infrastructure/languageserver/LanguageServerController.scala
Show resolved
Hide resolved
...la/runtime-version-manager/src/main/scala/org/enso/runtimeversionmanager/runner/Runner.scala
Outdated
Show resolved
Hide resolved
...ct-manager/src/main/scala/org/enso/projectmanager/boot/configuration/MainProcessConfig.scala
Show resolved
Hide resolved
Co-authored-by: Hubert Plociniczak <[email protected]>
b3251dc
to
b491672
Compare
|
2ea881b
to
8728e1a
Compare
private def jvmMode = | ||
Opts.flag( | ||
private def jvm = | ||
Opts.optionalParameter[Path]( |
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 have to admit I am not sure at all how to represent this optional option with optional parameter in this system?
- in 8728e1a I at least fixed the compilation
- but using
Option(jvm)
at various places is unlikely correct, right @radeusgd?
additionalArgs | ||
) => (config: Config) => | ||
Launcher(config).runRun( | ||
path = path, | ||
versionOverride = versionOverride, | ||
useSystemJVM = systemJVMOverride, | ||
jvmOpts = jvmOpts, | ||
jvmMode = jvmMode, | ||
jvm = Option(jvm), |
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.
- Assuming
jvm
is nevernull
, this will always produceSome
and that's not what we want. - It should be
None
if the--jvm
option wasn't specified at all - How does one represent that with
Opts
factory methods, @radeusgd?
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'm not sure if I understand what you want to achieve.
Do I understand correctly that you want to support 2 scenarios?
--jvm
with nothing after it - to enable JVM mode but no path to the JVM--jvm <path>
with a path to the JVM that should be used
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.
If the requirements above are correct, then I'm afraid that the framework does not support such a duality at all.
The problem is the framework was created with some other assumptions in mind that contradict the approach above. One of the features we wanted in the framework was that the flags and options can appear in mostly any order relative to positional arguments.
Thus we either have flags that do not expect any 'values' after them, or parameters that expect 1 'value' for it. Thus, if I encounter --foo bar
- depending on if --foo
is a flag or a parameter, I can determine if bar
should be treated as the 'value' for parameter foo
or if bar
is just a positional argument following --foo
.
Of course I can imagine we could take some other approach to this, but these are assumptions of this framework and I think it may be unlikely that it may be easy to change them.
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.
So IF my assumptions about what you want from this parameter/flag are correct, I would suggest to try some other approach for selecting the JVM to use. As this flag is doing 2 things at once (one could argue violating SRP).
I'd suggest to keep a boolean flag --jvm
that either is there or isn't present.
Note that we already have a flag --use-system-jvm
in the same launcher (in fact it's next to your --jvm
option). Perhaps that + setting of JAVA_HOME
and PATH
could be sufficient.
If not, I'd suggest to add --use-custom-jvm=<path>
parameter that would override the default selection.
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.
Unless I misunderstood your requirements, and you are okay for <path>
argument of --jvm
to be required - i.e. you either:
- do not specify
--jvm
at all - specify
--jvm some-path
always with some path.
In that case I think you should have it almost ready - the optionalParameter
yields results in form of Option[A]
so isn't your jvm
already an Option[Path]
? Then the Option(jvm)
should not be needed. Or is the type something else?
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.
suggest to try some other approach
With ...
The primary goal of this PR is to fix sbt "runProjectManagerDistribution --debug"
... being achieved by giving the --jvm
flag in project-manager
and enso
the same meaning and behavior. It is not really possible to try some other approach in ensoup
. That wouldn't bring the needed consistency.
But let's ask a question:
- why do we have the
--jvm
flag at all? - it has been added by Make Native Image opt-out #12515, but
- why do we need the flag at all?
- unless I am mistaken
ensoup
can pass any options (specified after--
) toenso
, right Radek? - then we could just delete the special support and use
ensoup run -- --jvm....
- what do you think @hubertp, @radeusgd?
- vote +1 for me to open a new PR that removes the
ensoup
--jvm
option/flag/parameter altogether
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.
Yes, passing some custom options can be done by passing them after --
. I think due to the non-standard (from perspective of ensoup's CLI) behaviour of --jvm
, passing it after --
may be the preferred solution.
On the other hand let's not that part of ensoup
's job is also selecting which JVM to use to run the engine. SO I feel like we are kind of having 2 places that now do a similar thing here. This duplication bothers me a bit, but it's a completely separate issue.
So as for argument passing - yeah I'd vote for passing --jvm
after --
and thus we avoid the issues with CLI parsing.
But still slightly worried that we have 2 components selecting JVMs - right now ensoup
will select some JVM for the engine and then the engine may actually select another one. Messy.
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.
passing it after
--
may be the preferred solution.
I can try to open a PR removing this ensoup --jvm
altogether. Is that OKeyish, @hubertp?
part of
ensoup
's job is also selecting which JVM to use to run the engine.
- can you point me to the specification?
- it may need updating - it was written prior
enso
being a native executable
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.
Some docs:
https://github.com/enso-org/enso/blob/develop/docs/distribution/launcher.md#enso-and-graal-version-management
https://github.com/enso-org/enso/blob/develop/docs/distribution/launcher-cli.md#--use-system-jvm
Code that manages GraalVM versions and finds/installs the JVM for a given engine version:
https://github.com/enso-org/enso/blob/develop/lib/scala/runtime-version-manager/src/main/java/org/enso/runtimeversionmanager/components/GraalVersionManager.java
https://github.com/enso-org/enso/blob/develop/lib/scala/runtime-version-manager/src/main/scala/org/enso/runtimeversionmanager/components/RuntimeVersionManager.scala#L145-L168
Building engine manifest that specifies the JVM used with it:
enso/project/DistributionPackage.scala
Lines 191 to 196 in a1aa84c
buildEngineManifest( | |
template = file("distribution/manifest.template.yaml"), | |
destination = distributionRoot / "manifest.yaml", | |
graalVersion = graalVersion, | |
javaVersion = javaVersion | |
) |
The representation of the Manifest file in code (and its parsing via YamlDecoder
):
https://github.com/enso-org/enso/blob/develop/lib/scala/runtime-version-manager/src/main/scala/org/enso/runtimeversionmanager/components/Manifest.scala#L39
For each engine release we create a manifest.yaml
artifact that stores the JVM version needed to run that engine.
ensoup
, when installing a given release, downloads this manifest first and it will then install the required GraalVM version if it is not yet installed. All JVMs used for Enso are kept in $ENSO_DATA_DIRECTORY/runtime
(see https://github.com/enso-org/enso/blob/a1aa84c0285de4b86168ace233d6d5b50693311c/docs/distribution/distribution.md#installed-enso-distribution-layout).
Perhaps this logic should be updated if the requirements are changed.
Perhaps if no JVM is needed as its running native (but --jvm
flag still needs a JVM, right?) the JVM version in manifest.yaml
could be set to null
. Proper launcher upgrade (breaking change) would be needed for that though as currently null
is not a valid value and the logic would break. Ideally it should be done in a backwards compatible way (e.g. by creating a new launcher version and bumping minimum-launcher-version
so that a newer launcher is used for engines that rely on the new logic).
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.
- GraalVM will still be needed even with
enso
native executable - first of all
--jvm
needs the GraalVM - the GraalVM will be even more needed with Using
Channel
to load Java classes #13238- unless we create an native only mode
- that would prevent automatic delegation to HotSpot JVM
Some docs:
https://github.com/enso-org/enso/blob/develop/docs/distribution/launcher.md#enso-and-graal-version-management
https://github.com/enso-org/enso/blob/develop/docs/distribution/launcher-cli.md#--use-system-jvm
OK. I believe the following flag can be removed...
--use-system-jvm
Tells the launcher to use the default JVM (based on JAVA_HOME) instead of the managed one. Will not work if the set-up JVM version is not GraalVM.
GraalVM Override
While the launcher manages its own installation of GraalVM to ensure that the right JVM version is used to launch each version of Enso, the user can override this mechanism to use the installed system JVM instead. This is an advanced feature and should rarely be used.
...such an advanced feature deserves to be complicated - e.g. ensoup run -- --jvm path_to_JDK
would be good enough replacement...
Pull Request Description
Fixing broken sbt command by adding support for optional parameter to
--jvm
argument:was broken by incorrect assumption that
--jvm
flags may take arguments. Theenso
one did accept argument, theproject-manager
one didn't. This PR fixes that by giving theproject-manager
--jvm
flag an optional path attribute.Important Notes
Checklist
Please ensure that the following checklist has been satisfied before submitting the PR:
Scala,
Java,