Repository navigation
Java Runtime Requirements
The runtime guidance and legacy-view behavior below are verified against merged source commit a1fd732e13a2cf9b73c9762d3de3cb445acea545 in microsoft/vscode-java-pack, PR #1768. The project-settings synchronization section has separate PR #1777 provenance. This records merged implementation, not evidence of release or deployment.
The JDK used to launch the Java language server is separate from the JDK used to compile and run your projects. The tooling minimum depends on the installed Language Support for Java extension and compiler mode. redhat.java 1.57.0 and newer requires JDK 25+ regardless of compiler mode. With the normal compiler configuration, versions 1.39.0-1.56.x require JDK 21+, and earlier supported versions require JDK 17+. A compatible bundled runtime satisfies the tooling requirement; Java 27 project support does not require JDK 27 just to launch the language server.
For older versions with java.jdt.ls.javac.enabled=on, the tooling minimum is JDK 23 for versions 1.36.0-1.40.x, JDK 24 for 1.41.0-1.45.x, and JDK 25 for 1.46.0-1.56.x. off and auto (where supported) keep the normal minimum; versions before 1.36.0 do not support this mode. Runtime guidance, the FAQ, and the legacy tooling-JDK picker share these requirements, which do not restrict project JDK choices.
Java: Configure Java Runtime opens the project-settings JDK page. Its local-JDK picker changes the selected project's JDK, not the JDK used to launch the language server. Older project targets remain supported through java.configuration.runtimes and your Maven or Gradle build configuration.
To set the language-server launch JDK explicitly, configure java.jdt.ls.java.home. Open the Java logs (java.open.logs) for startup diagnostics. Runtime selection and startup diagnostics belong to redhat.java; Java Pack does not probe tooling candidates, activate the language extension to obtain runtime information, or automatically open runtime configuration based on its own checks.
Java Pack's JDK Runtime tab distinguishes the selected project path from the available runtime inventory. A matching path shows its runtime name. An unlisted nonempty path instead shows a selected, disabled Current project JDK (not listed) option and the path; missing metadata shows Project JDK not available. Neither placeholder silently selects the first installed JDK. For an unlisted installation, use Refresh JDKs to re-query the inventory or Find a local JDK... to locate it. The latter remains a project-scoped java.project.updateJdk action, not a tooling-JDK selection. [7][8]
ClasspathRequestHandler.loadProjectClasspath resolves java.project.getSettings before querying java.vm.getAllInstalls, because resolving the project VM can register a JDK after an earlier inventory query. It sends the selected JDK path and refreshed inventory together in classpath.onDidLoadProjectClasspath; the loadClasspath reducer updates them in one state transition. Classpath request IDs and path.relative checks on filesystem paths reject superseded loads or replies for a project no longer selected, preserving the filesystem-based project identity check. Inventory request IDs reject older replies, including older failures before telemetry or user notification. These guards concern project-settings loading, not every asynchronous operation in Java tooling. [7][9]
A successful empty inventory is published and clears stale runtime choices. A current inventory failure reports telemetry and Unable to load Java runtimes: ..., but returns an undefined inventory rather than a successful empty result: a successful classpath load still supplies the actual project JDK path, and the reducer retains the previous inventory when the payload is undefined. Inventory-only refresh replaces runtime choices without changing an unapplied JDK selection or its effective project value; it does not apply settings, clean the workspace, or restart VS Code. [7][9][10]
This is pack-owned project-JDK presentation/synchronization, not a change to language-server launch requirements or automatic tooling-JDK selection. The legacy tabs and tooling guidance above remain separate. The PR references issue #1443; its exact original cache failure and reporter confirmation are not established by these source checks. Merge alone does not establish a released fix. [7][8][10][11]
tests/project-settings.test.js provides mocked handler, Redux, and static-render checks for late JDK registration, stale inventory success/failure, successful empty inventory, current inventory errors retaining the actual project path, project switches, combined list/path state updates, unapplied-choice preservation, and matching/unlisted/missing selection rendering. These checks are runnable with node --test tests/project-settings.test.js; they do not replace execution of real language-server or browser behavior. [10]
Run autotest run test-plans/java-extension-pack.yaml for the existing classpath UI plan. It uses stable VS Code, redhat.java plus the Java Pack, and the sibling checkout fixture ../../vscode-java/test/resources/projects/eclipse/simple-app; setup suppresses release notes and the first help view. After language-server readiness and classpath-page opening, the added JDK-tab steps require a real selected, non-disabled runtime option before and after Refresh JDKs, with no unavailable-JDK placeholder. The plan retains the non-unmanaged-project Add Library... / Apply Settings regression and deterministic .classpath assertion. This verifies current-JDK availability across refresh, not an injected JDK 21-to-24 startup race. These are inspected test assertions, not independently observed test passes. [11]
References [7]–[11] below are in microsoft/vscode-java-pack at full merged/source-tip commit 731f1209b675ce6be1962f6d0092682d1bb1fd8b, PR #1777; source identity microsoft/vscode-java-pack#1777:731f1209b675ce6be1962f6d0092682d1bb1fd8b. All five PR file patches were inspected with single-file paging, PR base/head/merge identities and file count rechecked afterward, and all five final files read at this immutable revision. This reconciles the current project-settings behavior without replacing PR #1768's unrelated tooling/legacy knowledge.
- [7]
src/project-settings/handlers/ClasspathRequestHandler.ts:loadProjectClasspath,listVmInstalls,getVmInstallsFromLS,addNewJdk, andchangeJdk. - [8]
src/project-settings/assets/classpath/features/components/JdkRuntime.tsx:JdkRuntime, selection synchronization, disabled placeholders, and refresh/browse actions. - [9]
src/project-settings/assets/classpath/features/classpathConfigurationViewSlice.ts:loadClasspath,listVmInstalls, andsetJdksreducers. - [10]
tests/project-settings.test.js: mocked handler/state and rendered-selection regressions. - [11]
test-plans/java-extension-pack.yaml: setup, project-JDK refresh steps, and retained library/apply assertions. PR #1777's description states the original reporter's API/cache evidence is unavailable; no exact original-cache reproduction is claimed here.
Previously opened legacy runtime tabs can still be restored for compatibility; they are not opened by the current Java: Configure Java Runtime command. These tabs show the runtime reported by redhat.java, with Refresh and explicit JDK browsing/installation actions when no runtime is reported. Missing information is not treated as a startup failure, and upstream errors are shown alongside any available project configuration. The legacy tab's Locate an Existing JDK action saves an explicit tooling choice to java.jdt.ls.java.home, unlike the current project-settings picker.
That explicit legacy selection checks for javac and the shared tooling minimum before saving globally; it does not raise project JDK requirements. Project-JDK disk discovery remains separate from tooling metadata. getToolingRuntimeInfo() reads an already-active extension's javaRequirement.tooling_jre and tooling_jre_version; only upstream Error status creates a tooling error. A reported runtime below the minimum or a configured/reported path mismatch produces a factual warning, not a replacement-runtime search. [1][2]
Project inventory failures do not hide the reported language-server runtime or successfully queried projects. The legacy tab displays the query errors and indicates when project information could not be fully loaded; projects with unavailable type information are not treated as ordinary unmanaged projects.
References below are in microsoft/vscode-java-pack at full source commit a1fd732e13a2cf9b73c9762d3de3cb445acea545, PR #1768; source identity microsoft/vscode-java-pack#1768:a1fd732e13a2cf9b73c9762d3de3cb445acea545.
- [1]
src/java-runtime/utils/upstreamApi.ts:getRequiredJdkVersion()andgetToolingRuntimeInfo(), version thresholds and read-only upstream metadata. - [2]
src/java-runtime/index.tsandsrc/java-runtime/assets/: project inventory, explicit legacy picker, serializer,ProjectJDKPanel,ToolingJDKPanel, andJDKActions. - [3]
src/extension.ts: startup scheduling without pack-owned runtime preflight; retained legacy serializer. - [4]
src/commands/index.ts,java.runtime, andsrc/project-settings/handlers/ClasspathRequestHandler.ts,addNewJdk: current command routing and project-scopedjava.project.updateJdkcall, retained context rather than a new command migration in this PR. - [5]
src/beginner-tips/: host-injected minimum passed throughBeginnerTipstoFaqPanel, tooling settings/log links, and separate project-runtime guidance. - [6]
tests/java-runtime.test.js: mocked host/API and component assertions. See Development and Validation for test entry points and their limits; no test execution result is asserted here.