Steve T
Steve T

Reputation: 383

How do you change java version using SDKMAN without needing to close Intellij IDEA first?

I have sdkman installed on my PC laptop. I work on two separate projects, where P1 uses Java 11 and P2 uses Java 8. If I am working on P1, but something comes up and I need to work on P2, I will open up P2 using my ide (IntelliJ IDEA). Since P2 uses Java 8, I will open a terminal and use sdkman to change my pc to use Java 8. However, when I attempt this, I get 2 error messages:

user1@ bin $ sdk default java 8.322.06.2-amzn

rm: cannot remove '/c/Users/user1/.sdkman/candidates/java/current/lib/jrt-fs.jar': 
Device or resource busy

ln: failed to create symbolic link 
'/c/Users/user1/.sdkman/candidates/java/current/8.322.06.2-amzn': No such file or 
directory

When I look in the "current/" directory, instead of it being populated with the Java 8 JDK, it looks like "lib/jrt-fs.jar" (left over from the previous Java 11 JDK content) has not been deleted, and is in fact still residing in "current/". If I attempt to delete "lib/" via the file system, it tells me that the folder cannot be deleted, as a program is using it. I think there is a file handle not released by the ide, because when I close the ide, I can delete the folder, and I can use sdkman to populate the "current/" folder again.

enter image description here

Question: Is there a way to release the ide file handle on contents in the "current/" folder, without closing the ide?

Caveat: When I googled "Device or resource busy" I saw mentioned that I could use the umount command somehow, but I am not sure if this is a false trail or if I just need more information: here

Note: I am using the Community Edition of IntelliJ IDEA, version 2022.3.2

Edit: Here is a snapshot of the Project Settings that shows picking the JDK from the file system.

enter image description here

Upvotes: 4

Views: 9932

Answers (2)

Steve T
Steve T

Reputation: 383

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.

Upvotes: 4

Basil Bourque
Basil Bourque

Reputation: 338171

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.

Upvotes: 1

Related Questions