diff --git a/org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target b/org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target
index 57c546c346..ff9b4853bb 100644
--- a/org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target
+++ b/org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target
@@ -15,6 +15,10 @@
+
+
+
+
@@ -25,7 +29,7 @@
-
+
@@ -35,26 +39,26 @@
-
-
-
- org.apache.commons
- commons-lang3
- 3.8.1
- jar
-
-
-
-
-
-
- jakarta.servlet
- jakarta.servlet-api
- 5.0.0
- jar
-
-
-
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.8.1
+ jar
+
+
+
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+ 5.0.0
+ jar
+
+
+
-
+
\ No newline at end of file
diff --git a/org.eclipse.jdt.ls.tests/fakejdk/21/rtstubs.jar b/org.eclipse.jdt.ls.tests/fakejdk/21/rtstubs.jar
new file mode 100644
index 0000000000..fb6cb93825
Binary files /dev/null and b/org.eclipse.jdt.ls.tests/fakejdk/21/rtstubs.jar differ
diff --git a/org.eclipse.jdt.ls.tests/projects/eclipse/java21/.classpath b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/.classpath
new file mode 100644
index 0000000000..0b599b90d5
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.jdt.ls.tests/projects/eclipse/java21/.project b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/.project
new file mode 100644
index 0000000000..a89415d417
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/.project
@@ -0,0 +1,17 @@
+
+
+ java21
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/org.eclipse.jdt.ls.tests/projects/eclipse/java21/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..abea9a426a
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,16 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=21
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=enabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=21
+
diff --git a/org.eclipse.jdt.ls.tests/projects/eclipse/java21/src/main/java/foo/bar/Foo.java b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/src/main/java/foo/bar/Foo.java
new file mode 100644
index 0000000000..78e1dfd0e3
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/src/main/java/foo/bar/Foo.java
@@ -0,0 +1,9 @@
+package foo.bar;
+
+/**
+ * It's a Foo class
+ */
+public sealed interface Foo
+permits Bar {
+}
+record Bar(String name) implements Foo { }
diff --git a/org.eclipse.jdt.ls.tests/projects/eclipse/java21/src/main/java/org/sample/Test.java b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/src/main/java/org/sample/Test.java
new file mode 100644
index 0000000000..aca1a4ec7e
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/eclipse/java21/src/main/java/org/sample/Test.java
@@ -0,0 +1,4 @@
+package org.sample;
+
+public class Test {
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.classpath b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.classpath
new file mode 100644
index 0000000000..63c971dc56
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.classpath
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.project b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.project
new file mode 100644
index 0000000000..adfdeb5b8f
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.project
@@ -0,0 +1,23 @@
+
+
+ salut-java21
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..354d9630e0
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,17 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=21
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=enabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=21
+
+
diff --git a/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.settings/org.eclipse.m2e.core.prefs b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000000..f897a7f1cb
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/pom.xml b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/pom.xml
new file mode 100644
index 0000000000..af6a7184a7
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/pom.xml
@@ -0,0 +1,26 @@
+
+ 4.0.0
+ foo.bar
+ salut-java21
+ 0.0.1-SNAPSHOT
+
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+ 21
+ --enable-preview
+
+
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.5
+
+
+
diff --git a/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/src/main/java/org/sample/Bar.java b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/src/main/java/org/sample/Bar.java
new file mode 100644
index 0000000000..c8839a8886
--- /dev/null
+++ b/org.eclipse.jdt.ls.tests/projects/maven/salut-java21/src/main/java/org/sample/Bar.java
@@ -0,0 +1,14 @@
+package org.sample;
+
+/**
+ * This is Bar
+ */
+public class Bar {
+
+ public static void main(String[] args) {
+ Object foo = "x";
+ if (foo instanceof String str) {
+ System.out.println(str);
+ }
+ }
+}
diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/ModifierCorrectionsQuickFixTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/ModifierCorrectionsQuickFixTest.java
index 0f32eec96b..19c04265df 100644
--- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/ModifierCorrectionsQuickFixTest.java
+++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/ModifierCorrectionsQuickFixTest.java
@@ -1211,11 +1211,11 @@ public void testClassExtendFinalClass() throws Exception {
@Test
public void testAddSealedMissingClassModifierProposal() throws Exception {
- Map options20 = new HashMap<>();
- JavaModelUtil.setComplianceOptions(options20, JavaCore.VERSION_20);
- options20.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
- options20.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
- fJProject.setOptions(options20);
+ Map options21 = new HashMap<>();
+ JavaModelUtil.setComplianceOptions(options21, JavaCore.VERSION_21);
+ options21.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+ options21.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+ fJProject.setOptions(options21);
IPackageFragment pack1 = fSourceFolder.createPackageFragment("test", false, null);
assertNoErrors(fJProject.getResource());
@@ -1258,11 +1258,11 @@ public void testAddSealedMissingClassModifierProposal() throws Exception {
@Test
public void testAddSealedAsDirectSuperClass() throws Exception {
- Map options20 = new HashMap<>();
- JavaModelUtil.setComplianceOptions(options20, JavaCore.VERSION_20);
- options20.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
- options20.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
- fJProject.setOptions(options20);
+ Map options21 = new HashMap<>();
+ JavaModelUtil.setComplianceOptions(options21, JavaCore.VERSION_21);
+ options21.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+ options21.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+ fJProject.setOptions(options21);
IPackageFragment pack1 = fSourceFolder.createPackageFragment("test", false, null);
assertNoErrors(fJProject.getResource());
@@ -1287,11 +1287,11 @@ public void testAddSealedAsDirectSuperClass() throws Exception {
@Test
public void testAddPermitsToDirectSuperClass() throws Exception {
- Map options20 = new HashMap<>();
- JavaModelUtil.setComplianceOptions(options20, JavaCore.VERSION_20);
- options20.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
- options20.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
- fJProject.setOptions(options20);
+ Map options21 = new HashMap<>();
+ JavaModelUtil.setComplianceOptions(options21, JavaCore.VERSION_21);
+ options21.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+ options21.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+ fJProject.setOptions(options21);
IPackageFragment pack1 = fSourceFolder.createPackageFragment("test", false, null);
assertNoErrors(fJProject.getResource());
diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/UnresolvedTypesQuickFixTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/UnresolvedTypesQuickFixTest.java
index 6b819ff640..58a62a516a 100644
--- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/UnresolvedTypesQuickFixTest.java
+++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/UnresolvedTypesQuickFixTest.java
@@ -1492,11 +1492,11 @@ public void testDontImportTestClassesInMainCode() throws Exception {
@Test
public void testTypeInSealedTypeDeclaration() throws Exception {
- Map options20 = new HashMap<>();
- JavaModelUtil.setComplianceOptions(options20, JavaCore.VERSION_20);
- options20.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
- options20.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
- fJProject1.setOptions(options20);
+ Map options21 = new HashMap<>();
+ JavaModelUtil.setComplianceOptions(options21, JavaCore.VERSION_21);
+ options21.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+ options21.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+ fJProject1.setOptions(options21);
IPackageFragment pack1 = fSourceFolder.createPackageFragment("test1", false, null);
StringBuilder buf = new StringBuilder();
diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/EclipseProjectImporterTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/EclipseProjectImporterTest.java
index 7463889d0e..0650c6b6ca 100644
--- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/EclipseProjectImporterTest.java
+++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/EclipseProjectImporterTest.java
@@ -197,7 +197,7 @@ public void testPreviewFeatures16() throws Exception {
@Test
public void testPreviewFeaturesDisabledByDefault() throws Exception {
- String name = "java20";
+ String name = "java21";
importProjects("eclipse/" + name);
IProject project = getProject(name);
assertIsJavaProject(project);
diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/InvisibleProjectImporterTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/InvisibleProjectImporterTest.java
index ebb829c776..8afc281f28 100644
--- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/InvisibleProjectImporterTest.java
+++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/InvisibleProjectImporterTest.java
@@ -204,7 +204,7 @@ public void getPackageName() throws Exception {
public void testPreviewFeaturesEnabledByDefault() throws Exception {
String defaultJVM = JavaRuntime.getDefaultVMInstall().getId();
try {
- TestVMType.setTestJREAsDefault("20");
+ TestVMType.setTestJREAsDefault("21");
IProject invisibleProject = copyAndImportFolder("singlefile/java14", "foo/bar/Foo.java");
assertTrue(invisibleProject.exists());
assertNoErrors(invisibleProject);
diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporterTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporterTest.java
index a068dda651..c315e02e27 100644
--- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporterTest.java
+++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/MavenProjectImporterTest.java
@@ -348,6 +348,17 @@ public void testJava20Project() throws Exception {
IJavaProject javaProject = JavaCore.create(project);
assertEquals(JavaCore.ENABLED, javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, false));
assertEquals(JavaCore.IGNORE, javaProject.getOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, false));
+ assertHasErrors(project, "Preview features enabled at an invalid source release level");
+ }
+
+ @Test
+ public void testJava21Project() throws Exception {
+ IProject project = importMavenProject("salut-java21");
+ assertIsJavaProject(project);
+ assertEquals("21", getJavaSourceLevel(project));
+ IJavaProject javaProject = JavaCore.create(project);
+ assertEquals(JavaCore.ENABLED, javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, false));
+ assertEquals(JavaCore.IGNORE, javaProject.getOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, false));
assertNoErrors(project);
}