Skip to content
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

Incorrect JDK used when running with Gradle #3633

Closed
aaronshenhao opened this issue Apr 27, 2024 · 4 comments
Closed

Incorrect JDK used when running with Gradle #3633

aaronshenhao opened this issue Apr 27, 2024 · 4 comments

Comments

@aaronshenhao
Copy link

aaronshenhao commented Apr 27, 2024

Edit: Solved. Not a bug but configuration error (solution below).

Upon clicking run, I notice that my project is being run with the JDK located under ~/.gradle/jdks instead of the JDK I specified in settings.json.

Environment
  • Operating System: Windows 11 Home
  • JDK version: OpenJDK-18
  • Visual Studio Code version: 1.88.1
  • Java extension version: 1.30.0
Steps To Reproduce
  1. Load a gradle project and set up the settings as below.
  2. Click run.

Unable to attach sample files as it is for coursework.

Current Result

This is what it runs the project with:

cd /home/username/projectfile ; /usr/bin/env /home/username/.gradle/jdks/eclipse_adoptium-18-amd64-linux/jdk-18.0.2.1+1/bin/java @/tmp/cp_argfile.argfile ore.Driver 
Expected Result

This is what it should run the project with:

cd /home/username/projectfile ; /usr/bin/env /home/username/.jdks/openjdk-19 @/tmp/cp_argfile.argfile ore.Driver 
Additional Informations

settings.json file:

{
    "java.configuration.runtimes": [
        {
            "name": "JavaSE-19",
            "path": "/home/username/.jdks/openjdk-19",
        },
        {
            "name": "JavaSE-19",
            "path": "/home/username/.jdks/openjdk-20",
        },
        {
            "name": "JavaSE-19",
            "path": "/home/username/.jdks/openjdk-22",
            "default": true
        },
    ],

    "java.jdt.ls.java.home": "/home/username/.jdks/openjdk-19"
}

java.jdt.ls.java.home is being used by the "Gradle for Java" extension by Microsoft to specify the JDK.

@aaronshenhao aaronshenhao changed the title Does not use correct JDK with Gradle Incorrect JDK used when running with Gradle Apr 27, 2024
@mklinkj
Copy link

mklinkj commented Apr 28, 2024

hello.

I created an example test project and checked its operation...

If you want to use the coursework project with JDK 18, you can do it as follows.

{
    "java.configuration.runtimes": [
        { 
            "name": "JavaSE-18",  // 💡Install Java 18 on the system and add the path
            "path": "/home/username/.jdks/openjdk-18",
        },
        {
            "name": "JavaSE-19",
            "path": "/home/username/.jdks/openjdk-19",
        },
        {
            "name": "JavaSE-20", // 💡Renamed to JavaSE-20.
            "path": "/home/username/.jdks/openjdk-20",
        },
        {
            "name": "JavaSE-22", // 💡Renamed to JavaSE-22.
            "path": "/home/username/.jdks/openjdk-22",
            "default": true
        },
    ],

    // 💡 Path to Java Home to run Gradle for Java
    "java.jdt.ls.java.home": "/home/username/.jdks/openjdk-19"

}

TODO:

  1. Add JavaSE 18 installation path to java.configuration.runtimes.
  2. Correctly corrected duplicate JavaSE-?? name.

"java.jdt.ls.java.home" is simply the path to run the Gradle for Java extension, and if JAVA_HOME is set globally on the system, it does not seem to need to be specifically specified.

Example Test

Example Project

This is a simple example program that prints the currently running Java Home.

System environment

In my case, to prevent gradle from automatically downloading a JDK that cannot be used, I disabled automatic downloading and manually specified the JDK path.

%USERPROFILE%/.gradle/gradle.properties

org.gradle.java.installations.auto-detect=false
org.gradle.java.installations.auto-download=false
org.gradle.java.installations.paths=C:/JDK/8,C:/JDK/11,C:/JDK/17,C:/JDK/18,C:/JDK/21

VSCode - User Settings.json

    "java.configuration.runtimes": [
      {
        "name": "JavaSE-17",
        "path": "C:\\JDK\\17\\",
        "default": true
      },
      {
        "name": "JavaSE-21",
        "path": "C:\\JDK\\21\\"
      },
      {
        "name": "JavaSE-11",
        "path": "C:\\JDK\\11\\"
      },
		  {
        "name": "JavaSE-18",
        "path": "C:\\JDK\\18\\"
      },
      {
        "name": "JavaSE-1.8",
        "path": "C:\\JDK\\8\\"
      }
    ],
    // Java runtime path to run Gradle for Java
    // Required after installing "Gradle for Java". If the JAVA_HOME environment variable is set globally on the system, it does not need to be set.
    "java.import.gradle.java.home": "C:\\JDK\\21",

