diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JVMConfigurator.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JVMConfigurator.java index b9c8eba1e7..0d35366abe 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JVMConfigurator.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JVMConfigurator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019-2020 Red Hat Inc. and others. + * Copyright (c) 2019-2021 Red Hat Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -56,10 +56,11 @@ */ public class JVMConfigurator implements IVMInstallChangedListener { + public static final String JAVA_LS_DO_NOT_SET_DEFAULT_JVM = "java.ls.doNotSetDefaultJVM"; //$NON-NLS-1$ public static final String MAC_OSX_VM_TYPE = "org.eclipse.jdt.internal.launching.macosx.MacOSXType"; //$NON-NLS-1$ public static boolean configureDefaultVM(String javaHome) throws CoreException { - if (StringUtils.isBlank(javaHome)) { + if (StringUtils.isBlank(javaHome) || Boolean.getBoolean(JAVA_LS_DO_NOT_SET_DEFAULT_JVM)) { return false; } File jvmHome = new File(javaHome); @@ -97,7 +98,7 @@ public static boolean configureDefaultVM(String javaHome) throws CoreException { JavaLanguageServerPlugin.logInfo("Setting java.home " + jvmHome + " as default global VM"); JavaRuntime.setDefaultVMInstall(vm, new NullProgressMonitor()); JDTUtils.setCompatibleVMs(vm.getId()); - + setDefaultEnvironmentVM(vm); return true; } @@ -179,7 +180,7 @@ public static boolean configureJVMs(Preferences preferences, JavaClientConnectio } } vm = vmStandin.convertToRealVM(); - if (runtime.isDefault()) { + if (runtime.isDefault() && !Boolean.getBoolean(JAVA_LS_DO_NOT_SET_DEFAULT_JVM)) { defaultVMSet = true; if (!Objects.equals(vm, JavaRuntime.getDefaultVMInstall())) { JavaLanguageServerPlugin.logInfo("Setting runtime " + runtime.getName() + "-" + runtime.getInstallationFile() + " as default global VM"); @@ -229,12 +230,41 @@ private static void sendNotification(JavaClientConnection connection, String mes connection.showNotificationMessage(MessageType.Error, message); } + private static boolean setDefaultEnvironmentVM(IVMInstall vm) { + if (vm instanceof AbstractVMInstall) { + AbstractVMInstall jvm = (AbstractVMInstall) vm; + long jdkLevel = CompilerOptions.versionToJdkLevel(jvm.getJavaVersion()); + String vmCompliance = CompilerOptions.versionFromJdkLevel(jdkLevel); + IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager(); + IExecutionEnvironment[] environments = manager.getExecutionEnvironments(); + for (IExecutionEnvironment environment : environments) { + if (environment != null) { + if (Objects.equals(vm, environment.getDefaultVM())) { + return true; + } + String compliance = environment.getComplianceOptions().get(JavaCore.COMPILER_COMPLIANCE); + if (Objects.equals(vmCompliance, compliance)) { + if (environment.isStrictlyCompatible(vm)) { + JavaLanguageServerPlugin.logInfo("Setting " + vm.getInstallLocation() + " as '" + environment.getId() + "' environment (id:" + vm.getId() + ")"); + environment.setDefaultVM(vm); + return true; + } + } + } + } + } + return false; + } + private static boolean setDefaultEnvironmentVM(IVMInstall vm, String name) { IExecutionEnvironment environment = getExecutionEnvironment(name); if (environment != null) { if (Objects.equals(vm, environment.getDefaultVM())) { return true; } + if (Objects.equals(environment.getDefaultVM(), JavaRuntime.getDefaultVMInstall())) { + return true; + } IVMInstall[] compatibleVMs = environment.getCompatibleVMs(); for (IVMInstall compatibleVM : compatibleVMs) { if (compatibleVM.equals(vm)) { diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java index 9f19b5849e..3fd4cbfc6d 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java @@ -998,7 +998,9 @@ public static Preferences createFrom(Map configuration) { if (v instanceof Boolean) { runtime.setDefault((Boolean) v); } - hasDefault[0] = true; + if (runtime.isDefault()) { + hasDefault[0] = true; + } } break; default: diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/JVMConfiguratorTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/JVMConfiguratorTest.java index 8a2b19bad6..9df4377d5c 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/JVMConfiguratorTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/JVMConfiguratorTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019-2020 Red Hat Inc. and others. + * Copyright (c) 2019-2021 Red Hat Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at @@ -13,6 +13,7 @@ package org.eclipse.jdt.ls.core.internal; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -109,6 +110,27 @@ public void testDefaultVM() throws CoreException { assertEquals("9", newDefaultVM.getId()); } + // https://github.com/eclipse/eclipse.jdt.ls/issues/1960 + @Test + public void testJavaLSSetDefaultJVM() throws CoreException { + String setDefaultJVM = System.getProperty(JVMConfigurator.JAVA_LS_DO_NOT_SET_DEFAULT_JVM); + try { + System.setProperty(JVMConfigurator.JAVA_LS_DO_NOT_SET_DEFAULT_JVM, "true"); + String javaHome = new File(TestVMType.getFakeJDKsLocation(), "9").getAbsolutePath(); + boolean changed = JVMConfigurator.configureDefaultVM(javaHome); + IVMInstall newDefaultVM = JavaRuntime.getDefaultVMInstall(); + assertFalse("A VM has been changed", changed); + assertEquals(originalVm, newDefaultVM); + assertNotEquals("9", newDefaultVM.getId()); + } finally { + if (setDefaultJVM != null) { + System.setProperty(JVMConfigurator.JAVA_LS_DO_NOT_SET_DEFAULT_JVM, setDefaultJVM); + } else { + System.clearProperty(JVMConfigurator.JAVA_LS_DO_NOT_SET_DEFAULT_JVM); + } + } + } + @Test public void testJVM() throws Exception { try { @@ -140,7 +162,6 @@ public void testJVM() throws Exception { assertTrue(vm instanceof IVMInstall2); String version = ((IVMInstall2) vm).getJavaVersion(); assertTrue(version.startsWith(JavaCore.VERSION_11)); - StandardVMType svt = (StandardVMType) vm.getVMInstallType(); LibraryLocation[] libs = vm.getLibraryLocations(); assertNotNull(libs); for (LibraryLocation lib : libs) { @@ -162,6 +183,66 @@ public void testJVM() throws Exception { assertNull(vm); } + // https://github.com/eclipse/eclipse.jdt.ls/issues/1960 + @Test + public void testJVM2() throws Exception { + String setDefaultJVM = System.getProperty(JVMConfigurator.JAVA_LS_DO_NOT_SET_DEFAULT_JVM); + try { + System.setProperty(JVMConfigurator.JAVA_LS_DO_NOT_SET_DEFAULT_JVM, "true"); + Preferences prefs = new Preferences(); + Bundle bundle = Platform.getBundle(JavaLanguageServerTestPlugin.PLUGIN_ID); + URL url = FileLocator.toFileURL(bundle.getEntry("/fakejdk2/11a")); + File file = URIUtil.toFile(URIUtil.toURI(url)); + String path = file.getAbsolutePath(); + String javadoc = "file:///javadoc"; + Set runtimes = new HashSet<>(); + RuntimeEnvironment runtime = new RuntimeEnvironment(); + runtime.setPath(path); + runtime.setName(ENVIRONMENT_NAME); + runtime.setJavadoc(javadoc); + runtime.setDefault(true); + assertTrue(runtime.isValid()); + runtimes.add(runtime); + prefs.setRuntimes(runtimes); + file = runtime.getInstallationFile(); + assertTrue(file != null && file.isDirectory()); + IVMInstallType installType = JavaRuntime.getVMInstallType(StandardVMType.ID_STANDARD_VM_TYPE); + IStatus status = installType.validateInstallLocation(file); + assertTrue(status.toString(), status.isOK()); + boolean changed = JVMConfigurator.configureJVMs(prefs); + assertTrue("A VM hasn't been changed", changed); + JobHelpers.waitForJobsToComplete(); + IVMInstall vm = JVMConfigurator.findVM(runtime.getInstallationFile(), ENVIRONMENT_NAME); + assertNotNull(vm); + assertTrue(vm instanceof IVMInstall2); + String version = ((IVMInstall2) vm).getJavaVersion(); + assertTrue(version.startsWith(JavaCore.VERSION_11)); + LibraryLocation[] libs = vm.getLibraryLocations(); + assertNotNull(libs); + for (LibraryLocation lib : libs) { + assertEquals(runtime.getJavadocURL(), lib.getJavadocLocation()); + } + IVMInstall newDefaultVM = JavaRuntime.getDefaultVMInstall(); + assertEquals(originalVm, newDefaultVM); + assertNotEquals(vm, newDefaultVM); + IExecutionEnvironment environment = JVMConfigurator.getExecutionEnvironment(ENVIRONMENT_NAME); + assertNotNull(environment); + assertEquals(vm, environment.getDefaultVM()); + } finally { + IVMInstall vm = JVMConfigurator.findVM(null, ENVIRONMENT_NAME); + if (vm != null) { + vm.getVMInstallType().disposeVMInstall(vm.getId()); + } + if (setDefaultJVM != null) { + System.setProperty(JVMConfigurator.JAVA_LS_DO_NOT_SET_DEFAULT_JVM, setDefaultJVM); + } else { + System.clearProperty(JVMConfigurator.JAVA_LS_DO_NOT_SET_DEFAULT_JVM); + } + } + IVMInstall vm = JVMConfigurator.findVM(null, ENVIRONMENT_NAME); + assertNull(vm); + } + @Test public void testInvalidJavadoc() throws Exception { Bundle bundle = Platform.getBundle(JavaLanguageServerTestPlugin.PLUGIN_ID);