After some additional effort to figure this out, it turned out to be an easy fix. SDKman stores the JDKs in this folder:
C:\Users\yourUserName\.sdkman\candidates\java
When you issue the command
sdk default java 8.322.06.2-amzn
it copies the JDK from the java 8 folder
C:\Users\yourUserName\.sdkman\candidates\java\8.322.06.2-amzn
and pastes it into the current folder.
C:\Users\yourUserName\.sdkman\candidates\java\current
The idea is that you point your pc to the "current/" directory so that when you change java version with SDKman, the pc environment variable never needs to be updated.
But for the ide, instead of pointing it to the "current/" directory, you can point it directly to the JDK folder
C:\Users\yourUserName\.sdkman\candidates\java\8.322.06.2-amzn
You can specify the JDK for each project, P1 and P2, separately. So even if you change java version with SDKman, that only effects the "current/" directory, which the ides are no longer pointing at.
Since I did this, I dont have to change java version if I want to switch working on my java 8 project to working on my java 11 project. And that means I dont have to close my java 8 project to open my java 11 project. I can have them both open at the same time, and switch between them easily.
Answer from Steve T on Stack OverflowAfter some additional effort to figure this out, it turned out to be an easy fix. SDKman stores the JDKs in this folder:
C:\Users\yourUserName\.sdkman\candidates\java
When you issue the command
sdk default java 8.322.06.2-amzn
it copies the JDK from the java 8 folder
C:\Users\yourUserName\.sdkman\candidates\java\8.322.06.2-amzn
and pastes it into the current folder.
C:\Users\yourUserName\.sdkman\candidates\java\current
The idea is that you point your pc to the "current/" directory so that when you change java version with SDKman, the pc environment variable never needs to be updated.
But for the ide, instead of pointing it to the "current/" directory, you can point it directly to the JDK folder
C:\Users\yourUserName\.sdkman\candidates\java\8.322.06.2-amzn
You can specify the JDK for each project, P1 and P2, separately. So even if you change java version with SDKman, that only effects the "current/" directory, which the ides are no longer pointing at.
Since I did this, I dont have to change java version if I want to switch working on my java 8 project to working on my java 11 project. And that means I dont have to close my java 8 project to open my java 11 project. I can have them both open at the same time, and switch between them easily.
Inside IntelliJ versus outside IntelliJ
- For running a project from within IntelliJ, you specify which JDK to use by configuring within IntelliJ.
- The current default JDK set by SDKMAN! only applies to Java apps being executed on their own, outside IntelliJ.
Unfortunately, configuring which JDK to run your app within IntelliJ is complicated and confusing, requiring you to go spelunking through various buried panels.
These panels include some for the JDK, and some for the language level (which version of Java to target):
- File | Project Structure | Project Settings | Project | SDK … and Language Level.
- File | Project Structure | Project Settings | Project | Modules | Language Level.
- Settings | Build, Execution, Deployment | Compiler | Java Compiler | Per-module bytecode version.
There may be others I don't recall at the moment. Search Stack Overflow to learn more.
If you are building a Web app in IntelliJ Ultimate edition, and running that app from within IntelliJ via an external application server such as Tomcat, Jetty, Glassfish, OpenLiberty, etc., then you need to also specify in another IntelliJ panel which JDK should be used to launch that app server.
If using Maven or Gradle, you need to specify language level there too.
Can't switch Java version in mac - Stack Overflow
Why won't sdkman change my default java version? - Stack Overflow
Switching versions of Java on Mac OSX
Easily switch between java versions with SDKMAN! and 'j'
Videos
I use https://sdkman.io/ to manage different java versions on my mac(M1).
I've installed several java versions using sdkman and it is easy to switch in between those versions using sdkman with one command.
I use jenv to switch between different java versions on mac.
>brew info jenv
==> jenv: stable 0.5.6 (bottled), HEAD
Manage your Java environment
https://www.jenv.be/
/opt/homebrew/Cellar/jenv/0.5.6 (86 files, 78KB) *
Poured from bottle on 2023-02-15 at 07:31:25
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/jenv.rb
License: MIT
==> Options
--HEAD
Install HEAD version
==> Caveats
To activate jenv, add the following to your shell profile e.g. ~/.profile
or ~/.zshrc:
export PATH="$HOME/.jenv/bin:$PATH"
eval "$(jenv init -)"
With
jenv local 11.0
or
jenv local 17.0
for example, I can switch do different versions of installed java.
I just happen to get that error, on Manjaro ..after an update of the S.O., so the error is the /usr/bin/java now points to the default java installed on the update.
So i just removed all Java versions installed on the updates cause I need only to use the sdkman.
Copysdk home java 8.0.232.hs-adpt
With this i can see where are the candidates on my case:
Copy/home/xxxx/.sdkman/candidates/java/8.0.232.hs-adpt
So after removed all java: i run java -version i found there is no java anymore.
So i force update sdkman
Copysdk selfupdate force
Then after install
Copysource "$HOME/.sdkman/bin/sdkman-init.sh"
And to be sure i ran :
Copyls -al /usr/bin/java
lrwxrwxrwx 1 root root 37 may 16 2020 /usr/bin/java -> /usr/lib/jvm/default-runtime/bin/java
and now it points to where sdkman supposed to:
And thats it now i can change versions again with sdkman.
Copysdk use java 11.0.5.hs-adpt
For me, the problem was the ending of .bashrc. I know, it explicitly says there "THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!", but I still decided to ignore that and wrote a few of my own lines after those ones 🤡. When I made sure the sdkman's lines were indeed at the very end of the file and after running sdk selfupdate force, setting the version started working properly across different terminals.
Hello!
I'm currently using Java 8 on my Mac and i'm finally getting around to the latest Java. I just installed JDK 19, and i'm wondering how i'm suppose to switch to the new jdk on my machine.
One doc says I can run this command: /usr/libexec/java_home -v 19 --exec javac -version
But my output just shows:
javac 1.8.0_291
Is there a standard way of switching java versions on Mac?
https://joerg-pfruender.github.io/software/java/2022/12/30/sdkman_j.html
First run /usr/libexec/java_home -V which will output something like the following:
Matching Java Virtual Machines (3):
1.8.0_05, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home
1.6.0_65-b14-462, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home
Pick the version you want to be the default (1.6.0_65-b14-462 for arguments sake) then:
export JAVA_HOME=`/usr/libexec/java_home -v 1.6.0_65-b14-462`
or you can specify just the major version, like:
export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
Now when you run java -version you will see:
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)
Add the export JAVA_HOME… line to your shell’s init file.
For Bash (as stated by antonyh):
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
For Fish (as stated by ormurin)
set -x JAVA_HOME (/usr/libexec/java_home -d64 -v1.8)
Updating the .zshrc file should work:
nano ~/.zshrc
export JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0)
Press CTRL+X to exit the editor Press Y to save your changes
source ~/.zshrc
echo $JAVA_HOME
java -version
This answer is an attempt to address: how to control java version system-wide (not just in currently running shell) when several versions of JDK are installed for development purposes on macOS El Capitan or newer (Sierra, High Sierra, Mojave). As far as I can tell, none of the current answers do that (*).
As a developer, I use several JDKs, and I want to switch from one to the other easily. Usually I have the latest stable one for general use, and others for tests. But I don't want the system (e.g. when I start my IDE) to use the latest "early access" version I have for now. I want to control system's default, and that should be latest stable.
The following approach works with Java 7 to 12 at least (early access at the time of this writing), with Oracle JDK or OpenJDK (including builds by AdoptOpenJDK produced after mid-October 2018).
Solution without 3rd party tools:
- leave all JDKs at their default location, under
/Library/Java/JavaVirtualMachines. The system will pick the highest version by default. - To exclude a JDK from being picked by default, rename its
Contents/Info.plisttoInfo.plist.disabled. That JDK can still be used when$JAVA_HOMEpoints to it, or explicitly referenced in a script or configuration. It will simply be ignored by system'sjavacommand.
System launcher will use the JDK with highest version among those that have an Info.plist file.
When working in a shell with alternate JDK, pick your method among existing answers (jenv, or custom aliases/scripts around /usr/libexec/java_home, etc).
Details of investigation in this gist.
(*) Current answers are either obsolete (no longer valid for macOS El Capitan or Sierra), or only address a single JDK, or do not address the system-wide aspect. Many explain how to change $JAVA_HOME, but this only affects the current shell and what is launched from there. It won't affect an application started from OS launcher (unless you change the right file and logout/login, which is tedious). Same for jenv, it's cool and all, but as far as I can tell it merely changes environment variables, so it has the same limitation.
I put together a beginner-friendly guide on SDKMAN!, a super handy tool for managing parallel versions of Java SDKs, Maven, Gradle, and many other development tools right from your terminal.
If you've ever struggled with switching between Java versions for different projects, SDKMAN! can really simplify your workflow.
In the post, I cover:
What SDKMAN! is and why it’s useful.
How to install it.
How to install and switch between SDKs.
Tips for setting a default version.
Hope it helps someone!