Java Version settings for example project - build.gradle

// Apply a specific Java toolchain to ease working on different environments.
java {
  toolchain {
    languageVersion = JavaLanguageVersion.of(18)
  }
}

Run it by clicking the Run link that appears above the main() method.

If you run the test project with the settings as above...

C:\git-mklinkj\QnA\vscode-java\gradle-java-home-test> cmd /C "C:\JDK\18\bin\java.exe @%LOCALAPPDATA%\Temp\cp_bcmlni503byv5p5eyxxi4hqsu.argfile org.example.App "
Java Home: C:\JDK\18
  • I confirmed that it works well with JDK 18.

    image-20240428182053968

Run it by clicking application > run Task in “Gradle for Java”

  • I confirmed that it works well with JDK 18.

    image-20240428181800400

⚠️ Caution

  • When changing the JDK version of a project, it is better to use Clean Java Language Server Workspace.

💡 If you have a development environment that uses multiple versions of the JDK environment, I personally think it would be better to disable Gralde's automatic JDK detection function and automatic download function... 😅

Then, please take note of this. Have a great day.

@aaronshenhao
Copy link
Author

aaronshenhao commented Apr 28, 2024

@mklinkj Wow, I really appreciate the detailed solution. And apologies for the typo.

Thanks to your example, I've managed to find the source of the problem. There appeared to be two separate problems, which affected the "Language Support for Java" and "Gradle for Java" extensions separately.

I do have the following setting in my build.gradle file, which I forgot to mention. It seems like you've mentioned it as well.

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(18)
    }
}

Here are the two problems (not bugs but user errors) I found:

  1. JavaSE-18 was required in build.gradle, but it was unavailable due to it not being listed in java.configuration.runtimes in settings.json.
    • Effect: Language Support for Java imports the wrong JVM (automatically downloaded by Gradle).
    • Fix: List it in java.configuration.runtimes or remove the requirement in build.gradle
    • Gradle for Java is not affected.
  2. java.jdt.ls.java.home does not point to the correct JDK (JavaSE-18).
    • Effects: Gradle for Java imports the wrong JVM (automatically downloaded by Gradle).
    • Fix: Make java.jdt.ls.java.home point to the correct JDK or remove the requirement in build.gradle
    • Language Support for Java is not affected (still manages to find the correct version).

I found that setting java.import.gradle.java.home or modifying the gradle.properties file didn't seem to have any effect. I thought setting the gradle.properties file would help in case 2, but it didn't.

Gradle properties additions I used:

org.gradle.java.installations.auto-detect=false
org.gradle.java.installations.auto-download=false
org.gradle.java.installations.paths=C:/JDK/8,C:/JDK/11,C:/JDK/17,C:/JDK/18,C:/JDK/21

Other notes:
I got link errors, but that was because I clicked the wrong button on the Gradle for Java sidebar (build instead of application/run).

Thanks again for your help!

@mklinkj
Copy link

mklinkj commented Apr 29, 2024

I did this because I didn't want Gradle to automatically download and use JDKs that weren't on my system and preferred to use JDKs that I had manually installed on my system.

Glad it worked out for you and thanks for the answer. Have a nice day 👍


There are parts where I gave speculative answers. 😅

    // Specifies the folder path to the JDK (17 or more recent) used to launch the Java Language Server. 
    // This setting will replace the Java extension's embedded JRE to start the Java Language Server.
    "java.jdt.ls.java.home": "C:\\JDK\\17",
    // The location to the JVM used to run the Gradle daemon.
    "java.import.gradle.java.home": "C:\\JDK\\17",
  • If java.jdt.ls.java.home is not set, Java Language Server runs as the following built-in JRE. %USERPROFILE%\.vscode\extensions\redhat.java-1.30.0-win32-x64\jre\17.0.10-win32-x86_64
    • 💡However, when using this value without setting it, there were rare cases where automatic completion of Java basic classes did not work properly.
  • java.import.gradle.java.home seems to mean the Java path that Gradle For Java uses when running the Gradle daemon rather than executing Gradle For Java itself.

@rgrunber
Copy link
Member

Glad you were able to resolve this. Closing for now but feel free to re-open if there's some other problems.

Note, as of 1.23.0 (we're about to release 1.31.0 soon), JDK detection is done automatically which should lessen the strain of users needing to populate java.configuration.runtimes manually. See https://www.npmjs.com/package/jdk-utils#usage for some of the supported locations. Also as was pointed out the java.jdt.ls.java.home & java.import.gradle.java.home are meant for the JRE used for the JDT-LS/Gradle runtimes. For configuring which JDK is used by an open project, there is java.configuration.runtimes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants