Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -348,4 +348,45 @@ public static void configureJVMSettings(IJavaProject javaProject, IVMInstall vmI
}
}

/**
* Reset preview feature options that jdt.ls auto-enabled for an invisible project but that became
* invalid after the bundled compiler advanced to a newer Java release (preview enabled at a
* non-latest compliance fails the whole build). Only options that look auto-enabled by jdt.ls
* (enabled, with the preview-report severity set to {@code ignore}) on a project whose compliance
* is below {@link JavaCore#latestSupportedJavaVersion()} are reset; deliberate user settings,
* managed projects, projects with a linked (user-owned) settings folder and projects on the
* latest JDK are left untouched.
*
* @param javaProject the unmanaged project to reconcile.
* @return {@code true} if the preview options were reset.
*/
public static boolean reconcilePreviewFeatureSettings(IJavaProject javaProject) {
if (javaProject == null || !ProjectUtils.isUnmanagedFolder(javaProject.getProject())) {
return false;
}
// A linked settings folder holds user-owned prefs on disk that jdt.ls never auto-enabled;
// don't reconcile (and don't write back into) those, mirroring configureJVMSettings.
if (ProjectUtils.isSettingsFolderLinked(javaProject.getProject())) {
return false;
}
if (!JavaCore.ENABLED.equals(javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true))) {
return false;
}
// Only reconcile settings that were auto-enabled (and silenced) by jdt.ls, not ones a user set on purpose.
if (!JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, true))) {
return false;
}
String compliance = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
if (compliance == null || JavaCore.compareJavaVersions(compliance, JavaCore.latestSupportedJavaVersion()) >= 0) {
// The project is still on the latest supported version, enabling preview is valid.
return false;
}
Hashtable<String, String> defaultOptions = JavaCore.getDefaultOptions();
javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, defaultOptions.get(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES));
javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, defaultOptions.get(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES));
JavaLanguageServerPlugin.logInfo("Reset stale preview feature settings for project " + javaProject.getProject().getName()
+ " (compliance " + compliance + " is below the latest supported Java version " + JavaCore.latestSupportedJavaVersion() + ").");
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.eclipse.jdt.ls.core.internal.IConstants;
import org.eclipse.jdt.ls.core.internal.JDTUtils;
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
import org.eclipse.jdt.ls.core.internal.JVMConfigurator;
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
import org.eclipse.jdt.ls.core.internal.preferences.PreferenceManager;
Expand Down Expand Up @@ -157,6 +158,10 @@ public static boolean loadInvisibleProject(IPath javaFile, IPath rootPath, boole

IJavaProject javaProject = JavaCore.create(invisibleProject);

// Reset stale preview feature settings that would otherwise break the build after the bundled
// compiler advances to a newer Java release. See https://github.com/redhat-developer/vscode-java/issues/4420
JVMConfigurator.reconcilePreviewFeatureSettings(javaProject);

IFolder workspaceLinkFolder = invisibleProject.getFolder(ProjectUtils.WORKSPACE_LINK);
PreferenceManager preferencesManager = JavaLanguageServerPlugin.getPreferencesManager();
List<String> sourcePathsFromPreferences = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.ls.core.internal.JavaProjectHelper;
import org.eclipse.jdt.ls.core.internal.JVMConfigurator;
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
import org.eclipse.jdt.ls.core.internal.TestVMType;
Expand Down Expand Up @@ -233,6 +234,57 @@ public void testPreviewFeaturesDisabledForNotLatestJDK() throws Exception {
}
}

@Test
public void testStalePreviewFeaturesAreReset() throws Exception {
// Use a fixture without a .settings folder so it isn't linked: jdt.ls only auto-enables preview
// (the state this reconciles) when the settings folder is not linked.
IProject invisibleProject = copyAndImportFolder("singlefile/java14", "foo/bar/Foo.java");
assertTrue(invisibleProject.exists());
IJavaProject javaProject = JavaCore.create(invisibleProject);
// Simulate the state left behind after the bundled compiler advanced to a newer "latest":
// preview was auto-enabled (and silenced) by jdt.ls at a compliance that is no longer the latest.
String olderThanLatest = JavaCore.getAllVersions().get(JavaCore.getAllVersions().size() - 2);
javaProject.setOption(JavaCore.COMPILER_COMPLIANCE, olderThanLatest);
javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);

assertTrue(JVMConfigurator.reconcilePreviewFeatureSettings(javaProject));

assertEquals(JavaCore.DISABLED, javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true));
assertEquals(JavaCore.getDefaultOptions().get(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES),
javaProject.getOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, true));
}

@Test
public void testPreviewFeaturesKeptWhenOnLatestJDK() throws Exception {
IProject invisibleProject = copyAndImportFolder("singlefile/java14", "foo/bar/Foo.java");
assertTrue(invisibleProject.exists());
IJavaProject javaProject = JavaCore.create(invisibleProject);
javaProject.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.latestSupportedJavaVersion());
javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);

assertFalse(JVMConfigurator.reconcilePreviewFeatureSettings(javaProject));

assertEquals(JavaCore.ENABLED, javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true));
}

@Test
public void testExplicitPreviewFeaturesNotReset() throws Exception {
IProject invisibleProject = copyAndImportFolder("singlefile/java14", "foo/bar/Foo.java");
assertTrue(invisibleProject.exists());
IJavaProject javaProject = JavaCore.create(invisibleProject);
String olderThanLatest = JavaCore.getAllVersions().get(JavaCore.getAllVersions().size() - 2);
javaProject.setOption(JavaCore.COMPILER_COMPLIANCE, olderThanLatest);
javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
// A deliberate user setting keeps the default report severity (warning), not ignore.
javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.WARNING);

assertFalse(JVMConfigurator.reconcilePreviewFeatureSettings(javaProject));

assertEquals(JavaCore.ENABLED, javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true));
}

@Test
public void testSpecifyingOutputPath() throws Exception {
Preferences preferences = preferenceManager.getPreferences();
Expand Down
Loading