Open cardil opened 5 years ago
I've got to say that I really like the idea of introducing the new unuse
command here. I'd expect it to work as an opposing force to the use
command ie. it only affect the current shell.
In addition I would introduce another new command as counterpart to the default
command, and call that system
. ie. affects all subsequent shells that are opened.
So, this is what you would have:
$ sdk system java # use system java in all shells
$ sdk default java # use sdkman java in all shells
$ sdk unuse java # use the system java only in this current shell
$ sdk use java # use sdkman java in the current shell
Does this sound like an acceptable approach to everyone?
I must admit I rather like the other approach:
$ sdk use java 8-zulu # use sdkman java 8 in shell
$ sdk use java system # use os java in shell
$ sdk default java 11-zulu # use sdkman java 8 in all future shells
$ sdk default java system # use system java in all future shells
I think I just more used to that approach in other tools like rvm or pyenv. It's also more in line with other commands of sdkman. I think it will be easier to remember for users.
But adding two new commands is just fine as well.
It's basically the choosing between:
unused
and system
system
+0 for virtual version.
@vmj did you mean +1? 😀
@marc0der 😄 no, I meant "I don't feel strongly, but if this happens, the virtual version seemed more natural".
But now that I think about it more, what would the "system" version be for candidates that do not have any system counterpart or have multiple? It's probably "whatever the system was set up it to be". I.e. sdkman will just step aside and let things be as messy as they were before it.
In that case, I feel that unuse/system commands might be a bit easier to understand:
sdk unuse java
reverts to the default sdkman behaviour for the current shell. That behaviour could be to use one of sdkman java versions or it could be "let the system decide". sdk use java system
could do the same, but the words kind of give a promise that there is a single system java.sdk system java
undoes the sdkman setup for that candidate and lets the system do whatever it did without sdkman. sdk default java system
again kind of gives the impression that sdkman will still be involved when you type java
.So yes, I'm changing my vote to "+0 for new commands". Sorry 😜
But maybe the name of the system
command should be something like hide
or disable
. system
is not a verb and sdk system java
sounds like a script around /path/to/system/java --version
.
@vmj no worries! thanks for clarifying. And yes, good point about system
not being a verb.
If you are going for new methods maybe better names will be:
use
- unuse
default
- undefault
As you see, default is also not a verb.
Maybe change to set-default
and unset-default
.
@cardil we are using default
as a verb in this context. ie we default java to 11.0.1. We also won't be changing that any time soon as it is already widely used by all. I like the idea of introducing undefault
as counterpart to default
though.
But now that I think about it more, what would the "system" version be for candidates that do not have any system counterpart or have multiple?
Why not simply check if it exists and if there is no system-wide available installation then ask user’s confirmation if that is surely what is wanted?
For multiple choices, sdk can use the system’s alternatives/default resolution tool to show current OS default version like update-alternatives does in Ubuntu for an example.
Hm… maybe sdk can use system alternatives/default configuration tools to show system version in listing as well while using new version marking like “s” (lowercase) for system-wide available and “S” (uppercase) for currently set system wide default version in addition to “+” and “*”?
For multiple choices, sdk can use the system’s alternatives/default resolution tool to show current OS default version like update-alternatives does in Ubuntu for an example.
Introducing a dependency on tools that are available only on certain platforms is not good because we would need to start maintaining code branches for every platform under the sun. At the moment sdkman is decoupled as much as possible from it's environment and I think we should keep it that way. Therefore I'm not in favour of depending on tools like update-alternatives
on Ubuntu or /usr/libexec/java_home
on mac.
Why not simply check if it exists
It's not that simple. We don't know what we are checking for as sdkman is completely agnostic of the contents of the sdks that it serves. ie. we don't know (and don't want to care) what's in the bin
folder of each candidate, so we are not even aware that java
, scala
, groovy
, kotlin
executables are provided by sdkman.
Uprate-alternatives requires root access. Sdkman is user space program, it shouldn't rely on update-alternatives.
System option is pretty good option even you got nothing installed on system. You are using system, but there nothing there so it effectively unset a tool and disable it's usage.
Came across the need to do this today...
I have Oracle JDK 7 & 8 installed on mac using the installer(s) and OpenJDK 10 & 11 using sdkman.
Switching back to either of the "system" versions after switching to sdk managed version requires mucking about with the PATH
+1 for unuse
@martin-walsh That is absolutely not necessary. Simply use sdkman's local version feature: https://sdkman.io/usage#localversion
@marc0der The local version feature does not seem to work as documented in https://sdkman.io/usage#localversion
I tried sdk install groovy 2.4.13 /usr/local/src/groovy-2.4.13
from a local version. Instead of linking (or even copying) the existing installation, sdkman downloaded and installed a new copy of 2.4.13 in candidates/groovy/2.4.13/
I tried several other versions of Groovy, Java, etc....same problem.
Also, I note the help for sdk install
does not list a possible 4th argument to an existing path.
Currently trying this with version SDKMAN 5.7.3+337
Local feature works a charm for me on macOS!
sdk install java 7 /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/
SDKMAN 5.7.3+337
@hickst It certainly is working. Try using a version that is unique. I think 2.4.13
is taken, so maybe try something like 2.4.13-local
.
Success! Thanks for clarifying how it works. The fact that you cannot use the same name as sdkman
really should be in the documentation, though. Otherwise, the natural tendency is to follow the naming pattern used by the tool, which results in the failure to create a local
link. Also, the help documentation for the install
command should be updated to show the optional 4th argument (the existing installation path). Thanks again.
Even better, maybe sdkman itself should tell you that it is a reserved version string. Wdyt?
@marc0der Yes, having the tool itself help one to do it correctly definitely sounds like the best idea.
I also recommend a "local" Java example in the documentation, similar to the one @martin-walsh showed above (thanks for the help @martin-walsh!)
@hickst afaik, it is already documented.
Regarding letting the tool itself help you do it correctly, want to raise a PR for that one?
@marc0der which "it" is already documented? In the documentation for Install Local Version(s)
, I see only a single Groovy example. I am recommending that:
sdkman
already uses,sdk install java 10-zulu-local /Library/Java/JavaVirtualMachines/zulu-10.jdk/Contents/Home
sdkman
usage (help) strings to show the optional 4th argument. For example:
commands:
install or i <candidate> [version]
...
would become
commands:
install or i <candidate> [version] [path-to-local-installation]
...
@marc0der I would be happy to open a new issue but do we need to move this discussion to Gitter before I am allowed to do that?
Don't worry about the gitter discussion. You can update the website docs in this project with a PR: https://github.com/sdkman/sdkman-website
Of course the help can be updated in this project.
May I also suggest an unset
option, for those packages which don't have system artifacts?
E.g.
sdk unset grails
to effectively unlink any version of grails that's currently configured, but lasts beyond the current shell and doesn't force me to uninstall the various versions installed?
@jamesdh that might be confusing for users as the set
command is used for changing versions in the current shell only.
@marc0der isn't that use
?
In any case, it'd be nice to somehow remove any link to an installed version without actually uninstalling.
@jamesdh yes you're right, my bad.
I would also like to express my support for this functionality.
I've installed graalvm with sdk to play around with native compilation. However, on (nodejs) project was failing to build with graal's node . The only way I could get past this was to uninstall graalvm.
If there was an option to disable/unset sdk graal then I could have avoided the un-instalation.
I do hope sdkman implements this functionality. It is necessary.
@ieugen a better workaround is probably to install the default JDK (AdoptOpenJDK) and make that your system default. Then you shouldn't have any conflicts with Node. You can then apply the sdk use
command to switch to Graal in individual terminals when you require it. Hope that helps!
Thanks that is a good suggestion. I do have an issue with it. I already have adoptopenjdk installed via Debian package system. I do prefer that since I have unattended-upgrades in place. In this case I might go for this workaround if I can use both and experiment. I do prefer Debian packages since they are better integrated with the system.
Some feedback. The sdk use java XXX method works. However I still need to keep the java version installed in Debian since I have other packages that depend on it.
This does/can create some issues:
Using a localversion Java also worked for me. I am still unhappy about the fact, that sdkman sets JAVA_HOME to ~/.sdkman/candidates/java/current if I wish to use the system Java. I wish a solution which lets JAVA_HOME as it is defined by the system.
Ive discovered that a simple aproach is to use an bash function to enable sdkman, just enclose the 2 sdkamn lines into a function and call them if you need sdkman, but once loaded i dont know how a clean way to unload it would look like.
I was able to link system java sdk to sdkman using Install local version https://sdkman.io/usage#localversion. And sdkman was able to list my system java and I switched it.
For example: Adding system sdk to sdkman
# sdk install unique_name_of_sdk path_to_system_sdk
sdk install java-8-openjdk /usr/lib/jvm/java-8-openjdk-amd64/
Apply the local sdk version
sdk default java-8-openjdk
List all java version from sdk Output:
--------------------------------------------------------------------------------
Offline: only showing installed java versions
--------------------------------------------------------------------------------
> java-8-openjdk
* java-11-openjdk
* 17-open
--------------------------------------------------------------------------------
* - installed
> - currently in use
--------------------------------------------------------------------------------
Any news on this?
sdkman is basically breaking my Debian system, insisting in wanting to set its own JAVA_HOME
, after I set a default by cli. I did not know the change was basically irreversible... (unless uninstalling sdkman, and cleaning the .bashrc
.
Under Arch Linux, there is a way to create the virtual system
version by
sdk install java system /usr/lib/jvm/default
Since /usr/lib/jvm/default is a symlink managed by archlinux-java
command and where it points is the default java on the specific system.
However, it would be much nicer if SDKMan rather can roll back the changes in the environment regarding to the Java Runtime, and let system's default behavior happen whatever is that.
Please tick one:
Please explain the Issue / Feature Request here:
It's currently impossible, after using sdkman, to restore Java to use default installed in operation system. It should be possible to do that, even temporarly.
It's done this way by multiple tool version managers like:
I think sdkman could simply remove current binding for a tool with special command, removing
current
symlink for example:sdk use java system
or
sdk unuse java